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