Home | History | Annotate | Download | only in egl
      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);
     68 	inline void					expectTrue						(eglw::EGLBoolean got) { expectBoolean(EGL_TRUE, 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 
     80 bool isWindow (const CandidateConfig& c)
     81 {
     82 	return (c.surfaceType() & EGL_WINDOW_BIT) == EGL_WINDOW_BIT;
     83 }
     84 
     85 bool isPbuffer (const CandidateConfig& c)
     86 {
     87 	return (c.surfaceType() & EGL_PBUFFER_BIT) == EGL_PBUFFER_BIT;
     88 }
     89 
     90 bool isES2Renderable (const CandidateConfig& c)
     91 {
     92 	return (c.get(EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT) == EGL_OPENGL_ES2_BIT;
     93 }
     94 
     95 bool hasPreserveSwap (const CandidateConfig& c)
     96 {
     97 	return (c.surfaceType() & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) == EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
     98 }
     99 
    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 
    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 
    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 
    143 NegativePartialUpdateTest::~NegativePartialUpdateTest (void)
    144 {
    145 	deinit();
    146 }
    147 
    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 
    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 
    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 
    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 
    233 NotPostableTest::NotPostableTest (EglTestContext& context)
    234 	: NegativePartialUpdateTest (context, false, SURFACETYPE_PBUFFER, "not_postable_surface",  "Call setDamageRegion() on pbuffer")
    235 {
    236 }
    237 
    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 
    266 NotCurrentSurfaceTest::NotCurrentSurfaceTest (EglTestContext& context)
    267 	: NegativePartialUpdateTest (context, false, SURFACETYPE_WINDOW, "not_current_surface",  "Call setDamageRegion() on pbuffer")
    268 {
    269 }
    270 
    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 
    360 BufferPreservedTest::BufferPreservedTest (EglTestContext& context)
    361 	: NegativePartialUpdateTest (context, true, SURFACETYPE_WINDOW, "buffer_preserved",  "Call setDamageRegion() on pbuffer")
    362 {
    363 }
    364 
    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 
    393 SetTwiceTest::SetTwiceTest (EglTestContext& context)
    394 	: NegativePartialUpdateTest (context, false, SURFACETYPE_WINDOW, "set_damage_region_twice",  "Call setDamageRegion() twice")
    395 {
    396 }
    397 
    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 
    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 
    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 
    459 PassNullTest::PassNullTest (EglTestContext& context)
    460 	: NegativePartialUpdateTest (context, false, SURFACETYPE_WINDOW, "pass_null_0_as_params",  "Call setDamageRegion() with (NULL, 0)")
    461 {
    462 }
    463 
    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 
    491 NotCurrentSurfaceTest2::NotCurrentSurfaceTest2 (EglTestContext& context)
    492 	: NegativePartialUpdateTest (context, false, SURFACETYPE_WINDOW, "not_current_surface2",  "Call setDamageRegion() on pbuffer")
    493 {
    494 }
    495 
    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 
    543 NegativePartialUpdateTests::NegativePartialUpdateTests (EglTestContext& eglTestCtx)
    544 	: TestCaseGroup(eglTestCtx, "negative_partial_update", "Negative partial update tests")
    545 {
    546 }
    547 
    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