1 //
2 // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // EGLContextCompatibilityTest.cpp:
8 // This test will try to use all combinations of context configs and
9 // surface configs. If the configs are compatible, it checks that simple
10 // rendering works, otherwise it checks an error is generated one MakeCurrent.
11 //
12
13 #include <gtest/gtest.h>
14
15 #include <vector>
16
17 #include "common/debug.h"
18 #include "test_utils/ANGLETest.h"
19 #include "test_utils/angle_test_configs.h"
20 #include "test_utils/angle_test_instantiate.h"
21 #include "util/OSWindow.h"
22 #include "util/random_utils.h"
23
24 using namespace angle;
25
26 namespace
27 {
28 // The only configs with 16-bits for each of red, green, blue, and alpha is GL_RGBA16F
IsRGBA16FConfig(EGLDisplay display,EGLConfig config)29 bool IsRGBA16FConfig(EGLDisplay display, EGLConfig config)
30 {
31 EGLint red, green, blue, alpha;
32 eglGetConfigAttrib(display, config, EGL_RED_SIZE, &red);
33 eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &green);
34 eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blue);
35 eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &alpha);
36 return ((red == 16) && (green == 16) && (blue == 16) && (alpha == 16));
37 }
38
IsRGB10_A2Config(EGLDisplay display,EGLConfig config)39 bool IsRGB10_A2Config(EGLDisplay display, EGLConfig config)
40 {
41 EGLint red, green, blue, alpha;
42 eglGetConfigAttrib(display, config, EGL_RED_SIZE, &red);
43 eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &green);
44 eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blue);
45 eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &alpha);
46 return ((red == 10) && (green == 10) && (blue == 10) && (alpha == 2));
47 }
48
49 // Queries EGL config to determine if multisampled or not
IsMultisampledConfig(EGLDisplay display,EGLConfig config)50 bool IsMultisampledConfig(EGLDisplay display, EGLConfig config)
51 {
52 EGLint samples = 0;
53 eglGetConfigAttrib(display, config, EGL_SAMPLES, &samples);
54 return (samples > 1);
55 }
56
ShouldSkipConfig(EGLDisplay display,EGLConfig config,bool windowSurfaceTest)57 bool ShouldSkipConfig(EGLDisplay display, EGLConfig config, bool windowSurfaceTest)
58 {
59 // Skip multisampled configurations due to test instability.
60 if (IsMultisampledConfig(display, config))
61 return true;
62
63 // Disable RGBA16F/RGB10_A2 on Android due to OSWindow on Android not providing compatible
64 // windows (http://anglebug.com/3156)
65 if (IsAndroid())
66 {
67 if (IsRGB10_A2Config(display, config))
68 return true;
69
70 if (IsRGBA16FConfig(display, config))
71 return windowSurfaceTest;
72 }
73
74 return false;
75 }
76
GetConfigs(EGLDisplay display)77 std::vector<EGLConfig> GetConfigs(EGLDisplay display)
78 {
79 int nConfigs = 0;
80 if (eglGetConfigs(display, nullptr, 0, &nConfigs) != EGL_TRUE)
81 {
82 std::cerr << "EGLContextCompatiblityTest: eglGetConfigs error\n";
83 return {};
84 }
85 if (nConfigs == 0)
86 {
87 std::cerr << "EGLContextCompatiblityTest: no configs\n";
88 return {};
89 }
90
91 std::vector<EGLConfig> configs;
92
93 int nReturnedConfigs = 0;
94 configs.resize(nConfigs);
95 if (eglGetConfigs(display, configs.data(), nConfigs, &nReturnedConfigs) != EGL_TRUE)
96 {
97 std::cerr << "EGLContextCompatiblityTest: eglGetConfigs error\n";
98 return {};
99 }
100 if (nConfigs != nReturnedConfigs)
101 {
102 std::cerr << "EGLContextCompatiblityTest: eglGetConfigs returned wrong count\n";
103 return {};
104 }
105
106 return configs;
107 }
108
FromRenderer(EGLint renderer)109 PlatformParameters FromRenderer(EGLint renderer)
110 {
111 return WithNoFixture(PlatformParameters(2, 0, EGLPlatformParameters(renderer)));
112 }
113
EGLConfigName(EGLDisplay display,EGLConfig config)114 std::string EGLConfigName(EGLDisplay display, EGLConfig config)
115 {
116 EGLint red;
117 eglGetConfigAttrib(display, config, EGL_RED_SIZE, &red);
118 EGLint green;
119 eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &green);
120 EGLint blue;
121 eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blue);
122 EGLint alpha;
123 eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &alpha);
124 EGLint depth;
125 eglGetConfigAttrib(display, config, EGL_DEPTH_SIZE, &depth);
126 EGLint stencil;
127 eglGetConfigAttrib(display, config, EGL_STENCIL_SIZE, &stencil);
128 EGLint samples;
129 eglGetConfigAttrib(display, config, EGL_SAMPLES, &samples);
130
131 std::stringstream strstr;
132 if (red > 0)
133 {
134 strstr << "R" << red;
135 }
136 if (green > 0)
137 {
138 strstr << "G" << green;
139 }
140 if (blue > 0)
141 {
142 strstr << "B" << blue;
143 }
144 if (alpha > 0)
145 {
146 strstr << "A" << alpha;
147 }
148 if (depth > 0)
149 {
150 strstr << "D" << depth;
151 }
152 if (stencil > 0)
153 {
154 strstr << "S" << stencil;
155 }
156 if (samples > 0)
157 {
158 strstr << "MS" << samples;
159 }
160 return strstr.str();
161 }
162
163 const std::array<EGLint, 3> kContextAttribs = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
164
165 class EGLContextCompatibilityTest : public ANGLETestBase, public testing::Test
166 {
167 public:
EGLContextCompatibilityTest(EGLint renderer)168 EGLContextCompatibilityTest(EGLint renderer)
169 : ANGLETestBase(FromRenderer(renderer)), mRenderer(renderer)
170 {}
171
SetUp()172 void SetUp() final
173 {
174 ANGLETestBase::ANGLETestSetUp();
175 ASSERT_TRUE(eglGetPlatformDisplayEXT != nullptr);
176
177 EGLint dispattrs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, mRenderer, EGL_NONE};
178 mDisplay = eglGetPlatformDisplayEXT(
179 EGL_PLATFORM_ANGLE_ANGLE, reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
180 ASSERT_TRUE(mDisplay != EGL_NO_DISPLAY);
181
182 ASSERT_TRUE(eglInitialize(mDisplay, nullptr, nullptr) == EGL_TRUE);
183
184 int nConfigs = 0;
185 ASSERT_TRUE(eglGetConfigs(mDisplay, nullptr, 0, &nConfigs) == EGL_TRUE);
186 ASSERT_TRUE(nConfigs != 0);
187
188 int nReturnedConfigs = 0;
189 mConfigs.resize(nConfigs);
190 ASSERT_TRUE(eglGetConfigs(mDisplay, mConfigs.data(), nConfigs, &nReturnedConfigs) ==
191 EGL_TRUE);
192 ASSERT_TRUE(nConfigs == nReturnedConfigs);
193 }
194
TearDown()195 void TearDown() final
196 {
197 eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
198 eglTerminate(mDisplay);
199 ANGLETestBase::ANGLETestTearDown();
200 }
201
202 protected:
areConfigsCompatible(EGLConfig c1,EGLConfig c2,EGLint surfaceBit)203 bool areConfigsCompatible(EGLConfig c1, EGLConfig c2, EGLint surfaceBit)
204 {
205 EGLint colorBufferType1, colorBufferType2;
206 EGLint red1, red2, green1, green2, blue1, blue2, alpha1, alpha2;
207 EGLint depth1, depth2, stencil1, stencil2;
208 EGLint surfaceType1, surfaceType2;
209
210 eglGetConfigAttrib(mDisplay, c1, EGL_COLOR_BUFFER_TYPE, &colorBufferType1);
211 eglGetConfigAttrib(mDisplay, c2, EGL_COLOR_BUFFER_TYPE, &colorBufferType2);
212
213 eglGetConfigAttrib(mDisplay, c1, EGL_RED_SIZE, &red1);
214 eglGetConfigAttrib(mDisplay, c2, EGL_RED_SIZE, &red2);
215 eglGetConfigAttrib(mDisplay, c1, EGL_GREEN_SIZE, &green1);
216 eglGetConfigAttrib(mDisplay, c2, EGL_GREEN_SIZE, &green2);
217 eglGetConfigAttrib(mDisplay, c1, EGL_BLUE_SIZE, &blue1);
218 eglGetConfigAttrib(mDisplay, c2, EGL_BLUE_SIZE, &blue2);
219 eglGetConfigAttrib(mDisplay, c1, EGL_ALPHA_SIZE, &alpha1);
220 eglGetConfigAttrib(mDisplay, c2, EGL_ALPHA_SIZE, &alpha2);
221
222 eglGetConfigAttrib(mDisplay, c1, EGL_DEPTH_SIZE, &depth1);
223 eglGetConfigAttrib(mDisplay, c2, EGL_DEPTH_SIZE, &depth2);
224 eglGetConfigAttrib(mDisplay, c1, EGL_STENCIL_SIZE, &stencil1);
225 eglGetConfigAttrib(mDisplay, c2, EGL_STENCIL_SIZE, &stencil2);
226
227 eglGetConfigAttrib(mDisplay, c1, EGL_SURFACE_TYPE, &surfaceType1);
228 eglGetConfigAttrib(mDisplay, c2, EGL_SURFACE_TYPE, &surfaceType2);
229
230 EGLint colorComponentType1 = EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
231 EGLint colorComponentType2 = EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
232 if (IsEGLDisplayExtensionEnabled(mDisplay, "EGL_EXT_pixel_format_float"))
233 {
234 eglGetConfigAttrib(mDisplay, c1, EGL_COLOR_COMPONENT_TYPE_EXT, &colorComponentType1);
235 eglGetConfigAttrib(mDisplay, c2, EGL_COLOR_COMPONENT_TYPE_EXT, &colorComponentType2);
236 }
237
238 EXPECT_EGL_SUCCESS();
239
240 return colorBufferType1 == colorBufferType2 && red1 == red2 && green1 == green2 &&
241 blue1 == blue2 && alpha1 == alpha2 && colorComponentType1 == colorComponentType2 &&
242 depth1 == depth2 && stencil1 == stencil2 && (surfaceType1 & surfaceBit) != 0 &&
243 (surfaceType2 & surfaceBit) != 0;
244 }
245
testWindowCompatibility(EGLConfig windowConfig,EGLConfig contextConfig,bool compatible) const246 void testWindowCompatibility(EGLConfig windowConfig,
247 EGLConfig contextConfig,
248 bool compatible) const
249 {
250 OSWindow *osWindow = OSWindow::New();
251 ASSERT_TRUE(osWindow != nullptr);
252 osWindow->initialize("EGLContextCompatibilityTest", 500, 500);
253
254 EGLContext context =
255 eglCreateContext(mDisplay, contextConfig, EGL_NO_CONTEXT, kContextAttribs.data());
256 ASSERT_TRUE(context != EGL_NO_CONTEXT);
257
258 EGLSurface window =
259 eglCreateWindowSurface(mDisplay, windowConfig, osWindow->getNativeWindow(), nullptr);
260 ASSERT_EGL_SUCCESS();
261
262 if (compatible)
263 {
264 testClearSurface(window, windowConfig, context);
265 }
266 else
267 {
268 testMakeCurrentFails(window, context);
269 }
270
271 eglDestroySurface(mDisplay, window);
272 ASSERT_EGL_SUCCESS();
273
274 eglDestroyContext(mDisplay, context);
275 ASSERT_EGL_SUCCESS();
276
277 OSWindow::Delete(&osWindow);
278 }
279
testPbufferCompatibility(EGLConfig pbufferConfig,EGLConfig contextConfig,bool compatible) const280 void testPbufferCompatibility(EGLConfig pbufferConfig,
281 EGLConfig contextConfig,
282 bool compatible) const
283 {
284 EGLContext context =
285 eglCreateContext(mDisplay, contextConfig, EGL_NO_CONTEXT, kContextAttribs.data());
286 ASSERT_TRUE(context != EGL_NO_CONTEXT);
287
288 const EGLint pBufferAttribs[] = {
289 EGL_WIDTH, 500, EGL_HEIGHT, 500, EGL_NONE,
290 };
291 EGLSurface pbuffer = eglCreatePbufferSurface(mDisplay, pbufferConfig, pBufferAttribs);
292 ASSERT_TRUE(pbuffer != EGL_NO_SURFACE);
293
294 if (compatible)
295 {
296 testClearSurface(pbuffer, pbufferConfig, context);
297 }
298 else
299 {
300 testMakeCurrentFails(pbuffer, context);
301 }
302
303 eglDestroySurface(mDisplay, pbuffer);
304 ASSERT_EGL_SUCCESS();
305
306 eglDestroyContext(mDisplay, context);
307 ASSERT_EGL_SUCCESS();
308 }
309
310 std::vector<EGLConfig> mConfigs;
311 EGLDisplay mDisplay = EGL_NO_DISPLAY;
312 EGLint mRenderer = 0;
313
314 private:
testClearSurface(EGLSurface surface,EGLConfig surfaceConfig,EGLContext context) const315 void testClearSurface(EGLSurface surface, EGLConfig surfaceConfig, EGLContext context) const
316 {
317 eglMakeCurrent(mDisplay, surface, surface, context);
318 ASSERT_EGL_SUCCESS();
319
320 glViewport(0, 0, 500, 500);
321 glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
322 glClear(GL_COLOR_BUFFER_BIT);
323 ASSERT_GL_NO_ERROR();
324
325 EGLint surfaceCompontentType = EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
326 if (IsEGLDisplayExtensionEnabled(mDisplay, "EGL_EXT_pixel_format_float"))
327 {
328 eglGetConfigAttrib(mDisplay, surfaceConfig, EGL_COLOR_COMPONENT_TYPE_EXT,
329 &surfaceCompontentType);
330 }
331
332 if (surfaceCompontentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT)
333 {
334 EXPECT_PIXEL_EQ(250, 250, 0, 0, 255, 255);
335 }
336 else
337 {
338 EXPECT_PIXEL_32F_EQ(250, 250, 0, 0, 1.0f, 1.0f);
339 }
340
341 eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
342 ASSERT_EGL_SUCCESS();
343 }
344
testMakeCurrentFails(EGLSurface surface,EGLContext context) const345 void testMakeCurrentFails(EGLSurface surface, EGLContext context) const
346 {
347 eglMakeCurrent(mDisplay, surface, surface, context);
348 EXPECT_EGL_ERROR(EGL_BAD_MATCH);
349 }
350 };
351
352 // The test is split in several subtest so that simple cases
353 // are tested separately. Also each surface types are not tested
354 // together.
355
356 // Basic test checking contexts and windows created with the
357 // same config can render.
358 class EGLContextCompatibilityTest_WindowSameConfig : public EGLContextCompatibilityTest
359 {
360 public:
EGLContextCompatibilityTest_WindowSameConfig(EGLint renderer,size_t configIndex)361 EGLContextCompatibilityTest_WindowSameConfig(EGLint renderer, size_t configIndex)
362 : EGLContextCompatibilityTest(renderer), mConfigIndex(configIndex)
363 {}
364
TestBody()365 void TestBody() override
366 {
367 EGLConfig config = mConfigs[mConfigIndex];
368
369 EGLint surfaceType;
370 eglGetConfigAttrib(mDisplay, config, EGL_SURFACE_TYPE, &surfaceType);
371 ASSERT_EGL_SUCCESS();
372
373 ANGLE_SKIP_TEST_IF((surfaceType & EGL_WINDOW_BIT) == 0);
374
375 testWindowCompatibility(config, config, true);
376 }
377
378 EGLint mConfigIndex;
379 };
380
381 // Basic test checking contexts and pbuffers created with the
382 // same config can render.
383 class EGLContextCompatibilityTest_PbufferSameConfig : public EGLContextCompatibilityTest
384 {
385 public:
EGLContextCompatibilityTest_PbufferSameConfig(EGLint renderer,size_t configIndex)386 EGLContextCompatibilityTest_PbufferSameConfig(EGLint renderer, size_t configIndex)
387 : EGLContextCompatibilityTest(renderer), mConfigIndex(configIndex)
388 {}
389
TestBody()390 void TestBody() override
391 {
392 EGLConfig config = mConfigs[mConfigIndex];
393
394 EGLint surfaceType;
395 eglGetConfigAttrib(mDisplay, config, EGL_SURFACE_TYPE, &surfaceType);
396 ASSERT_EGL_SUCCESS();
397
398 ANGLE_SKIP_TEST_IF((surfaceType & EGL_PBUFFER_BIT) == 0);
399
400 testPbufferCompatibility(config, config, true);
401 }
402
403 EGLint mConfigIndex;
404 };
405
406 // Check that a context rendering to a window with a different
407 // config works or errors according to the EGL compatibility rules
408 class EGLContextCompatibilityTest_WindowDifferentConfig : public EGLContextCompatibilityTest
409 {
410 public:
EGLContextCompatibilityTest_WindowDifferentConfig(EGLint renderer,size_t configIndexA,size_t configIndexB)411 EGLContextCompatibilityTest_WindowDifferentConfig(EGLint renderer,
412 size_t configIndexA,
413 size_t configIndexB)
414 : EGLContextCompatibilityTest(renderer),
415 mConfigIndexA(configIndexA),
416 mConfigIndexB(configIndexB)
417 {}
418
TestBody()419 void TestBody() override
420 {
421 EGLConfig config1 = mConfigs[mConfigIndexA];
422 EGLConfig config2 = mConfigs[mConfigIndexB];
423
424 EGLint surfaceType;
425 eglGetConfigAttrib(mDisplay, config1, EGL_SURFACE_TYPE, &surfaceType);
426 ASSERT_EGL_SUCCESS();
427
428 ANGLE_SKIP_TEST_IF((surfaceType & EGL_WINDOW_BIT) == 0);
429
430 testWindowCompatibility(config1, config2,
431 areConfigsCompatible(config1, config2, EGL_WINDOW_BIT));
432 }
433
434 EGLint mConfigIndexA;
435 EGLint mConfigIndexB;
436 };
437
438 // Check that a context rendering to a pbuffer with a different
439 // config works or errors according to the EGL compatibility rules
440 class EGLContextCompatibilityTest_PbufferDifferentConfig : public EGLContextCompatibilityTest
441 {
442 public:
EGLContextCompatibilityTest_PbufferDifferentConfig(EGLint renderer,size_t configIndexA,size_t configIndexB)443 EGLContextCompatibilityTest_PbufferDifferentConfig(EGLint renderer,
444 size_t configIndexA,
445 size_t configIndexB)
446 : EGLContextCompatibilityTest(renderer),
447 mConfigIndexA(configIndexA),
448 mConfigIndexB(configIndexB)
449 {}
450
TestBody()451 void TestBody() override
452 {
453 EGLConfig config1 = mConfigs[mConfigIndexA];
454 EGLConfig config2 = mConfigs[mConfigIndexB];
455
456 EGLint surfaceType;
457 eglGetConfigAttrib(mDisplay, config1, EGL_SURFACE_TYPE, &surfaceType);
458 ASSERT_EGL_SUCCESS();
459
460 ANGLE_SKIP_TEST_IF((surfaceType & EGL_PBUFFER_BIT) == 0);
461
462 testPbufferCompatibility(config1, config2,
463 areConfigsCompatible(config1, config2, EGL_PBUFFER_BIT));
464 }
465
466 EGLint mConfigIndexA;
467 EGLint mConfigIndexB;
468 };
469 } // namespace
470
RegisterContextCompatibilityTests()471 void RegisterContextCompatibilityTests()
472 {
473 std::vector<EGLint> renderers = {{
474 EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE,
475 EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
476 EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE,
477 EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE,
478 EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE,
479 }};
480
481 LoadEntryPointsWithUtilLoader(angle::GLESDriverType::AngleEGL);
482
483 if (eglGetPlatformDisplayEXT == nullptr)
484 {
485 std::cerr << "EGLContextCompatiblityTest: missing eglGetPlatformDisplayEXT\n";
486 return;
487 }
488
489 for (EGLint renderer : renderers)
490 {
491 PlatformParameters params = FromRenderer(renderer);
492 if (IsPlatformAvailable(params))
493 continue;
494
495 EGLint dispattrs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, renderer, EGL_NONE};
496 EGLDisplay display = eglGetPlatformDisplayEXT(
497 EGL_PLATFORM_ANGLE_ANGLE, reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
498 if (display == EGL_NO_DISPLAY)
499 {
500 std::cerr << "EGLContextCompatiblityTest: eglGetPlatformDisplayEXT error\n";
501 return;
502 }
503
504 if (eglInitialize(display, nullptr, nullptr) != EGL_TRUE)
505 {
506 std::cerr << "EGLContextCompatiblityTest: eglInitialize error\n";
507 return;
508 }
509
510 std::vector<EGLConfig> configs = GetConfigs(display);
511 std::vector<std::string> configNames;
512 std::string rendererName = GetRendererName(renderer);
513
514 for (EGLConfig config : configs)
515 {
516 configNames.push_back(EGLConfigName(display, config));
517 }
518
519 for (size_t configIndex = 0; configIndex < configs.size(); ++configIndex)
520 {
521 if (ShouldSkipConfig(display, configs[configIndex], true))
522 continue;
523
524 std::stringstream nameStr;
525 nameStr << "WindowSameConfig/" << rendererName << "_" << configNames[configIndex];
526 std::string name = nameStr.str();
527
528 testing::RegisterTest(
529 "EGLContextCompatibilityTest", name.c_str(), nullptr, nullptr, __FILE__, __LINE__,
530 [renderer, configIndex]() -> EGLContextCompatibilityTest * {
531 return new EGLContextCompatibilityTest_WindowSameConfig(renderer, configIndex);
532 });
533 }
534
535 for (size_t configIndex = 0; configIndex < configs.size(); ++configIndex)
536 {
537 if (ShouldSkipConfig(display, configs[configIndex], false))
538 continue;
539
540 std::stringstream nameStr;
541 nameStr << "PbufferSameConfig/" << rendererName << "_" << configNames[configIndex];
542 std::string name = nameStr.str();
543
544 testing::RegisterTest(
545 "EGLContextCompatibilityTest", name.c_str(), nullptr, nullptr, __FILE__, __LINE__,
546 [renderer, configIndex]() -> EGLContextCompatibilityTest * {
547 return new EGLContextCompatibilityTest_PbufferSameConfig(renderer, configIndex);
548 });
549 }
550
551 // Because there are so many permutations, we skip some configs randomly.
552 // Attempt to run at most 100 tests per renderer.
553 RNG rng(0);
554 constexpr uint32_t kMaximumTestsPerRenderer = 100;
555 const uint32_t kTestCount = static_cast<uint32_t>(configs.size() * configs.size());
556 const float kSkipP =
557 1.0f - (static_cast<float>(std::min(kMaximumTestsPerRenderer, kTestCount)) /
558 static_cast<float>(kTestCount));
559
560 for (size_t configIndexA = 0; configIndexA < configs.size(); ++configIndexA)
561 {
562 if (ShouldSkipConfig(display, configs[configIndexA], true))
563 continue;
564
565 std::string configNameA = configNames[configIndexA];
566
567 for (size_t configIndexB = 0; configIndexB < configs.size(); ++configIndexB)
568 {
569 if (ShouldSkipConfig(display, configs[configIndexB], true))
570 continue;
571
572 if (rng.randomFloat() < kSkipP)
573 continue;
574
575 std::string configNameB = configNames[configIndexB];
576
577 std::stringstream nameStr;
578 nameStr << "WindowDifferentConfig/" << rendererName << "_" << configNameA << "_"
579 << configNameB;
580 std::string name = nameStr.str();
581
582 testing::RegisterTest(
583 "EGLContextCompatibilityTest", name.c_str(), nullptr, nullptr, __FILE__,
584 __LINE__,
585 [renderer, configIndexA, configIndexB]() -> EGLContextCompatibilityTest * {
586 return new EGLContextCompatibilityTest_WindowDifferentConfig(
587 renderer, configIndexA, configIndexB);
588 });
589 }
590 }
591
592 for (size_t configIndexA = 0; configIndexA < configs.size(); ++configIndexA)
593 {
594 if (ShouldSkipConfig(display, configs[configIndexA], false))
595 continue;
596
597 std::string configNameA = configNames[configIndexA];
598
599 for (size_t configIndexB = 0; configIndexB < configs.size(); ++configIndexB)
600 {
601 if (ShouldSkipConfig(display, configs[configIndexB], false))
602 continue;
603
604 if (rng.randomFloat() < kSkipP)
605 continue;
606
607 std::string configNameB = configNames[configIndexB];
608
609 std::stringstream nameStr;
610 nameStr << "PbufferDifferentConfig/" << rendererName << "_" << configNameA << "_"
611 << configNameB;
612 std::string name = nameStr.str();
613
614 testing::RegisterTest(
615 "EGLContextCompatibilityTest", name.c_str(), nullptr, nullptr, __FILE__,
616 __LINE__,
617 [renderer, configIndexA, configIndexB]() -> EGLContextCompatibilityTest * {
618 return new EGLContextCompatibilityTest_PbufferDifferentConfig(
619 renderer, configIndexA, configIndexB);
620 });
621 }
622 }
623
624 if (eglTerminate(display) == EGL_FALSE)
625 {
626 std::cerr << "EGLContextCompatiblityTest: eglTerminate error\n";
627 return;
628 }
629 }
630 }
631