Add packaging for TIZEN
[platform/upstream/VK-GL-CTS.git] / modules / egl / teglMakeCurrentPerfTests.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 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