Merge "Add support for EGL_EXT_pixel_format_float" into nougat-cts-dev am: 13a05434cc...
[platform/upstream/VK-GL-CTS.git] / modules / egl / teglPreservingSwapTests.cpp
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
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
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
156 GLES2Program::~GLES2Program (void)
157 {
158 }
159
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)(((float)px/2.0f) * x1 + (float)ox);
216                 const int y1i   = (int)(((float)py/2.0f) * y1 + (float)oy);
217
218                 const int x2i   = (int)(((float)px/2.0f) * x2 + (float)ox);
219                 const int y2i   = (int)(((float)py/2.0f) * y2 + (float)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
244 ReferenceProgram::ReferenceProgram (void)
245 {
246 }
247
248 ReferenceProgram::~ReferenceProgram (void)
249 {
250 }
251
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
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
296 PreservingSwapTest::~PreservingSwapTest (void)
297 {
298         deinit();
299 }
300
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
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
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
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
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
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
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
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
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
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
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)(((float)px/2.0f) * postSwapX1 + (float)ox);
505                 const int y1i   = (int)(((float)py/2.0f) * postSwapY1 + (float)oy);
506
507                 const int x2i   = (int)(((float)px/2.0f) * postSwapX2 + (float)ox);
508                 const int y2i   = (int)(((float)py/2.0f) * postSwapY2 + (float)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
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
578 PreservingSwapTests::PreservingSwapTests (EglTestContext& eglTestCtx)
579         : TestCaseGroup(eglTestCtx, "preserve_swap", "Color buffer preserving swap tests")
580 {
581 }
582
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