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