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,
60 const char *name, const char *description);
61 ~NegativePartialUpdateTest(void);
62 void init(void);
63 void deinit(void);
64 virtual IterateResult iterate(void) = 0;
65
66 protected:
67 void expectError(eglw::EGLenum error);
68 void expectBoolean(EGLBoolean expected, EGLBoolean got);
expectTrue(eglw::EGLBoolean got)69 inline void expectTrue(eglw::EGLBoolean got)
70 {
71 expectBoolean(EGL_TRUE, got);
72 }
expectFalse(eglw::EGLBoolean got)73 inline void expectFalse(eglw::EGLBoolean got)
74 {
75 expectBoolean(EGL_FALSE, got);
76 }
77
78 const bool m_preserveBuffer;
79 SurfaceType m_surfaceType;
80 EGLDisplay m_eglDisplay;
81 EGLConfig m_eglConfig;
82 NativeWindow *m_window;
83 EGLSurface m_eglSurface;
84 EGLContext m_eglContext;
85 };
86
isWindow(const CandidateConfig & c)87 bool isWindow(const CandidateConfig &c)
88 {
89 return (c.surfaceType() & EGL_WINDOW_BIT) == EGL_WINDOW_BIT;
90 }
91
isPbuffer(const CandidateConfig & c)92 bool isPbuffer(const CandidateConfig &c)
93 {
94 return (c.surfaceType() & EGL_PBUFFER_BIT) == EGL_PBUFFER_BIT;
95 }
96
isES2Renderable(const CandidateConfig & c)97 bool isES2Renderable(const CandidateConfig &c)
98 {
99 return (c.get(EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT) == EGL_OPENGL_ES2_BIT;
100 }
101
hasPreserveSwap(const CandidateConfig & c)102 bool hasPreserveSwap(const CandidateConfig &c)
103 {
104 return (c.surfaceType() & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) == EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
105 }
106
getEGLConfig(const Library & egl,EGLDisplay eglDisplay,unsigned surfaceTypes,bool preserveBuffer)107 EGLConfig getEGLConfig(const Library &egl, EGLDisplay eglDisplay, unsigned surfaceTypes, bool preserveBuffer)
108 {
109 FilterList filters;
110 if ((surfaceTypes & NegativePartialUpdateTest::SURFACETYPE_WINDOW) != 0)
111 filters << isWindow;
112 if ((surfaceTypes & NegativePartialUpdateTest::SURFACETYPE_PBUFFER) != 0)
113 filters << isPbuffer;
114 if (((surfaceTypes & NegativePartialUpdateTest::SURFACETYPE_WINDOW) == 0) &&
115 ((surfaceTypes & NegativePartialUpdateTest::SURFACETYPE_PBUFFER) == 0))
116 DE_FATAL("Invalid surfaceType");
117
118 filters << isES2Renderable;
119
120 if (preserveBuffer)
121 filters << hasPreserveSwap;
122
123 return chooseSingleConfig(egl, eglDisplay, filters);
124 }
125
initAndMakeCurrentEGLContext(const Library & egl,EGLDisplay eglDisplay,EGLSurface eglSurface,EGLConfig eglConfig,const EGLint * attribList)126 EGLContext initAndMakeCurrentEGLContext(const Library &egl, EGLDisplay eglDisplay, EGLSurface eglSurface,
127 EGLConfig eglConfig, const EGLint *attribList)
128 {
129 EGLContext eglContext = EGL_NO_CONTEXT;
130
131 egl.bindAPI(EGL_OPENGL_ES_API);
132 eglContext = egl.createContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, attribList);
133 EGLU_CHECK_MSG(egl, "eglCreateContext");
134 TCU_CHECK(eglSurface != EGL_NO_SURFACE);
135 egl.makeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
136 EGLU_CHECK_MSG(egl, "eglMakeCurrent");
137
138 return eglContext;
139 }
140
NegativePartialUpdateTest(EglTestContext & eglTestCtx,bool preserveBuffer,SurfaceType surfaceType,const char * name,const char * description)141 NegativePartialUpdateTest::NegativePartialUpdateTest(EglTestContext &eglTestCtx, bool preserveBuffer,
142 SurfaceType surfaceType, const char *name, const char *description)
143 : TestCase(eglTestCtx, name, description)
144 , m_preserveBuffer(preserveBuffer)
145 , m_surfaceType(surfaceType)
146 , m_eglDisplay(EGL_NO_DISPLAY)
147 , m_window(DE_NULL)
148 , m_eglSurface(EGL_NO_SURFACE)
149 , m_eglContext(EGL_NO_CONTEXT)
150 {
151 }
152
~NegativePartialUpdateTest(void)153 NegativePartialUpdateTest::~NegativePartialUpdateTest(void)
154 {
155 deinit();
156 }
157
init(void)158 void NegativePartialUpdateTest::init(void)
159 {
160 const Library &egl = m_eglTestCtx.getLibrary();
161 static const EGLint contextAttribList[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
162 const int width = 480;
163 const int height = 480;
164
165 m_eglDisplay = getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
166
167 if (!hasExtension(egl, m_eglDisplay, "EGL_KHR_partial_update"))
168 TCU_THROW(NotSupportedError, "EGL_KHR_partial_update is not supported");
169
170 if (m_surfaceType == SURFACETYPE_PBUFFER)
171 {
172 m_eglConfig = getEGLConfig(egl, m_eglDisplay, SURFACETYPE_PBUFFER, m_preserveBuffer);
173 const EGLint pbufferAttribList[] = {EGL_WIDTH, width, EGL_HEIGHT, height, EGL_NONE};
174 m_eglSurface = egl.createPbufferSurface(m_eglDisplay, m_eglConfig, pbufferAttribList);
175 }
176 else
177 {
178 m_eglConfig = getEGLConfig(egl, m_eglDisplay, SURFACETYPE_WINDOW | SURFACETYPE_PBUFFER, m_preserveBuffer);
179 const NativeWindowFactory &factory =
180 selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
181 m_window = factory.createWindow(&m_eglTestCtx.getNativeDisplay(), m_eglDisplay, m_eglConfig, DE_NULL,
182 WindowParams(width, height, parseWindowVisibility(m_testCtx.getCommandLine())));
183 m_eglSurface =
184 createWindowSurface(m_eglTestCtx.getNativeDisplay(), *m_window, m_eglDisplay, m_eglConfig, DE_NULL);
185 }
186 m_eglContext = initAndMakeCurrentEGLContext(egl, m_eglDisplay, m_eglSurface, m_eglConfig, contextAttribList);
187 }
188
deinit(void)189 void NegativePartialUpdateTest::deinit(void)
190 {
191 const Library &egl = m_eglTestCtx.getLibrary();
192
193 if (m_eglContext != EGL_NO_CONTEXT)
194 {
195 EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
196 EGLU_CHECK_CALL(egl, destroyContext(m_eglDisplay, m_eglContext));
197 m_eglContext = EGL_NO_CONTEXT;
198 }
199
200 if (m_eglSurface != EGL_NO_SURFACE)
201 {
202 EGLU_CHECK_CALL(egl, destroySurface(m_eglDisplay, m_eglSurface));
203 m_eglSurface = EGL_NO_SURFACE;
204 }
205
206 if (m_eglDisplay != EGL_NO_DISPLAY)
207 {
208 EGLU_CHECK_CALL(egl, terminate(m_eglDisplay));
209 m_eglDisplay = EGL_NO_DISPLAY;
210 }
211
212 delete m_window;
213 m_window = DE_NULL;
214 }
215
expectError(EGLenum expected)216 void NegativePartialUpdateTest::expectError(EGLenum expected)
217 {
218 const EGLenum err = m_eglTestCtx.getLibrary().getError();
219
220 if (err != expected)
221 {
222 m_testCtx.getLog() << TestLog::Message << "// ERROR expected: " << eglu::getErrorStr(expected)
223 << ", Got: " << eglu::getErrorStr(err) << TestLog::EndMessage;
224 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
225 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid error");
226 }
227 }
228
expectBoolean(EGLBoolean expected,EGLBoolean got)229 void NegativePartialUpdateTest::expectBoolean(EGLBoolean expected, EGLBoolean got)
230 {
231 if (expected != got)
232 {
233 m_testCtx.getLog() << TestLog::Message << "// ERROR expected: " << eglu::getBooleanStr(expected)
234 << ", Got: " << eglu::getBooleanStr(got) << TestLog::EndMessage;
235 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
236 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid value");
237 }
238 }
239
240 class NotPostableTest : public NegativePartialUpdateTest
241 {
242 public:
243 NotPostableTest(EglTestContext &context);
244 TestCase::IterateResult iterate(void);
245 };
246
NotPostableTest(EglTestContext & context)247 NotPostableTest::NotPostableTest(EglTestContext &context)
248 : NegativePartialUpdateTest(context, false, SURFACETYPE_PBUFFER, "not_postable_surface",
249 "Call setDamageRegion() on pbuffer")
250 {
251 }
252
iterate(void)253 TestCase::IterateResult NotPostableTest::iterate(void)
254 {
255 const Library &egl = m_eglTestCtx.getLibrary();
256 TestLog &log = m_testCtx.getLog();
257 CallLogWrapper wrapper(egl, log);
258 EGLint damageRegion[] = {10, 10, 10, 10};
259 int bufferAge = -1;
260
261 wrapper.enableLogging(true);
262 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
263 {
264 tcu::ScopedLogSection(log, "Test1", "If the surface is pbuffer (not postable) --> EGL_BAD_MATCH");
265 EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED));
266 EGLU_CHECK_CALL(egl, querySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge));
267 expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion,
268 DE_LENGTH_OF_ARRAY(damageRegion) / 4));
269 expectError(EGL_BAD_MATCH);
270 }
271
272 return STOP;
273 }
274
275 class NotCurrentSurfaceTest : public NegativePartialUpdateTest
276 {
277 public:
278 NotCurrentSurfaceTest(EglTestContext &context);
279 TestCase::IterateResult iterate(void);
280 };
281
NotCurrentSurfaceTest(EglTestContext & context)282 NotCurrentSurfaceTest::NotCurrentSurfaceTest(EglTestContext &context)
283 : NegativePartialUpdateTest(context, false, SURFACETYPE_WINDOW, "not_current_surface",
284 "Call setDamageRegion() on pbuffer")
285 {
286 }
287
iterate(void)288 TestCase::IterateResult NotCurrentSurfaceTest::iterate(void)
289 {
290 const int impossibleBufferAge = -26084;
291 const Library &egl = m_eglTestCtx.getLibrary();
292 const EGLint attribList[] = {EGL_WIDTH, 64, EGL_HEIGHT, 64, EGL_NONE};
293 const eglu::UniqueSurface unusedPbuffer(egl, m_eglDisplay,
294 egl.createPbufferSurface(m_eglDisplay, m_eglConfig, attribList));
295 TestLog &log = m_testCtx.getLog();
296 CallLogWrapper wrapper(egl, log);
297 EGLint damageRegion[] = {10, 10, 10, 10};
298 int bufferAge = impossibleBufferAge;
299
300 wrapper.enableLogging(true);
301 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
302 EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, *unusedPbuffer, *unusedPbuffer, m_eglContext));
303 {
304 tcu::ScopedLogSection(
305 log, "Test2.1",
306 "If query buffer age on a surface that is not the current draw surface --> EGL_BAD_SURFACE");
307 EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED));
308 expectFalse(wrapper.eglQuerySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge));
309 expectError(EGL_BAD_SURFACE);
310
311 if (bufferAge != impossibleBufferAge)
312 {
313 log << tcu::TestLog::Message
314 << "On failure, eglQuerySurface shouldn't change buffer age but buffer age has been changed to "
315 << bufferAge << tcu::TestLog::EndMessage;
316 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail, bufferAge shouldn't be changed");
317 }
318 }
319 {
320 tcu::ScopedLogSection(
321 log, "Test2.2",
322 "If call setDamageRegion() on a surface that is not the current draw surface --> EGL_BAD_MATCH");
323 expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, 1));
324 expectError(EGL_BAD_MATCH);
325 }
326
327 EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
328 {
329 tcu::ScopedLogSection(
330 log, "Test3.1",
331 "If query buffer age on a surface that is not the current draw surface --> EGL_BAD_SURFACE");
332 EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED));
333 expectFalse(wrapper.eglQuerySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge));
334 expectError(EGL_BAD_SURFACE);
335
336 if (bufferAge != impossibleBufferAge)
337 {
338 log << tcu::TestLog::Message
339 << "On failure, eglQuerySurface shouldn't change buffer age but buffer age has been changed to "
340 << bufferAge << tcu::TestLog::EndMessage;
341 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail, bufferAge shouldn't be changed");
342 }
343 }
344 {
345 tcu::ScopedLogSection(
346 log, "Test3.2",
347 "If call setDamageRegion() on a surface that is not the current draw surface --> EGL_BAD_MATCH");
348 expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, 1));
349 expectError(EGL_BAD_MATCH);
350 }
351
352 if (hasExtension(egl, m_eglDisplay, "EGL_KHR_surfaceless_context"))
353 {
354 EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, m_eglContext));
355 {
356 tcu::ScopedLogSection(
357 log, "Test4.1",
358 "If query buffer age on a surface that is not the current draw surface --> EGL_BAD_SURFACE");
359 EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED));
360 expectFalse(wrapper.eglQuerySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge));
361 expectError(EGL_BAD_SURFACE);
362
363 if (bufferAge != impossibleBufferAge)
364 {
365 log << tcu::TestLog::Message
366 << "On failure, eglQuerySurface shouldn't change buffer age but buffer age has been changed to "
367 << bufferAge << tcu::TestLog::EndMessage;
368 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail, bufferAge shouldn't be changed");
369 }
370 }
371 {
372 tcu::ScopedLogSection(
373 log, "Test4.2",
374 "If call setDamageRegion() on a surface that is not the current draw surface --> EGL_BAD_MATCH");
375 expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, 1));
376 expectError(EGL_BAD_MATCH);
377 }
378 }
379
380 return STOP;
381 }
382
383 class BufferPreservedTest : public NegativePartialUpdateTest
384 {
385 public:
386 BufferPreservedTest(EglTestContext &context);
387 TestCase::IterateResult iterate(void);
388 };
389
BufferPreservedTest(EglTestContext & context)390 BufferPreservedTest::BufferPreservedTest(EglTestContext &context)
391 : NegativePartialUpdateTest(context, true, SURFACETYPE_WINDOW, "buffer_preserved",
392 "Call setDamageRegion() on pbuffer")
393 {
394 }
395
iterate(void)396 TestCase::IterateResult BufferPreservedTest::iterate(void)
397 {
398 const Library &egl = m_eglTestCtx.getLibrary();
399 TestLog &log = m_testCtx.getLog();
400 CallLogWrapper wrapper(egl, log);
401 EGLint damageRegion[] = {10, 10, 10, 10};
402 int bufferAge = -1;
403
404 wrapper.enableLogging(true);
405 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
406 {
407 tcu::ScopedLogSection(log, "Test3", "If buffer_preserved --> EGL_BAD_MATCH");
408 EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED));
409 EGLU_CHECK_CALL(egl, querySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge));
410 expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion,
411 DE_LENGTH_OF_ARRAY(damageRegion) / 4));
412 expectError(EGL_BAD_MATCH);
413 }
414
415 return STOP;
416 }
417
418 class SetTwiceTest : public NegativePartialUpdateTest
419 {
420 public:
421 SetTwiceTest(EglTestContext &context);
422 TestCase::IterateResult iterate(void);
423 };
424
SetTwiceTest(EglTestContext & context)425 SetTwiceTest::SetTwiceTest(EglTestContext &context)
426 : NegativePartialUpdateTest(context, false, SURFACETYPE_WINDOW, "set_damage_region_twice",
427 "Call setDamageRegion() twice")
428 {
429 }
430
iterate(void)431 TestCase::IterateResult SetTwiceTest::iterate(void)
432 {
433 const Library &egl = m_eglTestCtx.getLibrary();
434 TestLog &log = m_testCtx.getLog();
435 CallLogWrapper wrapper(egl, log);
436 EGLint damageRegion[] = {10, 10, 10, 10};
437 int bufferAge = -1;
438
439 wrapper.enableLogging(true);
440 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
441 {
442 tcu::ScopedLogSection(log, "Test4", "If call setDamageRegion() twice --> EGL_BAD_ACCESS");
443 EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED));
444 EGLU_CHECK_CALL(egl, querySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge));
445 expectTrue(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion,
446 DE_LENGTH_OF_ARRAY(damageRegion) / 4));
447 expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion,
448 DE_LENGTH_OF_ARRAY(damageRegion) / 4));
449 expectError(EGL_BAD_ACCESS);
450 }
451
452 return STOP;
453 }
454
455 class NoAgeTest : public NegativePartialUpdateTest
456 {
457 public:
458 NoAgeTest(EglTestContext &context);
459 TestCase::IterateResult iterate(void);
460 };
461
NoAgeTest(EglTestContext & context)462 NoAgeTest::NoAgeTest(EglTestContext &context)
463 : NegativePartialUpdateTest(context, false, SURFACETYPE_WINDOW, "set_damage_region_before_query_age",
464 "Call setDamageRegion() without querying buffer age")
465 {
466 }
467
iterate(void)468 TestCase::IterateResult NoAgeTest::iterate(void)
469 {
470 const Library &egl = m_eglTestCtx.getLibrary();
471 TestLog &log = m_testCtx.getLog();
472 CallLogWrapper wrapper(egl, log);
473 EGLint damageRegion[] = {10, 10, 10, 10};
474
475 wrapper.enableLogging(true);
476 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
477 {
478 tcu::ScopedLogSection(log, "Test5", "If buffer age is not queried --> EGL_BAD_ACCESS");
479 EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED));
480 expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion,
481 DE_LENGTH_OF_ARRAY(damageRegion) / 4));
482 expectError(EGL_BAD_ACCESS);
483 }
484
485 return STOP;
486 }
487
488 class PassNullTest : public NegativePartialUpdateTest
489 {
490 public:
491 PassNullTest(EglTestContext &context);
492 TestCase::IterateResult iterate(void);
493 };
494
PassNullTest(EglTestContext & context)495 PassNullTest::PassNullTest(EglTestContext &context)
496 : NegativePartialUpdateTest(context, false, SURFACETYPE_WINDOW, "pass_null_0_as_params",
497 "Call setDamageRegion() with (NULL, 0)")
498 {
499 }
500
iterate(void)501 TestCase::IterateResult PassNullTest::iterate(void)
502 {
503 const Library &egl = m_eglTestCtx.getLibrary();
504 TestLog &log = m_testCtx.getLog();
505 CallLogWrapper wrapper(egl, log);
506 int bufferAge = -1;
507
508 wrapper.enableLogging(true);
509 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
510 {
511 tcu::ScopedLogSection(log, "Test6", "If pass (null, 0) to setDamageRegion(), no error");
512 EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED));
513 EGLU_CHECK_CALL(egl, querySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge));
514 expectTrue(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, DE_NULL, 0));
515 expectError(EGL_SUCCESS);
516 }
517
518 return STOP;
519 }
520
521 class NotCurrentSurfaceTest2 : public NegativePartialUpdateTest
522 {
523 public:
524 NotCurrentSurfaceTest2(EglTestContext &context);
525 TestCase::IterateResult iterate(void);
526 };
527
NotCurrentSurfaceTest2(EglTestContext & context)528 NotCurrentSurfaceTest2::NotCurrentSurfaceTest2(EglTestContext &context)
529 : NegativePartialUpdateTest(context, false, SURFACETYPE_WINDOW, "not_current_surface2",
530 "Call setDamageRegion() on pbuffer")
531 {
532 }
533
iterate(void)534 TestCase::IterateResult NotCurrentSurfaceTest2::iterate(void)
535 {
536 const Library &egl = m_eglTestCtx.getLibrary();
537 const EGLint attribList[] = {EGL_WIDTH, 64, EGL_HEIGHT, 64, EGL_NONE};
538 const eglu::UniqueSurface unusedPbuffer(egl, m_eglDisplay,
539 egl.createPbufferSurface(m_eglDisplay, m_eglConfig, attribList));
540 TestLog &log = m_testCtx.getLog();
541 CallLogWrapper wrapper(egl, log);
542 EGLint damageRegion[] = {10, 10, 10, 10};
543 int bufferAge = -1;
544
545 wrapper.enableLogging(true);
546 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
547
548 EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED));
549 EGLU_CHECK_CALL(egl, querySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge));
550
551 {
552 tcu::ScopedLogSection(
553 log, "Test7",
554 "If call setDamageRegion() on a surface that is not the current draw surface --> EGL_BAD_MATCH");
555 EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, *unusedPbuffer, *unusedPbuffer, m_eglContext));
556 expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, 1));
557 expectError(EGL_BAD_MATCH);
558 }
559 {
560 tcu::ScopedLogSection(
561 log, "Test8",
562 "If call setDamageRegion() on a surface that is not the current draw surface --> EGL_BAD_MATCH");
563 EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
564 expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, 1));
565 expectError(EGL_BAD_MATCH);
566 }
567 if (hasExtension(egl, m_eglDisplay, "EGL_KHR_surfaceless_context"))
568 {
569 tcu::ScopedLogSection(
570 log, "Test9",
571 "If call setDamageRegion() on a surface that is not the current draw surface --> EGL_BAD_MATCH");
572 EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, m_eglContext));
573 expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, 1));
574 expectError(EGL_BAD_MATCH);
575 }
576
577 return STOP;
578 }
579
580 } // namespace
581
NegativePartialUpdateTests(EglTestContext & eglTestCtx)582 NegativePartialUpdateTests::NegativePartialUpdateTests(EglTestContext &eglTestCtx)
583 : TestCaseGroup(eglTestCtx, "negative_partial_update", "Negative partial update tests")
584 {
585 }
586
init(void)587 void NegativePartialUpdateTests::init(void)
588 {
589 addChild(new NotPostableTest(m_eglTestCtx));
590 addChild(new NotCurrentSurfaceTest(m_eglTestCtx));
591 addChild(new BufferPreservedTest(m_eglTestCtx));
592 addChild(new SetTwiceTest(m_eglTestCtx));
593 addChild(new NoAgeTest(m_eglTestCtx));
594 addChild(new PassNullTest(m_eglTestCtx));
595 addChild(new NotCurrentSurfaceTest2(m_eglTestCtx));
596 }
597
598 } // namespace egl
599 } // namespace deqp
600