• 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
54 	{
55 		SURFACETYPE_WINDOW = 0,
56 		SURFACETYPE_PBUFFER
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,NegativePartialUpdateTest::SurfaceType surfaceType,bool preserveBuffer)100 EGLConfig getEGLConfig (const Library& egl, EGLDisplay eglDisplay, NegativePartialUpdateTest::SurfaceType surfaceType, bool preserveBuffer)
101 {
102 	FilterList filters;
103 	if (surfaceType == NegativePartialUpdateTest::SURFACETYPE_WINDOW)
104 		filters << isWindow;
105 	else if (surfaceType == NegativePartialUpdateTest::SURFACETYPE_PBUFFER)
106 		filters << isPbuffer;
107 	else
108 		DE_FATAL("Invalid surfaceType");
109 
110 	filters << isES2Renderable;
111 
112 	if (preserveBuffer)
113 		filters << hasPreserveSwap;
114 
115 	return chooseSingleConfig(egl, eglDisplay, filters);
116 }
117 
initAndMakeCurrentEGLContext(const Library & egl,EGLDisplay eglDisplay,EGLSurface eglSurface,EGLConfig eglConfig,const EGLint * attribList)118 EGLContext initAndMakeCurrentEGLContext (const Library& egl, EGLDisplay eglDisplay, EGLSurface eglSurface, EGLConfig eglConfig, const EGLint* attribList)
119 {
120 	EGLContext eglContext = EGL_NO_CONTEXT;
121 
122 	egl.bindAPI(EGL_OPENGL_ES_API);
123 	eglContext = egl.createContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, attribList);
124 	EGLU_CHECK_MSG(egl, "eglCreateContext");
125 	TCU_CHECK(eglSurface != EGL_NO_SURFACE);
126 	egl.makeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
127 	EGLU_CHECK_MSG(egl, "eglMakeCurrent");
128 
129 	return eglContext;
130 }
131 
NegativePartialUpdateTest(EglTestContext & eglTestCtx,bool preserveBuffer,SurfaceType surfaceType,const char * name,const char * description)132 NegativePartialUpdateTest::NegativePartialUpdateTest (EglTestContext& eglTestCtx, bool preserveBuffer, SurfaceType surfaceType, const char* name, const char* description)
133 	: TestCase			(eglTestCtx, name, description)
134 	, m_preserveBuffer	(preserveBuffer)
135 	, m_surfaceType		(surfaceType)
136 	, m_eglDisplay		(EGL_NO_DISPLAY)
137 	, m_window			(DE_NULL)
138 	, m_eglSurface		(EGL_NO_SURFACE)
139 	, m_eglContext		(EGL_NO_CONTEXT)
140 {
141 }
142 
~NegativePartialUpdateTest(void)143 NegativePartialUpdateTest::~NegativePartialUpdateTest (void)
144 {
145 	deinit();
146 }
147 
init(void)148 void NegativePartialUpdateTest::init (void)
149 {
150 	const Library&		egl						= m_eglTestCtx.getLibrary();
151 	static const EGLint	contextAttribList[]		= { EGL_CONTEXT_CLIENT_VERSION, 2,	EGL_NONE };
152 	const int			width					= 480;
153 	const int			height					= 480;
154 
155 	m_eglDisplay = getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
156 
157 	if (!hasExtension(egl, m_eglDisplay, "EGL_KHR_partial_update"))
158 		TCU_THROW(NotSupportedError, "EGL_KHR_partial_update is not supported");
159 
160 	m_eglConfig = getEGLConfig(egl, m_eglDisplay, m_surfaceType, m_preserveBuffer);
161 
162 	if (m_surfaceType == SURFACETYPE_PBUFFER)
163 	{
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 		const NativeWindowFactory&	factory	= selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
170 		m_window = factory.createWindow(&m_eglTestCtx.getNativeDisplay(), m_eglDisplay, m_eglConfig, DE_NULL,
171 										WindowParams(width, height, parseWindowVisibility(m_testCtx.getCommandLine())));
172 		m_eglSurface = createWindowSurface(m_eglTestCtx.getNativeDisplay(), *m_window, m_eglDisplay, m_eglConfig, DE_NULL);
173 	}
174 	m_eglContext = initAndMakeCurrentEGLContext(egl, m_eglDisplay, m_eglSurface, m_eglConfig, contextAttribList);
175 }
176 
deinit(void)177 void NegativePartialUpdateTest::deinit (void)
178 {
179 	const Library& egl = m_eglTestCtx.getLibrary();
180 
181 	if (m_eglContext != EGL_NO_CONTEXT)
182 	{
183 		EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
184 		EGLU_CHECK_CALL(egl, destroyContext(m_eglDisplay, m_eglContext));
185 		m_eglContext = EGL_NO_CONTEXT;
186 	}
187 
188 	if (m_eglSurface != EGL_NO_SURFACE)
189 	{
190 		EGLU_CHECK_CALL(egl, destroySurface(m_eglDisplay, m_eglSurface));
191 		m_eglSurface = EGL_NO_SURFACE;
192 	}
193 
194 	if (m_eglDisplay != EGL_NO_DISPLAY)
195 	{
196 		EGLU_CHECK_CALL(egl, terminate(m_eglDisplay));
197 		m_eglDisplay = EGL_NO_DISPLAY;
198 	}
199 
200 	delete m_window;
201 	m_window = DE_NULL;
202 }
203 
expectError(EGLenum expected)204 void NegativePartialUpdateTest::expectError (EGLenum expected)
205 {
206 	const EGLenum err = m_eglTestCtx.getLibrary().getError();
207 
208 	if (err != expected)
209 	{
210 		m_testCtx.getLog() << TestLog::Message << "// ERROR expected: " << eglu::getErrorStr(expected) << ", Got: " << eglu::getErrorStr(err) << TestLog::EndMessage;
211 		if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
212 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid error");
213 	}
214 }
215 
expectBoolean(EGLBoolean expected,EGLBoolean got)216 void NegativePartialUpdateTest::expectBoolean (EGLBoolean expected, EGLBoolean got)
217 {
218 	if (expected != got)
219 	{
220 		m_testCtx.getLog() << TestLog::Message << "// ERROR expected: " << eglu::getBooleanStr(expected) <<  ", Got: " << eglu::getBooleanStr(got) << TestLog::EndMessage;
221 		if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
222 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid value");
223 	}
224 }
225 
226 class NotPostableTest : public NegativePartialUpdateTest
227 {
228 public:
229 							NotPostableTest (EglTestContext& context);
230 	TestCase::IterateResult iterate			(void);
231 };
232 
NotPostableTest(EglTestContext & context)233 NotPostableTest::NotPostableTest (EglTestContext& context)
234 	: NegativePartialUpdateTest (context, false, SURFACETYPE_PBUFFER, "not_postable_surface",  "Call setDamageRegion() on pbuffer")
235 {
236 }
237 
iterate(void)238 TestCase::IterateResult NotPostableTest::iterate (void)
239 {
240 	const Library&			egl				= m_eglTestCtx.getLibrary();
241 	TestLog&				log				= m_testCtx.getLog();
242 	CallLogWrapper			wrapper			(egl, log);
243 	EGLint					damageRegion[]	= { 10, 10, 10, 10 };
244 	int						bufferAge		= -1;
245 
246 	wrapper.enableLogging(true);
247 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
248 	{
249 		tcu::ScopedLogSection(log, "Test1", "If the surface is pbuffer (not postable) --> EGL_BAD_MATCH");
250 		EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED));
251 		EGLU_CHECK_CALL(egl, querySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge));
252 		expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, DE_LENGTH_OF_ARRAY(damageRegion)/4));
253 		expectError(EGL_BAD_MATCH);
254 	}
255 
256 	return STOP;
257 }
258 
259 class NotCurrentSurfaceTest : public NegativePartialUpdateTest
260 {
261 public:
262 							NotCurrentSurfaceTest	(EglTestContext& context);
263 	TestCase::IterateResult iterate					(void);
264 };
265 
NotCurrentSurfaceTest(EglTestContext & context)266 NotCurrentSurfaceTest::NotCurrentSurfaceTest (EglTestContext& context)
267 	: NegativePartialUpdateTest (context, false, SURFACETYPE_WINDOW, "not_current_surface",  "Call setDamageRegion() on pbuffer")
268 {
269 }
270 
iterate(void)271 TestCase::IterateResult NotCurrentSurfaceTest::iterate (void)
272 {
273 	const int					impossibleBufferAge = -26084;
274 	const Library&				egl					= m_eglTestCtx.getLibrary();
275 	const EGLConfig				config				= getEGLConfig(egl, m_eglDisplay, SURFACETYPE_PBUFFER, false);
276 	const EGLint				attribList[]		=
277 	{
278 		EGL_WIDTH,	64,
279 		EGL_HEIGHT,	64,
280 		EGL_NONE
281 	};
282 	const eglu::UniqueSurface	dummyPbuffer		(egl, m_eglDisplay, egl.createPbufferSurface(m_eglDisplay, config, 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, *dummyPbuffer, *dummyPbuffer, 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 EGLConfig				config			= getEGLConfig(egl, m_eglDisplay, SURFACETYPE_PBUFFER, false);
500 	const EGLint				attribList[]	=
501 	{
502 		EGL_WIDTH,	64,
503 		EGL_HEIGHT,	64,
504 		EGL_NONE
505 	};
506 	const eglu::UniqueSurface	dummyPbuffer	(egl, m_eglDisplay, egl.createPbufferSurface(m_eglDisplay, config, attribList));
507 	TestLog&					log				= m_testCtx.getLog();
508 	CallLogWrapper				wrapper			(egl, log);
509 	EGLint						damageRegion[]	= { 10, 10, 10, 10 };
510 	int							bufferAge		= -1;
511 
512 	wrapper.enableLogging(true);
513 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
514 
515 	EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED));
516 	EGLU_CHECK_CALL(egl, querySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge));
517 
518 	{
519 		tcu::ScopedLogSection(log, "Test7", "If call setDamageRegion() on a surface that is not the current draw surface --> EGL_BAD_MATCH");
520 		EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, *dummyPbuffer, *dummyPbuffer, m_eglContext));
521 		expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, 1));
522 		expectError(EGL_BAD_MATCH);
523 	}
524 	{
525 		tcu::ScopedLogSection(log, "Test8", "If call setDamageRegion() on a surface that is not the current draw surface --> EGL_BAD_MATCH");
526 		EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
527 		expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, 1));
528 		expectError(EGL_BAD_MATCH);
529 	}
530 	if (hasExtension(egl, m_eglDisplay, "EGL_KHR_surfaceless_context"))
531 	{
532 		tcu::ScopedLogSection(log, "Test9", "If call setDamageRegion() on a surface that is not the current draw surface --> EGL_BAD_MATCH");
533 		EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, m_eglContext));
534 		expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, 1));
535 		expectError(EGL_BAD_MATCH);
536 	}
537 
538 	return STOP;
539 }
540 
541 } // anonymous
542 
NegativePartialUpdateTests(EglTestContext & eglTestCtx)543 NegativePartialUpdateTests::NegativePartialUpdateTests (EglTestContext& eglTestCtx)
544 	: TestCaseGroup(eglTestCtx, "negative_partial_update", "Negative partial update tests")
545 {
546 }
547 
init(void)548 void NegativePartialUpdateTests::init (void)
549 {
550 	addChild(new NotPostableTest(m_eglTestCtx));
551 	addChild(new NotCurrentSurfaceTest(m_eglTestCtx));
552 	addChild(new BufferPreservedTest(m_eglTestCtx));
553 	addChild(new SetTwiceTest(m_eglTestCtx));
554 	addChild(new NoAgeTest(m_eglTestCtx));
555 	addChild(new PassNullTest(m_eglTestCtx));
556 	addChild(new NotCurrentSurfaceTest2(m_eglTestCtx));
557 }
558 
559 } // egl
560 } // deqp
561