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