1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program EGL Module
3 * ---------------------------------------
4 *
5 * Copyright 2014 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 EGL_SWAP_BEHAVIOR_PRESERVED_BIT.
22 *//*--------------------------------------------------------------------*/
23
24 #include "teglPreservingSwapTests.hpp"
25
26 #include "tcuImageCompare.hpp"
27 #include "tcuTestLog.hpp"
28 #include "tcuSurface.hpp"
29 #include "tcuTextureUtil.hpp"
30
31 #include "egluNativeWindow.hpp"
32 #include "egluUtil.hpp"
33
34 #include "eglwLibrary.hpp"
35 #include "eglwEnums.hpp"
36
37 #include "gluDefs.hpp"
38 #include "gluRenderContext.hpp"
39 #include "gluShaderProgram.hpp"
40
41 #include "glwDefs.hpp"
42 #include "glwEnums.hpp"
43 #include "glwFunctions.hpp"
44
45 #include "deRandom.hpp"
46
47 #include "deString.h"
48
49 #include <vector>
50 #include <string>
51
52 using std::vector;
53 using std::string;
54
55 using namespace eglw;
56
57 namespace deqp
58 {
59 namespace egl
60 {
61
62 namespace
63 {
64 class GLES2Program;
65 class ReferenceProgram;
66
67 class PreservingSwapTest : public TestCase
68 {
69 public:
70 enum DrawType
71 {
72 DRAWTYPE_NONE = 0,
73 DRAWTYPE_GLES2_CLEAR,
74 DRAWTYPE_GLES2_RENDER
75 };
76
77 PreservingSwapTest (EglTestContext& eglTestCtx, bool preserveColorbuffer, bool readPixelsBeforeSwap, DrawType preSwapDrawType, DrawType postSwapDrawType, const char* name, const char* description);
78 ~PreservingSwapTest (void);
79
80 void init (void);
81 void deinit (void);
82 IterateResult iterate (void);
83
84 private:
85 const int m_seed;
86 const bool m_preserveColorbuffer;
87 const bool m_readPixelsBeforeSwap;
88 const DrawType m_preSwapDrawType;
89 const DrawType m_postSwapDrawType;
90
91 EGLDisplay m_eglDisplay;
92 eglu::NativeWindow* m_window;
93 EGLSurface m_eglSurface;
94 EGLConfig m_eglConfig;
95 EGLContext m_eglContext;
96 glw::Functions m_gl;
97
98 GLES2Program* m_gles2Program;
99 ReferenceProgram* m_refProgram;
100
101 void initEGLSurface (EGLConfig config);
102 void initEGLContext (EGLConfig config);
103 };
104
105 class GLES2Program
106 {
107 public:
108 GLES2Program (const glw::Functions& gl);
109 ~GLES2Program (void);
110
111 void render (int width, int height, float x1, float y1, float x2, float y2, PreservingSwapTest::DrawType drawType);
112
113 private:
114 const glw::Functions& m_gl;
115 glu::ShaderProgram m_glProgram;
116 glw::GLuint m_coordLoc;
117 glw::GLuint m_colorLoc;
118
119 GLES2Program& operator= (const GLES2Program&);
120 GLES2Program (const GLES2Program&);
121 };
122
getSources(void)123 static glu::ProgramSources getSources (void)
124 {
125 const char* const vertexShaderSource =
126 "attribute mediump vec4 a_pos;\n"
127 "attribute mediump vec4 a_color;\n"
128 "varying mediump vec4 v_color;\n"
129 "void main(void)\n"
130 "{\n"
131 "\tv_color = a_color;\n"
132 "\tgl_Position = a_pos;\n"
133 "}";
134
135 const char* const fragmentShaderSource =
136 "varying mediump vec4 v_color;\n"
137 "void main(void)\n"
138 "{\n"
139 "\tgl_FragColor = v_color;\n"
140 "}";
141
142 return glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource);
143 }
144
GLES2Program(const glw::Functions & gl)145 GLES2Program::GLES2Program (const glw::Functions& gl)
146 : m_gl (gl)
147 , m_glProgram (gl, getSources())
148 , m_coordLoc ((glw::GLuint)-1)
149 , m_colorLoc ((glw::GLuint)-1)
150 {
151 m_colorLoc = m_gl.getAttribLocation(m_glProgram.getProgram(), "a_color");
152 m_coordLoc = m_gl.getAttribLocation(m_glProgram.getProgram(), "a_pos");
153 GLU_EXPECT_NO_ERROR(m_gl.getError(), "Failed to get attribute locations");
154 }
155
~GLES2Program(void)156 GLES2Program::~GLES2Program (void)
157 {
158 }
159
render(int width,int height,float x1,float y1,float x2,float y2,PreservingSwapTest::DrawType drawType)160 void GLES2Program::render (int width, int height, float x1, float y1, float x2, float y2, PreservingSwapTest::DrawType drawType)
161 {
162 if (drawType == PreservingSwapTest::DRAWTYPE_GLES2_RENDER)
163 {
164 const glw::GLfloat coords[] =
165 {
166 x1, y1, 0.0f, 1.0f,
167 x1, y2, 0.0f, 1.0f,
168 x2, y2, 0.0f, 1.0f,
169
170 x2, y2, 0.0f, 1.0f,
171 x2, y1, 0.0f, 1.0f,
172 x1, y1, 0.0f, 1.0f
173 };
174
175 const glw::GLubyte colors[] =
176 {
177 127, 127, 127, 255,
178 127, 127, 127, 255,
179 127, 127, 127, 255,
180
181 127, 127, 127, 255,
182 127, 127, 127, 255,
183 127, 127, 127, 255
184 };
185
186 m_gl.useProgram(m_glProgram.getProgram());
187 GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUseProgram() failed");
188
189 m_gl.enableVertexAttribArray(m_coordLoc);
190 m_gl.enableVertexAttribArray(m_colorLoc);
191 GLU_EXPECT_NO_ERROR(m_gl.getError(), "Failed to enable attributes");
192
193 m_gl.vertexAttribPointer(m_coordLoc, 4, GL_FLOAT, GL_FALSE, 0, coords);
194 m_gl.vertexAttribPointer(m_colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, colors);
195 GLU_EXPECT_NO_ERROR(m_gl.getError(), "Failed to set attribute pointers");
196
197 m_gl.drawArrays(GL_TRIANGLES, 0, 6);
198 GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDrawArrays() failed");
199
200 m_gl.disableVertexAttribArray(m_coordLoc);
201 m_gl.disableVertexAttribArray(m_colorLoc);
202 GLU_EXPECT_NO_ERROR(m_gl.getError(), "Failed to disable attributes");
203
204 m_gl.useProgram(0);
205 GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUseProgram() failed");
206 }
207 else if (drawType == PreservingSwapTest::DRAWTYPE_GLES2_CLEAR)
208 {
209 const int ox = width/2;
210 const int oy = height/2;
211
212 const int px = width;
213 const int py = height;
214
215 const int x1i = (int)((px/2.0f) * x1 + ox);
216 const int y1i = (int)((py/2.0f) * y1 + oy);
217
218 const int x2i = (int)((px/2.0f) * x2 + ox);
219 const int y2i = (int)((py/2.0f) * y2 + oy);
220
221 m_gl.enable(GL_SCISSOR_TEST);
222 m_gl.scissor(x1i, y1i, x2i-x1i, y2i-y1i);
223 m_gl.clearColor(0.5f, 0.5f, 0.5f, 1.0f);
224 m_gl.clear(GL_COLOR_BUFFER_BIT);
225 m_gl.disable(GL_SCISSOR_TEST);
226 }
227 else
228 DE_ASSERT(false);
229 }
230
231 class ReferenceProgram
232 {
233 public:
234 ReferenceProgram (void);
235 ~ReferenceProgram (void);
236
237 void render (tcu::Surface* target, float x1, float y1, float x2, float y2, PreservingSwapTest::DrawType drawType);
238
239 private:
240 ReferenceProgram (const ReferenceProgram&);
241 ReferenceProgram& operator= (const ReferenceProgram&);
242 };
243
ReferenceProgram(void)244 ReferenceProgram::ReferenceProgram (void)
245 {
246 }
247
~ReferenceProgram(void)248 ReferenceProgram::~ReferenceProgram (void)
249 {
250 }
251
render(tcu::Surface * target,float x1,float y1,float x2,float y2,PreservingSwapTest::DrawType drawType)252 void ReferenceProgram::render (tcu::Surface* target, float x1, float y1, float x2, float y2, PreservingSwapTest::DrawType drawType)
253 {
254 if (drawType == PreservingSwapTest::DRAWTYPE_GLES2_RENDER || drawType == PreservingSwapTest::DRAWTYPE_GLES2_CLEAR)
255 {
256 const int ox = target->getWidth()/2;
257 const int oy = target->getHeight()/2;
258
259 const int px = target->getWidth();
260 const int py = target->getHeight();
261
262 const int x1i = (int)((px/2.0) * x1 + ox);
263 const int y1i = (int)((py/2.0) * y1 + oy);
264
265 const int x2i = (int)((px/2.0) * x2 + ox);
266 const int y2i = (int)((py/2.0) * y2 + oy);
267
268 const tcu::RGBA color(127, 127, 127, 255);
269
270 for (int y = y1i; y <= y2i; y++)
271 {
272 for (int x = x1i; x <= x2i; x++)
273 target->setPixel(x, y, color);
274 }
275 }
276 else
277 DE_ASSERT(false);
278 }
279
PreservingSwapTest(EglTestContext & eglTestCtx,bool preserveColorbuffer,bool readPixelsBeforeSwap,DrawType preSwapDrawType,DrawType postSwapDrawType,const char * name,const char * description)280 PreservingSwapTest::PreservingSwapTest (EglTestContext& eglTestCtx, bool preserveColorbuffer, bool readPixelsBeforeSwap, DrawType preSwapDrawType, DrawType postSwapDrawType, const char* name, const char* description)
281 : TestCase (eglTestCtx, name, description)
282 , m_seed (deStringHash(name))
283 , m_preserveColorbuffer (preserveColorbuffer)
284 , m_readPixelsBeforeSwap (readPixelsBeforeSwap)
285 , m_preSwapDrawType (preSwapDrawType)
286 , m_postSwapDrawType (postSwapDrawType)
287 , m_eglDisplay (EGL_NO_DISPLAY)
288 , m_window (DE_NULL)
289 , m_eglSurface (EGL_NO_SURFACE)
290 , m_eglContext (EGL_NO_CONTEXT)
291 , m_gles2Program (DE_NULL)
292 , m_refProgram (DE_NULL)
293 {
294 }
295
~PreservingSwapTest(void)296 PreservingSwapTest::~PreservingSwapTest (void)
297 {
298 deinit();
299 }
300
getEGLConfig(const Library & egl,EGLDisplay eglDisplay,bool preserveColorbuffer)301 EGLConfig getEGLConfig (const Library& egl, EGLDisplay eglDisplay, bool preserveColorbuffer)
302 {
303 const EGLint attribList[] =
304 {
305 EGL_SURFACE_TYPE, EGL_WINDOW_BIT | (preserveColorbuffer ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0),
306 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
307 EGL_NONE
308 };
309
310 return eglu::chooseSingleConfig(egl, eglDisplay, &attribList[0]);
311 }
312
clearColorScreen(const glw::Functions & gl,float red,float green,float blue,float alpha)313 void clearColorScreen (const glw::Functions& gl, float red, float green, float blue, float alpha)
314 {
315 gl.clearColor(red, green, blue, alpha);
316 gl.clear(GL_COLOR_BUFFER_BIT);
317 }
318
clearColorReference(tcu::Surface * ref,float red,float green,float blue,float alpha)319 void clearColorReference (tcu::Surface* ref, float red, float green, float blue, float alpha)
320 {
321 tcu::clear(ref->getAccess(), tcu::Vec4(red, green, blue, alpha));
322 }
323
readPixels(const glw::Functions & gl,tcu::Surface * screen)324 void readPixels (const glw::Functions& gl, tcu::Surface* screen)
325 {
326 gl.readPixels(0, 0, screen->getWidth(), screen->getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen->getAccess().getDataPtr());
327 }
328
initEGLSurface(EGLConfig config)329 void PreservingSwapTest::initEGLSurface (EGLConfig config)
330 {
331 const eglu::NativeWindowFactory& factory = eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
332
333 m_window = factory.createWindow(&m_eglTestCtx.getNativeDisplay(), m_eglDisplay, config, DE_NULL, eglu::WindowParams(480, 480, eglu::parseWindowVisibility(m_testCtx.getCommandLine())));
334 m_eglSurface = eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *m_window, m_eglDisplay, config, DE_NULL);
335 }
336
initEGLContext(EGLConfig config)337 void PreservingSwapTest::initEGLContext (EGLConfig config)
338 {
339 const Library& egl = m_eglTestCtx.getLibrary();
340 const EGLint attribList[] =
341 {
342 EGL_CONTEXT_CLIENT_VERSION, 2,
343 EGL_NONE
344 };
345
346 egl.bindAPI(EGL_OPENGL_ES_API);
347 m_eglContext = egl.createContext(m_eglDisplay, config, EGL_NO_CONTEXT, attribList);
348 EGLU_CHECK_MSG(egl, "eglCreateContext");
349
350 DE_ASSERT(m_eglSurface != EGL_NO_SURFACE);
351 egl.makeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext);
352 EGLU_CHECK_MSG(egl, "eglMakeCurrent");
353 }
354
init(void)355 void PreservingSwapTest::init (void)
356 {
357 m_eglDisplay = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
358 m_eglConfig = getEGLConfig(m_eglTestCtx.getLibrary(), m_eglDisplay, m_preserveColorbuffer);
359
360 if (m_eglConfig == DE_NULL)
361 TCU_THROW(NotSupportedError, "No supported config found");
362
363 initEGLSurface(m_eglConfig);
364 initEGLContext(m_eglConfig);
365
366 m_eglTestCtx.initGLFunctions(&m_gl, glu::ApiType::es(2,0));
367
368 m_gles2Program = new GLES2Program(m_gl);
369 m_refProgram = new ReferenceProgram();
370 }
371
deinit(void)372 void PreservingSwapTest::deinit (void)
373 {
374 const Library& egl = m_eglTestCtx.getLibrary();
375
376 delete m_refProgram;
377 m_refProgram = DE_NULL;
378
379 delete m_gles2Program;
380 m_gles2Program = DE_NULL;
381
382 if (m_eglContext != EGL_NO_CONTEXT)
383 {
384 egl.makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
385 egl.destroyContext(m_eglDisplay, m_eglContext);
386 m_eglContext = EGL_NO_CONTEXT;
387 }
388
389 if (m_eglSurface != EGL_NO_SURFACE)
390 {
391 egl.destroySurface(m_eglDisplay, m_eglSurface);
392 m_eglSurface = EGL_NO_SURFACE;
393 }
394
395 if (m_eglDisplay != EGL_NO_DISPLAY)
396 {
397 egl.terminate(m_eglDisplay);
398 m_eglDisplay = EGL_NO_DISPLAY;
399 }
400
401 delete m_window;
402 m_window = DE_NULL;
403 }
404
compareToReference(tcu::TestLog & log,const char * name,const char * description,const tcu::Surface & reference,const tcu::Surface & screen,int x,int y,int width,int height)405 bool compareToReference (tcu::TestLog& log, const char* name, const char* description, const tcu::Surface& reference, const tcu::Surface& screen, int x, int y, int width, int height)
406 {
407 return tcu::fuzzyCompare(log, name, description,
408 getSubregion(reference.getAccess(), x, y, width, height),
409 getSubregion(screen.getAccess(), x, y, width, height),
410 0.05f, tcu::COMPARE_LOG_RESULT);
411 }
412
comparePreAndPostSwapFramebuffers(tcu::TestLog & log,const tcu::Surface & preSwap,const tcu::Surface & postSwap)413 bool comparePreAndPostSwapFramebuffers (tcu::TestLog& log, const tcu::Surface& preSwap, const tcu::Surface& postSwap)
414 {
415 return tcu::pixelThresholdCompare(log, "Pre- / Post framebuffer compare", "Compare pre- and post-swap framebuffers", preSwap, postSwap, tcu::RGBA(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT);
416 }
417
iterate(void)418 TestCase::IterateResult PreservingSwapTest::iterate (void)
419 {
420 const Library& egl = m_eglTestCtx.getLibrary();
421 tcu::TestLog& log = m_testCtx.getLog();
422 de::Random rnd(m_seed);
423
424 const int width = eglu::querySurfaceInt(egl, m_eglDisplay, m_eglSurface, EGL_WIDTH);
425 const int height = eglu::querySurfaceInt(egl, m_eglDisplay, m_eglSurface, EGL_HEIGHT);
426
427 const float clearRed = rnd.getFloat();
428 const float clearGreen = rnd.getFloat();
429 const float clearBlue = rnd.getFloat();
430 const float clearAlpha = 1.0f;
431
432 const float preSwapX1 = -0.9f * rnd.getFloat();
433 const float preSwapY1 = -0.9f * rnd.getFloat();
434 const float preSwapX2 = 0.9f * rnd.getFloat();
435 const float preSwapY2 = 0.9f * rnd.getFloat();
436
437 const float postSwapX1 = -0.9f * rnd.getFloat();
438 const float postSwapY1 = -0.9f * rnd.getFloat();
439 const float postSwapX2 = 0.9f * rnd.getFloat();
440 const float postSwapY2 = 0.9f * rnd.getFloat();
441
442 tcu::Surface postSwapFramebufferReference(width, height);
443 tcu::Surface preSwapFramebufferReference(width, height);
444
445 tcu::Surface postSwapFramebuffer(width, height);
446 tcu::Surface preSwapFramebuffer(width, height);
447
448 if (m_preserveColorbuffer)
449 EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED));
450
451 EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext));
452
453 clearColorScreen(m_gl, clearRed, clearGreen, clearBlue, clearAlpha);
454
455 if (m_readPixelsBeforeSwap)
456 clearColorReference(&preSwapFramebufferReference, clearRed, clearGreen, clearBlue, clearAlpha);
457
458 clearColorReference(&postSwapFramebufferReference, clearRed, clearGreen, clearBlue, clearAlpha);
459
460 if (m_preSwapDrawType != DRAWTYPE_NONE)
461 {
462 m_gles2Program->render(width, height, preSwapX1, preSwapY1, preSwapX2, preSwapY2, m_preSwapDrawType);
463 m_refProgram->render(&postSwapFramebufferReference, preSwapX1, preSwapY1, preSwapX2, preSwapY2, m_preSwapDrawType);
464 }
465
466 if (m_readPixelsBeforeSwap)
467 {
468 if (m_preSwapDrawType != DRAWTYPE_NONE)
469 m_refProgram->render(&preSwapFramebufferReference, preSwapX1, preSwapY1, preSwapX2, preSwapY2, m_preSwapDrawType);
470
471 readPixels(m_gl, &preSwapFramebuffer);
472 }
473
474 EGLU_CHECK_CALL(egl, swapBuffers(m_eglDisplay, m_eglSurface));
475
476 if (m_postSwapDrawType != DRAWTYPE_NONE)
477 {
478 m_refProgram->render(&postSwapFramebufferReference, postSwapX1, postSwapY1, postSwapX2, postSwapY2, m_postSwapDrawType);
479 m_gles2Program->render(width, height, postSwapX1, postSwapY1, postSwapX2, postSwapY2, m_postSwapDrawType);
480 }
481
482 readPixels(m_gl, &postSwapFramebuffer);
483
484 bool isOk = true;
485
486 if (m_preserveColorbuffer)
487 {
488 if (m_readPixelsBeforeSwap)
489 isOk = isOk && compareToReference(log, "Compare pre-swap framebuffer to reference", "Compare pre-swap framebuffer to reference", preSwapFramebufferReference, preSwapFramebuffer, 0, 0, width, height);
490
491 isOk = isOk && compareToReference(log, "Compare post-swap framebuffer to reference", "Compare post-swap framebuffer to reference", postSwapFramebufferReference, postSwapFramebuffer, 0, 0, width, height);
492
493 if (m_readPixelsBeforeSwap && m_postSwapDrawType == PreservingSwapTest::DRAWTYPE_NONE)
494 isOk = isOk && comparePreAndPostSwapFramebuffers(log, preSwapFramebuffer, postSwapFramebuffer);
495 }
496 else
497 {
498 const int ox = width/2;
499 const int oy = height/2;
500
501 const int px = width;
502 const int py = height;
503
504 const int x1i = (int)((px/2.0f) * postSwapX1 + ox);
505 const int y1i = (int)((py/2.0f) * postSwapY1 + oy);
506
507 const int x2i = (int)((px/2.0f) * postSwapX2 + ox);
508 const int y2i = (int)((py/2.0f) * postSwapY2 + oy);
509
510 if (m_readPixelsBeforeSwap)
511 isOk = isOk && compareToReference(log, "Compare pre-swap framebuffer to reference", "Compare pre-swap framebuffer to reference", preSwapFramebufferReference, preSwapFramebuffer, 0, 0, width, height);
512
513 DE_ASSERT(m_postSwapDrawType != DRAWTYPE_NONE);
514 isOk = isOk && compareToReference(log, "Compare valid are of post-swap framebuffer to reference", "Compare valid area of post-swap framebuffer to reference", postSwapFramebufferReference, postSwapFramebuffer, x1i, y1i, x2i - x1i, y2i - y1i);
515 }
516
517 if (isOk)
518 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
519 else
520 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
521
522 return STOP;
523 }
524
generateTestName(PreservingSwapTest::DrawType preSwapDrawType,PreservingSwapTest::DrawType postSwapDrawType)525 string generateTestName (PreservingSwapTest::DrawType preSwapDrawType, PreservingSwapTest::DrawType postSwapDrawType)
526 {
527 std::ostringstream stream;
528
529 if (preSwapDrawType == PreservingSwapTest::DRAWTYPE_NONE && postSwapDrawType == PreservingSwapTest::DRAWTYPE_NONE)
530 stream << "no_draw";
531 else
532 {
533 switch (preSwapDrawType)
534 {
535 case PreservingSwapTest::DRAWTYPE_NONE:
536 // Do nothing
537 break;
538
539 case PreservingSwapTest::DRAWTYPE_GLES2_RENDER:
540 stream << "pre_render";
541 break;
542
543 case PreservingSwapTest::DRAWTYPE_GLES2_CLEAR:
544 stream << "pre_clear";
545 break;
546
547 default:
548 DE_ASSERT(false);
549 }
550
551 if (preSwapDrawType != PreservingSwapTest::DRAWTYPE_NONE && postSwapDrawType != PreservingSwapTest::DRAWTYPE_NONE)
552 stream << "_";
553
554 switch (postSwapDrawType)
555 {
556 case PreservingSwapTest::DRAWTYPE_NONE:
557 // Do nothing
558 break;
559
560 case PreservingSwapTest::DRAWTYPE_GLES2_RENDER:
561 stream << "post_render";
562 break;
563
564 case PreservingSwapTest::DRAWTYPE_GLES2_CLEAR:
565 stream << "post_clear";
566 break;
567
568 default:
569 DE_ASSERT(false);
570 }
571 }
572
573 return stream.str();
574 }
575
576 } // anonymous
577
PreservingSwapTests(EglTestContext & eglTestCtx)578 PreservingSwapTests::PreservingSwapTests (EglTestContext& eglTestCtx)
579 : TestCaseGroup(eglTestCtx, "preserve_swap", "Color buffer preserving swap tests")
580 {
581 }
582
init(void)583 void PreservingSwapTests::init (void)
584 {
585 const PreservingSwapTest::DrawType preSwapDrawTypes[] =
586 {
587 PreservingSwapTest::DRAWTYPE_NONE,
588 PreservingSwapTest::DRAWTYPE_GLES2_CLEAR,
589 PreservingSwapTest::DRAWTYPE_GLES2_RENDER
590 };
591
592 const PreservingSwapTest::DrawType postSwapDrawTypes[] =
593 {
594 PreservingSwapTest::DRAWTYPE_NONE,
595 PreservingSwapTest::DRAWTYPE_GLES2_CLEAR,
596 PreservingSwapTest::DRAWTYPE_GLES2_RENDER
597 };
598
599 for (int preserveNdx = 0; preserveNdx < 2; preserveNdx++)
600 {
601 const bool preserve = (preserveNdx == 0);
602 TestCaseGroup* const preserveGroup = new TestCaseGroup(m_eglTestCtx, (preserve ? "preserve" : "no_preserve"), "");
603
604 for (int readPixelsNdx = 0; readPixelsNdx < 2; readPixelsNdx++)
605 {
606 const bool readPixelsBeforeSwap = (readPixelsNdx == 1);
607 TestCaseGroup* const readPixelsBeforeSwapGroup = new TestCaseGroup(m_eglTestCtx, (readPixelsBeforeSwap ? "read_before_swap" : "no_read_before_swap"), "");
608
609 for (int preSwapDrawTypeNdx = 0; preSwapDrawTypeNdx < DE_LENGTH_OF_ARRAY(preSwapDrawTypes); preSwapDrawTypeNdx++)
610 {
611 const PreservingSwapTest::DrawType preSwapDrawType = preSwapDrawTypes[preSwapDrawTypeNdx];
612
613 for (int postSwapDrawTypeNdx = 0; postSwapDrawTypeNdx < DE_LENGTH_OF_ARRAY(postSwapDrawTypes); postSwapDrawTypeNdx++)
614 {
615 const PreservingSwapTest::DrawType postSwapDrawType = postSwapDrawTypes[postSwapDrawTypeNdx];
616
617 // If not preserving and rendering after swap, then there is nothing to verify
618 if (!preserve && postSwapDrawType == PreservingSwapTest::DRAWTYPE_NONE)
619 continue;
620
621 const std::string name = generateTestName(preSwapDrawType, postSwapDrawType);
622
623 readPixelsBeforeSwapGroup->addChild(new PreservingSwapTest(m_eglTestCtx, preserve, readPixelsBeforeSwap, preSwapDrawType, postSwapDrawType, name.c_str(), ""));
624 }
625 }
626
627 preserveGroup->addChild(readPixelsBeforeSwapGroup);
628 }
629
630 addChild(preserveGroup);
631 }
632 }
633
634 } // egl
635 } // deqp
636