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 eglMakeCurrent performance tests. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "teglMakeCurrentPerfTests.hpp" 25 26 #include "egluNativeWindow.hpp" 27 #include "egluNativePixmap.hpp" 28 #include "egluUtil.hpp" 29 30 #include "eglwLibrary.hpp" 31 #include "eglwEnums.hpp" 32 33 #include "tcuTestLog.hpp" 34 35 #include "deRandom.hpp" 36 #include "deStringUtil.hpp" 37 38 #include "deClock.h" 39 #include "deString.h" 40 41 #include <algorithm> 42 #include <cmath> 43 #include <limits> 44 #include <sstream> 45 #include <string> 46 #include <vector> 47 48 using std::ostringstream; 49 using std::string; 50 using std::vector; 51 52 using tcu::TestLog; 53 54 using namespace eglw; 55 56 namespace deqp 57 { 58 namespace egl 59 { 60 61 class MakeCurrentPerfCase : public TestCase 62 { 63 public: 64 enum SurfaceType 65 { 66 SURFACETYPE_PBUFFER = (1<<0), 67 SURFACETYPE_WINDOW = (1<<1), 68 SURFACETYPE_PIXMAP = (1<<2) 69 }; 70 71 struct Spec 72 { 73 SurfaceType surfaceTypes; 74 int contextCount; 75 int surfaceCount; 76 77 bool release; 78 79 int iterationCount; 80 int sampleCount; 81 82 string toName (void) const; 83 string toDescription (void) const; 84 }; 85 MakeCurrentPerfCase (EglTestContext& eglTestCtx, const Spec& spec, const char* name, const char* description); 86 ~MakeCurrentPerfCase (void); 87 88 void init (void); 89 void deinit (void); 90 IterateResult iterate (void); 91 92 private: 93 Spec m_spec; 94 de::Random m_rnd; 95 96 EGLDisplay m_display; 97 EGLConfig m_config; 98 vector<EGLContext> m_contexts; 99 vector<EGLSurface> m_surfaces; 100 101 vector<eglu::NativeWindow*> m_windows; 102 vector<eglu::NativePixmap*> m_pixmaps; 103 104 vector<deUint64> m_samples; 105 106 void chooseConfig (void); 107 void createSurfaces (void); 108 void createContexts (void); 109 110 void destroySurfaces (void); 111 void destroyContexts (void); 112 113 void createPBuffer (void); 114 void createWindow (void); 115 void createPixmap (void); 116 117 void logTestInfo (void); 118 void logResults (void); 119 // Disabled 120 MakeCurrentPerfCase (const MakeCurrentPerfCase&); 121 MakeCurrentPerfCase& operator= (const MakeCurrentPerfCase&); 122 }; 123 124 string MakeCurrentPerfCase::Spec::toName (void) const 125 { 126 ostringstream name; 127 128 name << "context"; 129 130 if (contextCount > 1) 131 name << "s_" << contextCount; 132 133 if ((surfaceTypes & SURFACETYPE_WINDOW) != 0) 134 name << "_window" << (surfaceCount > 1 ? "s" : ""); 135 136 if ((surfaceTypes & SURFACETYPE_PIXMAP) != 0) 137 name << "_pixmap" << (surfaceCount > 1 ? "s" : ""); 138 139 if ((surfaceTypes & SURFACETYPE_PBUFFER) != 0) 140 name << "_pbuffer" << (surfaceCount > 1 ? "s" : ""); 141 142 if (surfaceCount > 1) 143 name << "_" << surfaceCount; 144 145 if (release) 146 name << "_release"; 147 148 return name.str(); 149 } 150 151 string MakeCurrentPerfCase::Spec::toDescription (void) const 152 { 153 // \todo [mika] Generate descrpition 154 return toName(); 155 } 156 157 MakeCurrentPerfCase::MakeCurrentPerfCase (EglTestContext& eglTestCtx, const Spec& spec, const char* name, const char* description) 158 : TestCase (eglTestCtx, tcu::NODETYPE_PERFORMANCE, name, description) 159 , m_spec (spec) 160 , m_rnd (deStringHash(name)) 161 , m_display (EGL_NO_DISPLAY) 162 , m_config (DE_NULL) 163 { 164 } 165 166 MakeCurrentPerfCase::~MakeCurrentPerfCase (void) 167 { 168 deinit(); 169 } 170 171 void MakeCurrentPerfCase::init (void) 172 { 173 m_display = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay()); 174 175 chooseConfig(); 176 createContexts(); 177 createSurfaces(); 178 } 179 180 void MakeCurrentPerfCase::deinit (void) 181 { 182 destroyContexts(); 183 destroySurfaces(); 184 185 if (m_display != EGL_NO_DISPLAY) 186 { 187 m_eglTestCtx.getLibrary().terminate(m_display); 188 m_display = EGL_NO_DISPLAY; 189 } 190 } 191 192 void MakeCurrentPerfCase::chooseConfig (void) 193 { 194 const EGLint surfaceBits = ((m_spec.surfaceTypes & SURFACETYPE_WINDOW) != 0 ? EGL_WINDOW_BIT : 0) 195 | ((m_spec.surfaceTypes & SURFACETYPE_PIXMAP) != 0 ? EGL_PIXMAP_BIT : 0) 196 | ((m_spec.surfaceTypes & SURFACETYPE_PBUFFER) != 0 ? EGL_PBUFFER_BIT : 0); 197 198 const EGLint attribList[] = { 199 EGL_SURFACE_TYPE, surfaceBits, 200 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 201 EGL_NONE 202 }; 203 204 const Library& egl = m_eglTestCtx.getLibrary(); 205 EGLint configCount = 0; 206 207 EGLU_CHECK_CALL(egl, chooseConfig(m_display, attribList, &m_config, 1, &configCount)); 208 209 if (configCount <= 0) 210 throw tcu::NotSupportedError("No compatible configs found"); 211 } 212 213 void MakeCurrentPerfCase::createSurfaces (void) 214 { 215 vector<SurfaceType> types; 216 217 if ((m_spec.surfaceTypes & SURFACETYPE_WINDOW) != 0) 218 types.push_back(SURFACETYPE_WINDOW); 219 220 if ((m_spec.surfaceTypes & SURFACETYPE_PIXMAP) != 0) 221 types.push_back(SURFACETYPE_PIXMAP); 222 223 if ((m_spec.surfaceTypes & SURFACETYPE_PBUFFER) != 0) 224 types.push_back(SURFACETYPE_PBUFFER); 225 226 DE_ASSERT((int)types.size() <= m_spec.surfaceCount); 227 228 // Create surfaces 229 for (int surfaceNdx = 0; surfaceNdx < m_spec.surfaceCount; surfaceNdx++) 230 { 231 SurfaceType type = types[surfaceNdx % types.size()]; 232 233 switch (type) 234 { 235 case SURFACETYPE_PBUFFER: 236 createPBuffer(); 237 break; 238 239 case SURFACETYPE_WINDOW: 240 createWindow(); 241 break; 242 243 case SURFACETYPE_PIXMAP: 244 createPixmap(); 245 break; 246 247 default: 248 DE_ASSERT(false); 249 }; 250 } 251 } 252 253 void MakeCurrentPerfCase::createPBuffer (void) 254 { 255 const Library& egl = m_eglTestCtx.getLibrary(); 256 const EGLint width = 256; 257 const EGLint height = 256; 258 259 const EGLint attribList[] = { 260 EGL_WIDTH, width, 261 EGL_HEIGHT, height, 262 EGL_NONE 263 }; 264 265 EGLSurface surface = egl.createPbufferSurface(m_display, m_config, attribList); 266 267 EGLU_CHECK_MSG(egl, "eglCreatePbufferSurface()"); 268 269 m_surfaces.push_back(surface); 270 } 271 272 void MakeCurrentPerfCase::createWindow (void) 273 { 274 const Library& egl = m_eglTestCtx.getLibrary(); 275 const EGLint width = 256; 276 const EGLint height = 256; 277 278 const eglu::NativeWindowFactory& windowFactory = eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine()); 279 280 eglu::NativeWindow* window = DE_NULL; 281 EGLSurface surface = EGL_NO_SURFACE; 282 283 try 284 { 285 window = windowFactory.createWindow(&m_eglTestCtx.getNativeDisplay(), m_display, m_config, DE_NULL, eglu::WindowParams(width, height, eglu::parseWindowVisibility(m_eglTestCtx.getTestContext().getCommandLine()))); 286 surface = eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *window, m_display, m_config, DE_NULL); 287 } 288 catch (...) 289 { 290 if (surface != EGL_NO_SURFACE) 291 egl.destroySurface(m_display, surface); 292 293 delete window; 294 throw; 295 } 296 297 m_windows.push_back(window); 298 m_surfaces.push_back(surface); 299 } 300 301 void MakeCurrentPerfCase::createPixmap (void) 302 { 303 const Library& egl = m_eglTestCtx.getLibrary(); 304 const EGLint width = 256; 305 const EGLint height = 256; 306 307 const eglu::NativePixmapFactory& pixmapFactory = eglu::selectNativePixmapFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine()); 308 309 eglu::NativePixmap* pixmap = DE_NULL; 310 EGLSurface surface = EGL_NO_SURFACE; 311 312 try 313 { 314 pixmap = pixmapFactory.createPixmap(&m_eglTestCtx.getNativeDisplay(), m_display, m_config, DE_NULL, width, height); 315 surface = eglu::createPixmapSurface(m_eglTestCtx.getNativeDisplay(), *pixmap, m_display, m_config, DE_NULL); 316 } 317 catch (...) 318 { 319 if (surface != EGL_NO_SURFACE) 320 egl.destroySurface(m_display, surface); 321 322 delete pixmap; 323 throw; 324 } 325 326 m_pixmaps.push_back(pixmap); 327 m_surfaces.push_back(surface); 328 } 329 330 void MakeCurrentPerfCase::destroySurfaces (void) 331 { 332 const Library& egl = m_eglTestCtx.getLibrary(); 333 334 if (m_surfaces.size() > 0) 335 { 336 EGLDisplay display = m_display; 337 338 // Destroy surfaces 339 for (vector<EGLSurface>::iterator iter = m_surfaces.begin(); iter != m_surfaces.end(); ++iter) 340 { 341 if (*iter != EGL_NO_SURFACE) 342 EGLU_CHECK_CALL(egl, destroySurface(display, *iter)); 343 *iter = EGL_NO_SURFACE; 344 } 345 346 m_surfaces.clear(); 347 348 // Destroy pixmaps 349 for (vector<eglu::NativePixmap*>::iterator iter = m_pixmaps.begin(); iter != m_pixmaps.end(); ++iter) 350 { 351 delete *iter; 352 *iter = NULL; 353 } 354 355 m_pixmaps.clear(); 356 357 // Destroy windows 358 for (vector<eglu::NativeWindow*>::iterator iter = m_windows.begin(); iter != m_windows.end(); ++iter) 359 { 360 delete *iter; 361 *iter = NULL; 362 } 363 364 m_windows.clear(); 365 366 // Clear all surface handles 367 m_surfaces.clear(); 368 } 369 } 370 371 void MakeCurrentPerfCase::createContexts (void) 372 { 373 const Library& egl = m_eglTestCtx.getLibrary(); 374 375 for (int contextNdx = 0; contextNdx < m_spec.contextCount; contextNdx++) 376 { 377 const EGLint attribList[] = { 378 EGL_CONTEXT_CLIENT_VERSION, 2, 379 EGL_NONE 380 }; 381 382 EGLU_CHECK_CALL(egl, bindAPI(EGL_OPENGL_ES_API)); 383 EGLContext context = egl.createContext(m_display, m_config, EGL_NO_CONTEXT, attribList); 384 EGLU_CHECK_MSG(egl, "eglCreateContext()"); 385 386 m_contexts.push_back(context); 387 } 388 } 389 390 void MakeCurrentPerfCase::destroyContexts (void) 391 { 392 const Library& egl = m_eglTestCtx.getLibrary(); 393 if (m_contexts.size() > 0) 394 { 395 EGLDisplay display = m_display; 396 397 for (vector<EGLContext>::iterator iter = m_contexts.begin(); iter != m_contexts.end(); ++iter) 398 { 399 if (*iter != EGL_NO_CONTEXT) 400 EGLU_CHECK_CALL(egl, destroyContext(display, *iter)); 401 *iter = EGL_NO_CONTEXT; 402 } 403 404 m_contexts.clear(); 405 } 406 } 407 408 void MakeCurrentPerfCase::logTestInfo (void) 409 { 410 TestLog& log = m_testCtx.getLog(); 411 412 { 413 tcu::ScopedLogSection section(log, "Test Info", "Test case information."); 414 415 log << TestLog::Message << "Context count: " << m_contexts.size() << TestLog::EndMessage; 416 log << TestLog::Message << "Surfaces count: " << m_surfaces.size() << TestLog::EndMessage; 417 log << TestLog::Message << "Sample count: " << m_spec.sampleCount << TestLog::EndMessage; 418 log << TestLog::Message << "Iteration count: " << m_spec.iterationCount << TestLog::EndMessage; 419 log << TestLog::Message << "Window count: " << m_windows.size() << TestLog::EndMessage; 420 log << TestLog::Message << "Pixmap count: " << m_pixmaps.size() << TestLog::EndMessage; 421 log << TestLog::Message << "PBuffer count: " << (m_surfaces.size() - m_windows.size() - m_pixmaps.size()) << TestLog::EndMessage; 422 423 if (m_spec.release) 424 log << TestLog::Message << "Context is released after each use. Both binding and releasing context are included in result time." << TestLog::EndMessage; 425 } 426 } 427 428 void MakeCurrentPerfCase::logResults (void) 429 { 430 TestLog& log = m_testCtx.getLog(); 431 432 log << TestLog::SampleList("Result", "Result") 433 << TestLog::SampleInfo << TestLog::ValueInfo("Time", "Time", "us", QP_SAMPLE_VALUE_TAG_RESPONSE) 434 << TestLog::EndSampleInfo; 435 436 for (int sampleNdx = 0; sampleNdx < (int)m_samples.size(); sampleNdx++) 437 log << TestLog::Sample << deInt64(m_samples[sampleNdx]) << TestLog::EndSample; 438 439 log << TestLog::EndSampleList; 440 441 // Log stats 442 { 443 deUint64 totalTimeUs = 0; 444 deUint64 totalIterationCount = 0; 445 446 float iterationTimeMeanUs = 0.0f; 447 float iterationTimeMedianUs = 0.0f; 448 float iterationTimeVarianceUs = 0.0f; 449 float iterationTimeSkewnessUs = 0.0f; 450 float iterationTimeMinUs = std::numeric_limits<float>::max(); 451 float iterationTimeMaxUs = 0.0f; 452 453 std::sort(m_samples.begin(), m_samples.end()); 454 455 // Calculate totals 456 for (int sampleNdx = 0; sampleNdx < (int)m_samples.size(); sampleNdx++) 457 { 458 totalTimeUs += m_samples[sampleNdx]; 459 totalIterationCount += m_spec.iterationCount; 460 } 461 462 // Calculate mean and median 463 iterationTimeMeanUs = ((float)(((double)totalTimeUs) / (double)totalIterationCount)); 464 iterationTimeMedianUs = ((float)(((double)m_samples[m_samples.size() / 2]) / (double)m_spec.iterationCount)); 465 466 // Calculate variance 467 for (int sampleNdx = 0; sampleNdx < (int)m_samples.size(); sampleNdx++) 468 { 469 float iterationTimeUs = (float)(((double)m_samples[sampleNdx]) / m_spec.iterationCount); 470 iterationTimeVarianceUs += std::pow(iterationTimeUs - iterationTimeMedianUs, 2.0f); 471 } 472 473 // Calculate min and max 474 for (int sampleNdx = 0; sampleNdx < (int)m_samples.size(); sampleNdx++) 475 { 476 float iterationTimeUs = (float)(((double)m_samples[sampleNdx]) / m_spec.iterationCount); 477 iterationTimeMinUs = std::min<float>(iterationTimeMinUs, iterationTimeUs); 478 iterationTimeMaxUs = std::max<float>(iterationTimeMaxUs, iterationTimeUs); 479 } 480 481 iterationTimeVarianceUs /= (float)m_samples.size(); 482 483 // Calculate skewness 484 for (int sampleNdx = 0; sampleNdx < (int)m_samples.size(); sampleNdx++) 485 { 486 float iterationTimeUs = (float)(((double)m_samples[sampleNdx]) / m_spec.iterationCount); 487 iterationTimeSkewnessUs = std::pow((iterationTimeUs - iterationTimeMedianUs) / iterationTimeVarianceUs, 2.0f); 488 } 489 490 iterationTimeSkewnessUs /= (float)m_samples.size(); 491 492 { 493 tcu::ScopedLogSection section(log, "Result", "Statistics from results."); 494 495 log << TestLog::Message << "Total time: " << totalTimeUs << "us" << TestLog::EndMessage; 496 log << TestLog::Message << "Mean: " << iterationTimeMeanUs << "us" << TestLog::EndMessage; 497 log << TestLog::Message << "Median: " << iterationTimeMedianUs << "us" << TestLog::EndMessage; 498 log << TestLog::Message << "Variance: " << iterationTimeVarianceUs << "us" << TestLog::EndMessage; 499 log << TestLog::Message << "Skewness: " << iterationTimeSkewnessUs << "us" << TestLog::EndMessage; 500 log << TestLog::Message << "Min: " << iterationTimeMinUs << "us" << TestLog::EndMessage; 501 log << TestLog::Message << "Max: " << iterationTimeMaxUs << "us" << TestLog::EndMessage; 502 } 503 504 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::floatToString((float)(((double)totalTimeUs)/(double)totalIterationCount), 2).c_str()); 505 } 506 } 507 508 TestCase::IterateResult MakeCurrentPerfCase::iterate (void) 509 { 510 const Library& egl = m_eglTestCtx.getLibrary(); 511 if (m_samples.size() == 0) 512 logTestInfo(); 513 514 { 515 EGLDisplay display = m_display; 516 deUint64 beginTimeUs = deGetMicroseconds(); 517 518 for (int iteration = 0; iteration < m_spec.iterationCount; iteration++) 519 { 520 EGLContext context = m_contexts[m_rnd.getUint32() % m_contexts.size()]; 521 EGLSurface surface = m_surfaces[m_rnd.getUint32() % m_surfaces.size()]; 522 523 egl.makeCurrent(display, surface, surface, context); 524 525 if (m_spec.release) 526 egl.makeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 527 } 528 529 m_samples.push_back(deGetMicroseconds() - beginTimeUs); 530 531 egl.makeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 532 EGLU_CHECK_MSG(egl, "eglMakeCurrent()"); 533 } 534 535 if ((int)m_samples.size() == m_spec.sampleCount) 536 { 537 logResults(); 538 return STOP; 539 } 540 else 541 return CONTINUE; 542 } 543 544 MakeCurrentPerfTests::MakeCurrentPerfTests (EglTestContext& eglTestCtx) 545 : TestCaseGroup(eglTestCtx, "make_current", "eglMakeCurrent performance tests") 546 { 547 } 548 549 void MakeCurrentPerfTests::init (void) 550 { 551 const int iterationCount = 100; 552 const int sampleCount = 100; 553 554 // Add simple test group 555 { 556 TestCaseGroup* simple = new TestCaseGroup(m_eglTestCtx, "simple", "Simple eglMakeCurrent performance tests using single context and surface"); 557 558 const MakeCurrentPerfCase::SurfaceType types[] = { 559 MakeCurrentPerfCase::SURFACETYPE_PBUFFER, 560 MakeCurrentPerfCase::SURFACETYPE_PIXMAP, 561 MakeCurrentPerfCase::SURFACETYPE_WINDOW 562 }; 563 564 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(types); typeNdx++) 565 { 566 for (int releaseNdx = 0; releaseNdx < 2; releaseNdx++) 567 { 568 MakeCurrentPerfCase::Spec spec; 569 570 spec.surfaceTypes = types[typeNdx]; 571 spec.contextCount = 1; 572 spec.surfaceCount = 1; 573 spec.release = (releaseNdx == 1); 574 spec.iterationCount = iterationCount; 575 spec.sampleCount = sampleCount; 576 577 simple->addChild(new MakeCurrentPerfCase(m_eglTestCtx, spec, spec.toName().c_str(), spec.toDescription().c_str())); 578 } 579 } 580 581 addChild(simple); 582 } 583 584 // Add multi context test group 585 { 586 TestCaseGroup* multiContext = new TestCaseGroup(m_eglTestCtx, "multi_context", "eglMakeCurrent performance tests using multiple contexts and single surface"); 587 588 const MakeCurrentPerfCase::SurfaceType types[] = { 589 MakeCurrentPerfCase::SURFACETYPE_PBUFFER, 590 MakeCurrentPerfCase::SURFACETYPE_PIXMAP, 591 MakeCurrentPerfCase::SURFACETYPE_WINDOW 592 }; 593 594 const int contextCounts[] = { 595 10, 100 596 }; 597 598 for (int contextCountNdx = 0; contextCountNdx < DE_LENGTH_OF_ARRAY(contextCounts); contextCountNdx++) 599 { 600 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(types); typeNdx++) 601 { 602 for (int releaseNdx = 0; releaseNdx < 2; releaseNdx++) 603 { 604 MakeCurrentPerfCase::Spec spec; 605 606 spec.surfaceTypes = types[typeNdx]; 607 spec.contextCount = contextCounts[contextCountNdx]; 608 spec.surfaceCount = 1; 609 spec.release = (releaseNdx == 1); 610 spec.iterationCount = iterationCount; 611 spec.sampleCount = sampleCount; 612 613 multiContext->addChild(new MakeCurrentPerfCase(m_eglTestCtx, spec, spec.toName().c_str(), spec.toDescription().c_str())); 614 } 615 } 616 } 617 618 addChild(multiContext); 619 } 620 621 // Add multi surface test group 622 { 623 TestCaseGroup* multiSurface = new TestCaseGroup(m_eglTestCtx, "multi_surface", "eglMakeCurrent performance tests using single context and multiple surfaces"); 624 625 const MakeCurrentPerfCase::SurfaceType types[] = { 626 MakeCurrentPerfCase::SURFACETYPE_PBUFFER, 627 MakeCurrentPerfCase::SURFACETYPE_PIXMAP, 628 MakeCurrentPerfCase::SURFACETYPE_WINDOW, 629 630 (MakeCurrentPerfCase::SurfaceType)(MakeCurrentPerfCase::SURFACETYPE_PBUFFER |MakeCurrentPerfCase::SURFACETYPE_PIXMAP), 631 (MakeCurrentPerfCase::SurfaceType)(MakeCurrentPerfCase::SURFACETYPE_PBUFFER |MakeCurrentPerfCase::SURFACETYPE_WINDOW), 632 (MakeCurrentPerfCase::SurfaceType)(MakeCurrentPerfCase::SURFACETYPE_PIXMAP |MakeCurrentPerfCase::SURFACETYPE_WINDOW), 633 634 (MakeCurrentPerfCase::SurfaceType)(MakeCurrentPerfCase::SURFACETYPE_PBUFFER|MakeCurrentPerfCase::SURFACETYPE_PIXMAP|MakeCurrentPerfCase::SURFACETYPE_WINDOW) 635 }; 636 637 const int surfaceCounts[] = { 638 10, 100 639 }; 640 641 for (int surfaceCountNdx = 0; surfaceCountNdx < DE_LENGTH_OF_ARRAY(surfaceCounts); surfaceCountNdx++) 642 { 643 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(types); typeNdx++) 644 { 645 for (int releaseNdx = 0; releaseNdx < 2; releaseNdx++) 646 { 647 MakeCurrentPerfCase::Spec spec; 648 649 spec.surfaceTypes = types[typeNdx]; 650 spec.surfaceCount = surfaceCounts[surfaceCountNdx]; 651 spec.contextCount = 1; 652 spec.release = (releaseNdx == 1); 653 spec.iterationCount = iterationCount; 654 spec.sampleCount = sampleCount; 655 656 multiSurface->addChild(new MakeCurrentPerfCase(m_eglTestCtx, spec, spec.toName().c_str(), spec.toDescription().c_str())); 657 } 658 } 659 } 660 661 addChild(multiSurface); 662 } 663 664 // Add Complex? test group 665 { 666 TestCaseGroup* multi = new TestCaseGroup(m_eglTestCtx, "complex", "eglMakeCurrent performance tests using multiple contexts and multiple surfaces"); 667 668 const MakeCurrentPerfCase::SurfaceType types[] = { 669 MakeCurrentPerfCase::SURFACETYPE_PBUFFER, 670 MakeCurrentPerfCase::SURFACETYPE_PIXMAP, 671 MakeCurrentPerfCase::SURFACETYPE_WINDOW, 672 673 (MakeCurrentPerfCase::SurfaceType)(MakeCurrentPerfCase::SURFACETYPE_PBUFFER |MakeCurrentPerfCase::SURFACETYPE_PIXMAP), 674 (MakeCurrentPerfCase::SurfaceType)(MakeCurrentPerfCase::SURFACETYPE_PBUFFER |MakeCurrentPerfCase::SURFACETYPE_WINDOW), 675 (MakeCurrentPerfCase::SurfaceType)(MakeCurrentPerfCase::SURFACETYPE_PIXMAP |MakeCurrentPerfCase::SURFACETYPE_WINDOW), 676 677 (MakeCurrentPerfCase::SurfaceType)(MakeCurrentPerfCase::SURFACETYPE_PBUFFER|MakeCurrentPerfCase::SURFACETYPE_PIXMAP|MakeCurrentPerfCase::SURFACETYPE_WINDOW) 678 }; 679 680 const int surfaceCounts[] = { 681 10, 100 682 }; 683 684 685 const int contextCounts[] = { 686 10, 100 687 }; 688 689 for (int surfaceCountNdx = 0; surfaceCountNdx < DE_LENGTH_OF_ARRAY(surfaceCounts); surfaceCountNdx++) 690 { 691 for (int contextCountNdx = 0; contextCountNdx < DE_LENGTH_OF_ARRAY(contextCounts); contextCountNdx++) 692 { 693 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(types); typeNdx++) 694 { 695 for (int releaseNdx = 0; releaseNdx < 2; releaseNdx++) 696 { 697 MakeCurrentPerfCase::Spec spec; 698 699 spec.surfaceTypes = types[typeNdx]; 700 spec.contextCount = contextCounts[contextCountNdx]; 701 spec.surfaceCount = surfaceCounts[surfaceCountNdx]; 702 spec.release = (releaseNdx == 1); 703 spec.iterationCount = iterationCount; 704 spec.sampleCount = sampleCount; 705 706 multi->addChild(new MakeCurrentPerfCase(m_eglTestCtx, spec, spec.toName().c_str(), spec.toDescription().c_str())); 707 } 708 } 709 } 710 } 711 712 addChild(multi); 713 } 714 } 715 716 } // egl 717 } // deqp 718