• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program EGL Module
3  * ---------------------------------------
4  *
5  * Copyright 2015 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *       http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Test negative use case of KHR_partial_update
22  *//*--------------------------------------------------------------------*/
23 
24 #include "teglNegativePartialUpdateTests.hpp"
25 
26 #include "tcuTestLog.hpp"
27 #include "tcuSurface.hpp"
28 
29 #include "egluCallLogWrapper.hpp"
30 #include "egluConfigFilter.hpp"
31 #include "egluNativeWindow.hpp"
32 #include "egluStrUtil.hpp"
33 #include "egluUnique.hpp"
34 #include "egluUtil.hpp"
35 
36 #include "eglwLibrary.hpp"
37 #include "eglwEnums.hpp"
38 
39 using namespace eglu;
40 using namespace eglw;
41 using tcu::TestLog;
42 
43 namespace deqp
44 {
45 namespace egl
46 {
47 namespace
48 {
49 
50 class NegativePartialUpdateTest : public TestCase
51 {
52 public:
53 	enum SurfaceType // used as a bit field when selecting a suitable EGL config
54 	{
55 		SURFACETYPE_WINDOW  = 1 << 0,
56 		SURFACETYPE_PBUFFER = 1 << 1
57 	};
58 
59 								NegativePartialUpdateTest		(EglTestContext& eglTestCtx, bool preserveBuffer, SurfaceType surfaceType, const char* name, const char* description);
60 								~NegativePartialUpdateTest		(void);
61 	void						init							(void);
62 	void						deinit							(void);
63 	virtual IterateResult		iterate							(void) = 0;
64 
65 protected:
66 	void						expectError						(eglw::EGLenum error);
67 	void						expectBoolean					(EGLBoolean expected, EGLBoolean got);
expectTrue(eglw::EGLBoolean got)68 	inline void					expectTrue						(eglw::EGLBoolean got) { expectBoolean(EGL_TRUE, got); }
expectFalse(eglw::EGLBoolean got)69 	inline void					expectFalse						(eglw::EGLBoolean got) { expectBoolean(EGL_FALSE, got); }
70 
71 	const bool					m_preserveBuffer;
72 	SurfaceType					m_surfaceType;
73 	EGLDisplay					m_eglDisplay;
74 	EGLConfig					m_eglConfig;
75 	NativeWindow*				m_window;
76 	EGLSurface					m_eglSurface;
77 	EGLContext					m_eglContext;
78 };
79 
isWindow(const CandidateConfig & c)80 bool isWindow (const CandidateConfig& c)
81 {
82 	return (c.surfaceType() & EGL_WINDOW_BIT) == EGL_WINDOW_BIT;
83 }
84 
isPbuffer(const CandidateConfig & c)85 bool isPbuffer (const CandidateConfig& c)
86 {
87 	return (c.surfaceType() & EGL_PBUFFER_BIT) == EGL_PBUFFER_BIT;
88 }
89 
isES2Renderable(const CandidateConfig & c)90 bool isES2Renderable (const CandidateConfig& c)
91 {
92 	return (c.get(EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT) == EGL_OPENGL_ES2_BIT;
93 }
94 
hasPreserveSwap(const CandidateConfig & c)95 bool hasPreserveSwap (const CandidateConfig& c)
96 {
97 	return (c.surfaceType() & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) == EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
98 }
99 
getEGLConfig(const Library & egl,EGLDisplay eglDisplay,unsigned surfaceTypes,bool preserveBuffer)100 EGLConfig getEGLConfig (const Library& egl, EGLDisplay eglDisplay, unsigned surfaceTypes, bool preserveBuffer)
101 {
102 	FilterList filters;
103 	if ((surfaceTypes & NegativePartialUpdateTest::SURFACETYPE_WINDOW) != 0)
104 		filters << isWindow;
105 	if ((surfaceTypes & NegativePartialUpdateTest::SURFACETYPE_PBUFFER) != 0)
106 		filters << isPbuffer;
107 	if (((surfaceTypes & NegativePartialUpdateTest::SURFACETYPE_WINDOW) == 0) &&
108 		((surfaceTypes & NegativePartialUpdateTest::SURFACETYPE_PBUFFER) == 0))
109 		DE_FATAL("Invalid surfaceType");
110 
111 	filters << isES2Renderable;
112 
113 	if (preserveBuffer)
114 		filters << hasPreserveSwap;
115 
116 	return chooseSingleConfig(egl, eglDisplay, filters);
117 }
118 
initAndMakeCurrentEGLContext(const Library & egl,EGLDisplay eglDisplay,EGLSurface eglSurface,EGLConfig eglConfig,const EGLint * attribList)119 EGLContext initAndMakeCurrentEGLContext (const Library& egl, EGLDisplay eglDisplay, EGLSurface eglSurface, EGLConfig eglConfig, const EGLint* attribList)
120 {
121 	EGLContext eglContext = EGL_NO_CONTEXT;
122 
123 	egl.bindAPI(EGL_OPENGL_ES_API);
124 	eglContext = egl.createContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, attribList);
125 	EGLU_CHECK_MSG(egl, "eglCreateContext");
126 	TCU_CHECK(eglSurface != EGL_NO_SURFACE);
127 	egl.makeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
128 	EGLU_CHECK_MSG(egl, "eglMakeCurrent");
129 
130 	return eglContext;
131 }
132 
NegativePartialUpdateTest(EglTestContext & eglTestCtx,bool preserveBuffer,SurfaceType surfaceType,const char * name,const char * description)133 NegativePartialUpdateTest::NegativePartialUpdateTest (EglTestContext& eglTestCtx, bool preserveBuffer, SurfaceType surfaceType, const char* name, const char* description)
134 	: TestCase			(eglTestCtx, name, description)
135 	, m_preserveBuffer	(preserveBuffer)
136 	, m_surfaceType		(surfaceType)
137 	, m_eglDisplay		(EGL_NO_DISPLAY)
138 	, m_window			(DE_NULL)
139 	, m_eglSurface		(EGL_NO_SURFACE)
140 	, m_eglContext		(EGL_NO_CONTEXT)
141 {
142 }
143 
~NegativePartialUpdateTest(void)144 NegativePartialUpdateTest::~NegativePartialUpdateTest (void)
145 {
146 	deinit();
147 }
148 
init(void)149 void NegativePartialUpdateTest::init (void)
150 {
151 	const Library&		egl						= m_eglTestCtx.getLibrary();
152 	static const EGLint	contextAttribList[]		= { EGL_CONTEXT_CLIENT_VERSION, 2,	EGL_NONE };
153 	const int			width					= 480;
154 	const int			height					= 480;
155 
156 	m_eglDisplay = getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
157 
158 	if (!hasExtension(egl, m_eglDisplay, "EGL_KHR_partial_update"))
159 		TCU_THROW(NotSupportedError, "EGL_KHR_partial_update is not supported");
160 
161 	if (m_surfaceType == SURFACETYPE_PBUFFER)
162 	{
163 		m_eglConfig = getEGLConfig(egl, m_eglDisplay, SURFACETYPE_PBUFFER, m_preserveBuffer);
164 		const EGLint pbufferAttribList[] = { EGL_WIDTH, width, EGL_HEIGHT, height, EGL_NONE };
165 		m_eglSurface = egl.createPbufferSurface(m_eglDisplay, m_eglConfig, pbufferAttribList);
166 	}
167 	else
168 	{
169 		m_eglConfig = getEGLConfig(egl, m_eglDisplay, SURFACETYPE_WINDOW | SURFACETYPE_PBUFFER, m_preserveBuffer);
170 		const NativeWindowFactory&	factory	= selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
171 		m_window = factory.createWindow(&m_eglTestCtx.getNativeDisplay(), m_eglDisplay, m_eglConfig, DE_NULL,
172 										WindowParams(width, height, parseWindowVisibility(m_testCtx.getCommandLine())));
173 		m_eglSurface = createWindowSurface(m_eglTestCtx.getNativeDisplay(), *m_window, m_eglDisplay, m_eglConfig, DE_NULL);
174 	}
175 	m_eglContext = initAndMakeCurrentEGLContext(egl, m_eglDisplay, m_eglSurface, m_eglConfig, contextAttribList);
176 }
177 
deinit(void)178 void NegativePartialUpdateTest::deinit (void)
179 {
180 	const Library& egl = m_eglTestCtx.getLibrary();
181 
182 	if (m_eglContext != EGL_NO_CONTEXT)
183 	{
184 		EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
185 		EGLU_CHECK_CALL(egl, destroyContext(m_eglDisplay, m_eglContext));
186 		m_eglContext = EGL_NO_CONTEXT;
187 	}
188 
189 	if (m_eglSurface != EGL_NO_SURFACE)
190 	{
191 		EGLU_CHECK_CALL(egl, destroySurface(m_eglDisplay, m_eglSurface));
192 		m_eglSurface = EGL_NO_SURFACE;
193 	}
194 
195 	if (m_eglDisplay != EGL_NO_DISPLAY)
196 	{
197 		EGLU_CHECK_CALL(egl, terminate(m_eglDisplay));
198 		m_eglDisplay = EGL_NO_DISPLAY;
199 	}
200 
201 	delete m_window;
202 	m_window = DE_NULL;
203 }
204 
expectError(EGLenum expected)205 void NegativePartialUpdateTest::expectError (EGLenum expected)
206 {
207 	const EGLenum err = m_eglTestCtx.getLibrary().getError();
208 
209 	if (err != expected)
210 	{
211 		m_testCtx.getLog() << TestLog::Message << "// ERROR expected: " << eglu::getErrorStr(expected) << ", Got: " << eglu::getErrorStr(err) << TestLog::EndMessage;
212 		if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
213 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid error");
214 	}
215 }
216 
expectBoolean(EGLBoolean expected,EGLBoolean got)217 void NegativePartialUpdateTest::expectBoolean (EGLBoolean expected, EGLBoolean got)
218 {
219 	if (expected != got)
220 	{
221 		m_testCtx.getLog() << TestLog::Message << "// ERROR expected: " << eglu::getBooleanStr(expected) <<  ", Got: " << eglu::getBooleanStr(got) << TestLog::EndMessage;
222 		if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
223 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid value");
224 	}
225 }
226 
227 class NotPostableTest : public NegativePartialUpdateTest
228 {
229 public:
230 							NotPostableTest (EglTestContext& context);
231 	TestCase::IterateResult iterate			(void);
232 };
233 
NotPostableTest(EglTestContext & context)234 NotPostableTest::NotPostableTest (EglTestContext& context)
235 	: NegativePartialUpdateTest (context, false, SURFACETYPE_PBUFFER, "not_postable_surface",  "Call setDamageRegion() on pbuffer")
236 {
237 }
238 
iterate(void)239 TestCase::IterateResult NotPostableTest::iterate (void)
240 {
241 	const Library&			egl				= m_eglTestCtx.getLibrary();
242 	TestLog&				log				= m_testCtx.getLog();
243 	CallLogWrapper			wrapper			(egl, log);
244 	EGLint					damageRegion[]	= { 10, 10, 10, 10 };
245 	int						bufferAge		= -1;
246 
247 	wrapper.enableLogging(true);
248 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
249 	{
250 		tcu::ScopedLogSection(log, "Test1", "If the surface is pbuffer (not postable) --> EGL_BAD_MATCH");
251 		EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED));
252 		EGLU_CHECK_CALL(egl, querySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge));
253 		expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, DE_LENGTH_OF_ARRAY(damageRegion)/4));
254 		expectError(EGL_BAD_MATCH);
255 	}
256 
257 	return STOP;
258 }
259 
260 class NotCurrentSurfaceTest : public NegativePartialUpdateTest
261 {
262 public:
263 							NotCurrentSurfaceTest	(EglTestContext& context);
264 	TestCase::IterateResult iterate					(void);
265 };
266 
NotCurrentSurfaceTest(EglTestContext & context)267 NotCurrentSurfaceTest::NotCurrentSurfaceTest (EglTestContext& context)
268 	: NegativePartialUpdateTest (context, false, SURFACETYPE_WINDOW, "not_current_surface",  "Call setDamageRegion() on pbuffer")
269 {
270 }
271 
iterate(void)272 TestCase::IterateResult NotCurrentSurfaceTest::iterate (void)
273 {
274 	const int					impossibleBufferAge = -26084;
275 	const Library&				egl					= m_eglTestCtx.getLibrary();
276 	const EGLint				attribList[]		=
277 	{
278 		EGL_WIDTH,	64,
279 		EGL_HEIGHT,	64,
280 		EGL_NONE
281 	};
282 	const eglu::UniqueSurface	unusedPbuffer		(egl, m_eglDisplay, egl.createPbufferSurface(m_eglDisplay, m_eglConfig, attribList));
283 	TestLog&					log					= m_testCtx.getLog();
284 	CallLogWrapper				wrapper				(egl, log);
285 	EGLint						damageRegion[]		= { 10, 10, 10, 10 };
286 	int							bufferAge			= impossibleBufferAge;
287 
288 	wrapper.enableLogging(true);
289 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
290 	EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, *unusedPbuffer, *unusedPbuffer, m_eglContext));
291 	{
292 		tcu::ScopedLogSection(log, "Test2.1", "If query buffer age on a surface that is not the current draw surface --> EGL_BAD_SURFACE");
293 		EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED));
294 		expectFalse(wrapper.eglQuerySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge));
295 		expectError(EGL_BAD_SURFACE);
296 
297 		if (bufferAge != impossibleBufferAge)
298 		{
299 			log << tcu::TestLog::Message << "On failure, eglQuerySurface shouldn't change buffer age but buffer age has been changed to " << bufferAge << tcu::TestLog::EndMessage;
300 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail, bufferAge shouldn't be changed");
301 		}
302 	}
303 	{
304 		tcu::ScopedLogSection(log, "Test2.2", "If call setDamageRegion() on a surface that is not the current draw surface --> EGL_BAD_MATCH");
305 		expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, 1));
306 		expectError(EGL_BAD_MATCH);
307 	}
308 
309 	EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
310 	{
311 		tcu::ScopedLogSection(log, "Test3.1", "If query buffer age on a surface that is not the current draw surface --> EGL_BAD_SURFACE");
312 		EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED));
313 		expectFalse(wrapper.eglQuerySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge));
314 		expectError(EGL_BAD_SURFACE);
315 
316 		if (bufferAge != impossibleBufferAge)
317 		{
318 			log << tcu::TestLog::Message << "On failure, eglQuerySurface shouldn't change buffer age but buffer age has been changed to " << bufferAge << tcu::TestLog::EndMessage;
319 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail, bufferAge shouldn't be changed");
320 		}
321 	}
322 	{
323 		tcu::ScopedLogSection(log, "Test3.2", "If call setDamageRegion() on a surface that is not the current draw surface --> EGL_BAD_MATCH");
324 		expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, 1));
325 		expectError(EGL_BAD_MATCH);
326 	}
327 
328 	if (hasExtension(egl, m_eglDisplay, "EGL_KHR_surfaceless_context"))
329 	{
330 		EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, m_eglContext));
331 		{
332 			tcu::ScopedLogSection(log, "Test4.1", "If query buffer age on a surface that is not the current draw surface --> EGL_BAD_SURFACE");
333 			EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED));
334 			expectFalse(wrapper.eglQuerySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge));
335 			expectError(EGL_BAD_SURFACE);
336 
337 			if (bufferAge != impossibleBufferAge)
338 			{
339 				log << tcu::TestLog::Message << "On failure, eglQuerySurface shouldn't change buffer age but buffer age has been changed to " << bufferAge << tcu::TestLog::EndMessage;
340 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail, bufferAge shouldn't be changed");
341 			}
342 		}
343 		{
344 			tcu::ScopedLogSection(log, "Test4.2", "If call setDamageRegion() on a surface that is not the current draw surface --> EGL_BAD_MATCH");
345 			expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, 1));
346 			expectError(EGL_BAD_MATCH);
347 		}
348 	}
349 
350 	return STOP;
351 }
352 
353 class BufferPreservedTest : public NegativePartialUpdateTest
354 {
355 public:
356 							BufferPreservedTest (EglTestContext& context);
357 	TestCase::IterateResult iterate				(void);
358 };
359 
BufferPreservedTest(EglTestContext & context)360 BufferPreservedTest::BufferPreservedTest (EglTestContext& context)
361 	: NegativePartialUpdateTest (context, true, SURFACETYPE_WINDOW, "buffer_preserved",  "Call setDamageRegion() on pbuffer")
362 {
363 }
364 
iterate(void)365 TestCase::IterateResult BufferPreservedTest::iterate (void)
366 {
367 	const Library&			egl				= m_eglTestCtx.getLibrary();
368 	TestLog&				log				= m_testCtx.getLog();
369 	CallLogWrapper			wrapper			(egl, log);
370 	EGLint					damageRegion[]	= { 10, 10, 10, 10 };
371 	int						bufferAge		= -1;
372 
373 	wrapper.enableLogging(true);
374 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
375 	{
376 		tcu::ScopedLogSection(log, "Test3", "If buffer_preserved --> EGL_BAD_MATCH");
377 		EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED));
378 		EGLU_CHECK_CALL(egl, querySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge));
379 		expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, DE_LENGTH_OF_ARRAY(damageRegion)/4));
380 		expectError(EGL_BAD_MATCH);
381 	}
382 
383 	return STOP;
384 }
385 
386 class SetTwiceTest : public NegativePartialUpdateTest
387 {
388 public:
389 							SetTwiceTest		(EglTestContext& context);
390 	TestCase::IterateResult iterate				(void);
391 };
392 
SetTwiceTest(EglTestContext & context)393 SetTwiceTest::SetTwiceTest (EglTestContext& context)
394 	: NegativePartialUpdateTest (context, false, SURFACETYPE_WINDOW, "set_damage_region_twice",  "Call setDamageRegion() twice")
395 {
396 }
397 
iterate(void)398 TestCase::IterateResult SetTwiceTest::iterate (void)
399 {
400 	const Library&			egl				= m_eglTestCtx.getLibrary();
401 	TestLog&				log				= m_testCtx.getLog();
402 	CallLogWrapper			wrapper			(egl, log);
403 	EGLint					damageRegion[]	= { 10, 10, 10, 10 };
404 	int						bufferAge		= -1;
405 
406 	wrapper.enableLogging(true);
407 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
408 	{
409 		tcu::ScopedLogSection(log, "Test4", "If call setDamageRegion() twice --> EGL_BAD_ACCESS");
410 		EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED));
411 		EGLU_CHECK_CALL(egl, querySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge));
412 		expectTrue(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, DE_LENGTH_OF_ARRAY(damageRegion)/4));
413 		expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, DE_LENGTH_OF_ARRAY(damageRegion)/4));
414 		expectError(EGL_BAD_ACCESS);
415 	}
416 
417 	return STOP;
418 }
419 
420 
421 class NoAgeTest : public NegativePartialUpdateTest
422 {
423 public:
424 							NoAgeTest			(EglTestContext& context);
425 	TestCase::IterateResult iterate				(void);
426 };
427 
NoAgeTest(EglTestContext & context)428 NoAgeTest::NoAgeTest (EglTestContext& context)
429 	: NegativePartialUpdateTest (context, false, SURFACETYPE_WINDOW, "set_damage_region_before_query_age",  "Call setDamageRegion() without querying buffer age")
430 {
431 }
432 
iterate(void)433 TestCase::IterateResult NoAgeTest::iterate (void)
434 {
435 	const Library&			egl				= m_eglTestCtx.getLibrary();
436 	TestLog&				log				= m_testCtx.getLog();
437 	CallLogWrapper			wrapper			(egl, log);
438 	EGLint					damageRegion[]	= { 10, 10, 10, 10 };
439 
440 	wrapper.enableLogging(true);
441 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
442 	{
443 		tcu::ScopedLogSection(log, "Test5", "If buffer age is not queried --> EGL_BAD_ACCESS");
444 		EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED));
445 		expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, DE_LENGTH_OF_ARRAY(damageRegion)/4));
446 		expectError(EGL_BAD_ACCESS);
447 	}
448 
449 	return STOP;
450 }
451 
452 class PassNullTest : public NegativePartialUpdateTest
453 {
454 public:
455 							PassNullTest			(EglTestContext& context);
456 	TestCase::IterateResult iterate					(void);
457 };
458 
PassNullTest(EglTestContext & context)459 PassNullTest::PassNullTest (EglTestContext& context)
460 	: NegativePartialUpdateTest (context, false, SURFACETYPE_WINDOW, "pass_null_0_as_params",  "Call setDamageRegion() with (NULL, 0)")
461 {
462 }
463 
iterate(void)464 TestCase::IterateResult PassNullTest::iterate (void)
465 {
466 	const Library&			egl				= m_eglTestCtx.getLibrary();
467 	TestLog&				log				= m_testCtx.getLog();
468 	CallLogWrapper			wrapper			(egl, log);
469 	int						bufferAge		= -1;
470 
471 	wrapper.enableLogging(true);
472 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
473 	{
474 		tcu::ScopedLogSection(log, "Test6", "If pass (null, 0) to setDamageRegion(), no error");
475 		EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED));
476 		EGLU_CHECK_CALL(egl, querySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge));
477 		expectTrue(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, DE_NULL, 0));
478 		expectError(EGL_SUCCESS);
479 	}
480 
481 	return STOP;
482 }
483 
484 class NotCurrentSurfaceTest2 : public NegativePartialUpdateTest
485 {
486 public:
487 							NotCurrentSurfaceTest2	(EglTestContext& context);
488 	TestCase::IterateResult iterate					(void);
489 };
490 
NotCurrentSurfaceTest2(EglTestContext & context)491 NotCurrentSurfaceTest2::NotCurrentSurfaceTest2 (EglTestContext& context)
492 	: NegativePartialUpdateTest (context, false, SURFACETYPE_WINDOW, "not_current_surface2",  "Call setDamageRegion() on pbuffer")
493 {
494 }
495 
iterate(void)496 TestCase::IterateResult NotCurrentSurfaceTest2::iterate (void)
497 {
498 	const Library&				egl				= m_eglTestCtx.getLibrary();
499 	const EGLint				attribList[]	=
500 	{
501 		EGL_WIDTH,	64,
502 		EGL_HEIGHT,	64,
503 		EGL_NONE
504 	};
505 	const eglu::UniqueSurface	unusedPbuffer	(egl, m_eglDisplay, egl.createPbufferSurface(m_eglDisplay, m_eglConfig, attribList));
506 	TestLog&					log				= m_testCtx.getLog();
507 	CallLogWrapper				wrapper			(egl, log);
508 	EGLint						damageRegion[]	= { 10, 10, 10, 10 };
509 	int							bufferAge		= -1;
510 
511 	wrapper.enableLogging(true);
512 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
513 
514 	EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED));
515 	EGLU_CHECK_CALL(egl, querySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge));
516 
517 	{
518 		tcu::ScopedLogSection(log, "Test7", "If call setDamageRegion() on a surface that is not the current draw surface --> EGL_BAD_MATCH");
519 		EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, *unusedPbuffer, *unusedPbuffer, m_eglContext));
520 		expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, 1));
521 		expectError(EGL_BAD_MATCH);
522 	}
523 	{
524 		tcu::ScopedLogSection(log, "Test8", "If call setDamageRegion() on a surface that is not the current draw surface --> EGL_BAD_MATCH");
525 		EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
526 		expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, 1));
527 		expectError(EGL_BAD_MATCH);
528 	}
529 	if (hasExtension(egl, m_eglDisplay, "EGL_KHR_surfaceless_context"))
530 	{
531 		tcu::ScopedLogSection(log, "Test9", "If call setDamageRegion() on a surface that is not the current draw surface --> EGL_BAD_MATCH");
532 		EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, m_eglContext));
533 		expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, 1));
534 		expectError(EGL_BAD_MATCH);
535 	}
536 
537 	return STOP;
538 }
539 
540 } // anonymous
541 
NegativePartialUpdateTests(EglTestContext & eglTestCtx)542 NegativePartialUpdateTests::NegativePartialUpdateTests (EglTestContext& eglTestCtx)
543 	: TestCaseGroup(eglTestCtx, "negative_partial_update", "Negative partial update tests")
544 {
545 }
546 
init(void)547 void NegativePartialUpdateTests::init (void)
548 {
549 	addChild(new NotPostableTest(m_eglTestCtx));
550 	addChild(new NotCurrentSurfaceTest(m_eglTestCtx));
551 	addChild(new BufferPreservedTest(m_eglTestCtx));
552 	addChild(new SetTwiceTest(m_eglTestCtx));
553 	addChild(new NoAgeTest(m_eglTestCtx));
554 	addChild(new PassNullTest(m_eglTestCtx));
555 	addChild(new NotCurrentSurfaceTest2(m_eglTestCtx));
556 }
557 
558 } // egl
559 } // deqp
560