• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2014 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 // angle_test_instantiate.cpp: Adds support for filtering parameterized
8 // tests by platform, so we skip unsupported configs.
9 
10 #include "test_utils/angle_test_instantiate.h"
11 
12 #include <algorithm>
13 #include <array>
14 #include <iostream>
15 #include <map>
16 
17 #include "angle_gl.h"
18 #include "common/debug.h"
19 #include "common/platform.h"
20 #include "common/system_utils.h"
21 #include "common/third_party/base/anglebase/no_destructor.h"
22 #include "gpu_info_util/SystemInfo.h"
23 #include "test_utils/angle_test_configs.h"
24 #include "util/EGLWindow.h"
25 #include "util/OSWindow.h"
26 #include "util/test_utils.h"
27 
28 #if defined(ANGLE_PLATFORM_WINDOWS)
29 #    include <VersionHelpers.h>
30 #    include "util/windows/WGLWindow.h"
31 #endif  // defined(ANGLE_PLATFORM_WINDOWS)
32 
33 #if defined(ANGLE_PLATFORM_APPLE)
34 #    include "test_utils/angle_test_instantiate_apple.h"
35 #endif
36 
37 namespace angle
38 {
39 namespace
40 {
IsAngleEGLConfigSupported(const PlatformParameters & param,OSWindow * osWindow)41 bool IsAngleEGLConfigSupported(const PlatformParameters &param, OSWindow *osWindow)
42 {
43     std::unique_ptr<angle::Library> eglLibrary;
44 
45 #if defined(ANGLE_USE_UTIL_LOADER)
46     eglLibrary.reset(
47         angle::OpenSharedLibrary(ANGLE_EGL_LIBRARY_NAME, angle::SearchType::ModuleDir));
48 #endif
49 
50     EGLWindow *eglWindow = EGLWindow::New(param.majorVersion, param.minorVersion);
51     ConfigParameters configParams;
52     bool result =
53         eglWindow->initializeGL(osWindow, eglLibrary.get(), angle::GLESDriverType::AngleEGL,
54                                 param.eglParameters, configParams);
55     eglWindow->destroyGL();
56     EGLWindow::Delete(&eglWindow);
57     return result;
58 }
59 
IsSystemWGLConfigSupported(const PlatformParameters & param,OSWindow * osWindow)60 bool IsSystemWGLConfigSupported(const PlatformParameters &param, OSWindow *osWindow)
61 {
62 #if defined(ANGLE_PLATFORM_WINDOWS) && defined(ANGLE_USE_UTIL_LOADER)
63     std::unique_ptr<angle::Library> openglLibrary(
64         angle::OpenSharedLibrary("opengl32", angle::SearchType::SystemDir));
65 
66     WGLWindow *wglWindow = WGLWindow::New(param.majorVersion, param.minorVersion);
67     ConfigParameters configParams;
68     bool result =
69         wglWindow->initializeGL(osWindow, openglLibrary.get(), angle::GLESDriverType::SystemWGL,
70                                 param.eglParameters, configParams);
71     wglWindow->destroyGL();
72     WGLWindow::Delete(&wglWindow);
73     return result;
74 #else
75     return false;
76 #endif  // defined(ANGLE_PLATFORM_WINDOWS) && defined(ANGLE_USE_UTIL_LOADER)
77 }
78 
IsSystemEGLConfigSupported(const PlatformParameters & param,OSWindow * osWindow)79 bool IsSystemEGLConfigSupported(const PlatformParameters &param, OSWindow *osWindow)
80 {
81 #if defined(ANGLE_USE_UTIL_LOADER)
82     std::unique_ptr<angle::Library> eglLibrary;
83 
84     eglLibrary.reset(OpenSharedLibraryWithExtension(GetNativeEGLLibraryNameWithExtension(),
85                                                     SearchType::SystemDir));
86 
87     EGLWindow *eglWindow = EGLWindow::New(param.majorVersion, param.minorVersion);
88     ConfigParameters configParams;
89     bool result =
90         eglWindow->initializeGL(osWindow, eglLibrary.get(), angle::GLESDriverType::SystemEGL,
91                                 param.eglParameters, configParams);
92     eglWindow->destroyGL();
93     EGLWindow::Delete(&eglWindow);
94     return result;
95 #else
96     return false;
97 #endif
98 }
99 
IsAndroidDevice(const std::string & deviceName)100 bool IsAndroidDevice(const std::string &deviceName)
101 {
102     if (!IsAndroid())
103     {
104         return false;
105     }
106     SystemInfo *systemInfo = GetTestSystemInfo();
107     if (systemInfo->machineModelName == deviceName)
108     {
109         return true;
110     }
111     return false;
112 }
113 
IsAndroid9OrNewer()114 bool IsAndroid9OrNewer()
115 {
116     if (!IsAndroid())
117     {
118         return false;
119     }
120     SystemInfo *systemInfo = GetTestSystemInfo();
121     if (systemInfo->androidSdkLevel >= 28)
122     {
123         return true;
124     }
125     return false;
126 }
127 
GetActiveGPUDeviceInfo()128 GPUDeviceInfo *GetActiveGPUDeviceInfo()
129 {
130     SystemInfo *systemInfo = GetTestSystemInfo();
131     // Unfortunately sometimes GPU info collection can fail.
132     if (systemInfo->gpus.empty())
133     {
134         return nullptr;
135     }
136     return &systemInfo->gpus[systemInfo->activeGPUIndex];
137 }
138 
HasSystemVendorID(VendorID vendorID)139 bool HasSystemVendorID(VendorID vendorID)
140 {
141     GPUDeviceInfo *gpuInfo = GetActiveGPUDeviceInfo();
142 
143     return gpuInfo && gpuInfo->vendorId == vendorID;
144 }
145 
HasSystemDeviceID(VendorID vendorID,DeviceID deviceID)146 bool HasSystemDeviceID(VendorID vendorID, DeviceID deviceID)
147 {
148     GPUDeviceInfo *gpuInfo = GetActiveGPUDeviceInfo();
149 
150     return gpuInfo && gpuInfo->vendorId == vendorID && gpuInfo->deviceId == deviceID;
151 }
152 
153 using ParamAvailabilityCache = std::map<PlatformParameters, bool>;
154 
GetAvailabilityCache()155 ParamAvailabilityCache &GetAvailabilityCache()
156 {
157     static angle::base::NoDestructor<std::unique_ptr<ParamAvailabilityCache>>
158         sParamAvailabilityCache(new ParamAvailabilityCache());
159     return **sParamAvailabilityCache;
160 }
161 
162 constexpr size_t kMaxConfigNameLen = 100;
163 std::array<char, kMaxConfigNameLen> gSelectedConfig;
164 }  // namespace
165 
166 bool gEnableANGLEPerTestCaptureLabel = false;
167 
IsConfigSelected()168 bool IsConfigSelected()
169 {
170     return gSelectedConfig[0] != 0;
171 }
172 
173 #if !defined(ANGLE_PLATFORM_APPLE)
174 // For Apple platform, see angle_test_instantiate_apple.mm
IsMetalTextureSwizzleAvailable()175 bool IsMetalTextureSwizzleAvailable()
176 {
177     return false;
178 }
179 
IsMetalCompressedTexture3DAvailable()180 bool IsMetalCompressedTexture3DAvailable()
181 {
182     return false;
183 }
184 #endif
185 
GetTestSystemInfo()186 SystemInfo *GetTestSystemInfo()
187 {
188     static SystemInfo *sSystemInfo = nullptr;
189     if (sSystemInfo == nullptr)
190     {
191         sSystemInfo = new SystemInfo;
192         if (!GetSystemInfo(sSystemInfo))
193         {
194             std::cerr << "Warning: incomplete system info collection.\n";
195         }
196 
197         // On dual-GPU Macs we want the active GPU to always appear to be the
198         // high-performance GPU for tests.
199         // We can call the generic GPU info collector which selects the
200         // non-Intel GPU as the active one on dual-GPU machines.
201         if (IsOSX())
202         {
203             GetDualGPUInfo(sSystemInfo);
204         }
205 
206         // Print complete system info when available.
207         // Seems to trip up Android test expectation parsing.
208         // Also don't print info when a config is selected to prevent test spam.
209         if (!IsAndroid() && !IsConfigSelected())
210         {
211             PrintSystemInfo(*sSystemInfo);
212         }
213     }
214     return sSystemInfo;
215 }
216 
IsAndroid()217 bool IsAndroid()
218 {
219 #if defined(ANGLE_PLATFORM_ANDROID)
220     return true;
221 #else
222     return false;
223 #endif
224 }
225 
IsLinux()226 bool IsLinux()
227 {
228 #if defined(ANGLE_PLATFORM_LINUX)
229     return true;
230 #else
231     return false;
232 #endif
233 }
234 
IsOSX()235 bool IsOSX()
236 {
237 #if defined(ANGLE_PLATFORM_MACOS)
238     return true;
239 #else
240     return false;
241 #endif
242 }
243 
IsIOS()244 bool IsIOS()
245 {
246 #if defined(ANGLE_PLATFORM_IOS)
247     return true;
248 #else
249     return false;
250 #endif
251 }
252 
IsARM64()253 bool IsARM64()
254 {
255 // _M_ARM64 is Windows-specific, while __aarch64__ is for other platforms.
256 #if defined(_M_ARM64) || defined(__aarch64__)
257     return true;
258 #else
259     return false;
260 #endif
261 }
262 
IsOzone()263 bool IsOzone()
264 {
265 #if defined(USE_OZONE) && (defined(USE_X11) || defined(ANGLE_USE_VULKAN_DISPLAY))
266     // We do not have a proper support for Ozone/Linux yet. Still, we need to figure out how to
267     // properly initialize tests and differentiate between X11 and Wayland. Probably, passing a
268     // command line argument could be sufficient. At the moment, run tests only for X11 backend
269     // as we don't have Wayland support in Angle. Yes, this is a bit weird to return false, but
270     // it makes it possible to continue angle tests with X11 regardless of the Chromium config
271     // for linux, which is use_x11 && use_ozone.  Also, IsOzone is a bit vague now. It was only
272     // expected that angle could run with ozone/drm backend for ChromeOS. And returning true
273     // for desktop Linux when USE_OZONE && USE_X11 are both defined results in incorrect tests'
274     // expectations. We should also rework them and make IsOzone less vague.
275     //
276     // TODO(crbug.com/angleproject/4977): make it possible to switch between X11 and Wayland on
277     // Ozone/Linux builds. Probably, it's possible to identify the WAYLAND backend by checking
278     // the WAYLAND_DISPLAY or XDG_SESSION_TYPE env vars. And also make the IsOzone method less
279     // vague (read the comment above).
280     return false;
281 #elif defined(USE_OZONE)
282     return true;
283 #else
284     return false;
285 #endif
286 }
287 
IsWindows()288 bool IsWindows()
289 {
290 #if defined(ANGLE_PLATFORM_WINDOWS)
291     return true;
292 #else
293     return false;
294 #endif
295 }
296 
IsWindows7()297 bool IsWindows7()
298 {
299 #if defined(ANGLE_PLATFORM_WINDOWS)
300     return ::IsWindows7OrGreater() && !::IsWindows8OrGreater();
301 #else
302     return false;
303 #endif
304 }
305 
IsFuchsia()306 bool IsFuchsia()
307 {
308 #if defined(ANGLE_PLATFORM_FUCHSIA)
309     return true;
310 #else
311     return false;
312 #endif
313 }
314 
IsNexus5X()315 bool IsNexus5X()
316 {
317     return IsAndroidDevice("Nexus 5X");
318 }
319 
IsNexus9()320 bool IsNexus9()
321 {
322     return IsAndroidDevice("Nexus 9");
323 }
324 
IsPixelXL()325 bool IsPixelXL()
326 {
327     return IsAndroidDevice("Pixel XL");
328 }
329 
IsPixel2()330 bool IsPixel2()
331 {
332     return IsAndroidDevice("Pixel 2");
333 }
334 
IsPixel2XL()335 bool IsPixel2XL()
336 {
337     return IsAndroidDevice("Pixel 2 XL");
338 }
339 
IsPixel4()340 bool IsPixel4()
341 {
342     return IsAndroidDevice("Pixel 4");
343 }
344 
IsPixel4XL()345 bool IsPixel4XL()
346 {
347     return IsAndroidDevice("Pixel 4 XL");
348 }
349 
IsNVIDIAShield()350 bool IsNVIDIAShield()
351 {
352     return IsAndroidDevice("SHIELD Android TV");
353 }
354 
IsIntel()355 bool IsIntel()
356 {
357     return HasSystemVendorID(kVendorID_Intel);
358 }
359 
IsIntelUHD630Mobile()360 bool IsIntelUHD630Mobile()
361 {
362     return HasSystemDeviceID(kVendorID_Intel, kDeviceID_UHD630Mobile);
363 }
364 
IsIntelHD630Mobile()365 bool IsIntelHD630Mobile()
366 {
367     return HasSystemDeviceID(kVendorID_Intel, kDeviceID_HD630Mobile);
368 }
369 
IsAMD()370 bool IsAMD()
371 {
372     return HasSystemVendorID(kVendorID_AMD);
373 }
374 
IsApple()375 bool IsApple()
376 {
377     return HasSystemVendorID(kVendorID_Apple);
378 }
379 
IsARM()380 bool IsARM()
381 {
382     return HasSystemVendorID(kVendorID_ARM);
383 }
384 
IsSwiftshaderDevice()385 bool IsSwiftshaderDevice()
386 {
387     return HasSystemDeviceID(kVendorID_GOOGLE, kDeviceID_Swiftshader);
388 }
389 
IsNVIDIA()390 bool IsNVIDIA()
391 {
392 #if defined(ANGLE_PLATFORM_ANDROID)
393     // NVIDIA Shield cannot detect vendor ID (http://anglebug.com/3541)
394     if (IsNVIDIAShield())
395     {
396         return true;
397     }
398 #endif
399     return HasSystemVendorID(kVendorID_NVIDIA);
400 }
401 
IsQualcomm()402 bool IsQualcomm()
403 {
404     return IsNexus5X() || IsNexus9() || IsPixelXL() || IsPixel2() || IsPixel2XL() || IsPixel4() ||
405            IsPixel4XL();
406 }
407 
Is64Bit()408 bool Is64Bit()
409 {
410 #if defined(ANGLE_IS_64_BIT_CPU)
411     return true;
412 #else
413     return false;
414 #endif  // defined(ANGLE_IS_64_BIT_CPU)
415 }
416 
IsConfigAllowlisted(const SystemInfo & systemInfo,const PlatformParameters & param)417 bool IsConfigAllowlisted(const SystemInfo &systemInfo, const PlatformParameters &param)
418 {
419     VendorID vendorID =
420         systemInfo.gpus.empty() ? 0 : systemInfo.gpus[systemInfo.activeGPUIndex].vendorId;
421 
422     // We support the default and null back-ends on every platform.
423     if (param.driver == GLESDriverType::AngleEGL)
424     {
425         if (param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE)
426             return true;
427         if (param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE)
428             return true;
429     }
430 
431     // TODO: http://crbug.com/swiftshader/145
432     // Swiftshader does not currently have all the robustness features
433     // we need for ANGLE. In particular, it is unable to detect and recover
434     // from infinitely looping shaders. That bug is the tracker for fixing
435     // that and when resolved we can remove the following code.
436     // This test will disable tests marked with the config WithRobustness
437     // when run with the swiftshader Vulkan driver and on Android.
438     if ((param.isSwiftshader() || IsSwiftshaderDevice()) &&
439         param.eglParameters.robustness == EGL_TRUE)
440     {
441         return false;
442     }
443 
444     if (IsWindows())
445     {
446         switch (param.driver)
447         {
448             case GLESDriverType::AngleEGL:
449                 switch (param.getRenderer())
450                 {
451                     case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE:
452                     case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
453                         return true;
454                     case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
455                         // Note we disable AMD OpenGL testing on Windows due to using a very old and
456                         // outdated card with many driver bugs. See http://anglebug.com/5123
457                         return !IsAMD();
458                     case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:
459                         if (IsARM64())
460                         {
461                             return param.getDeviceType() ==
462                                    EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE;
463                         }
464                         return true;
465                     case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
466                         // ES 3.1+ back-end is not supported properly.
467                         if (param.eglParameters.majorVersion == 3 &&
468                             param.eglParameters.minorVersion > 0)
469                         {
470                             return false;
471                         }
472 
473                         // Win ES emulation is currently only supported on NVIDIA.
474                         return IsNVIDIA(vendorID);
475                     default:
476                         return false;
477                 }
478             case GLESDriverType::SystemWGL:
479                 // AMD does not support the ES compatibility extensions.
480                 return !IsAMD(vendorID);
481             default:
482                 return false;
483         }
484     }
485 
486 #if defined(ANGLE_PLATFORM_APPLE)
487     if (IsOSX() || IsIOS())
488     {
489         // We do not support non-ANGLE bindings on OSX.
490         if (param.driver != GLESDriverType::AngleEGL)
491         {
492             return false;
493         }
494 
495         switch (param.getRenderer())
496         {
497             case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
498                 // ES 3.1+ back-end is not supported properly.
499                 if (param.majorVersion == 3 && param.minorVersion > 0)
500                 {
501                     return false;
502                 }
503                 return true;
504             case EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE:
505                 if (!IsMetalRendererAvailable())
506                 {
507                     return false;
508                 }
509                 return true;
510             case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:
511                 // OSX does not support native vulkan
512                 return param.getDeviceType() == EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE;
513             default:
514                 return false;
515         }
516     }
517 #endif  // #if defined(ANGLE_PLATFORM_APPLE)
518 
519     if (IsFuchsia())
520     {
521         // We do not support non-ANGLE bindings on Fuchsia.
522         if (param.driver != GLESDriverType::AngleEGL)
523         {
524             return false;
525         }
526 
527         // ES 3 configs do not work properly on Fuchsia ARM.
528         // TODO(anglebug.com/4352): Investigate missing features.
529         if (param.majorVersion > 2 && IsARM())
530             return false;
531 
532         // Loading swiftshader is not brought up on Fuchsia.
533         // TODO(anglebug.com/4353): Support loading swiftshader vulkan ICD.
534         if (param.getDeviceType() == EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE)
535             return false;
536 
537         // Currently we only support the Vulkan back-end on Fuchsia.
538         return (param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE);
539     }
540 
541     if (IsOzone())
542     {
543         // We do not support non-ANGLE bindings on Ozone.
544         if (param.driver != GLESDriverType::AngleEGL)
545             return false;
546 
547         // ES 3 configs do not work properly on Ozone.
548         if (param.majorVersion > 2)
549             return false;
550 
551         // Currently we only support the GLES back-end on Ozone.
552         return (param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE);
553     }
554 
555     if (IsLinux() || IsAndroid())
556     {
557         // We do not support WGL bindings on Linux/Android. We do support system EGL.
558         switch (param.driver)
559         {
560             case GLESDriverType::SystemEGL:
561                 return param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
562             case GLESDriverType::SystemWGL:
563                 return false;
564             default:
565                 break;
566         }
567     }
568 
569     if (IsLinux())
570     {
571         ASSERT(param.driver == GLESDriverType::AngleEGL);
572 
573         // Currently we support the OpenGL and Vulkan back-ends on Linux.
574         switch (param.getRenderer())
575         {
576             case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
577                 return true;
578             case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:
579                 // http://issuetracker.google.com/173004081
580                 return !IsIntel() || !param.isEnabled(Feature::AsyncCommandQueue) ||
581                        param.isDisabled(Feature::AsyncCommandQueue);
582             default:
583                 return false;
584         }
585     }
586 
587     if (IsAndroid())
588     {
589         ASSERT(param.driver == GLESDriverType::AngleEGL);
590 
591         // Nexus Android devices don't support backing 3.2 contexts
592         if (param.eglParameters.majorVersion == 3 && param.eglParameters.minorVersion == 2)
593         {
594             if (IsNexus5X())
595             {
596                 return false;
597             }
598         }
599 
600         // Currently we support the GLES and Vulkan back-ends on Android.
601         switch (param.getRenderer())
602         {
603             case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
604                 return true;
605             case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:
606                 // Swiftshader's vulkan frontend doesn't build on Android.
607                 if (param.getDeviceType() == EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE)
608                 {
609                     return false;
610                 }
611                 if (!IsAndroid9OrNewer())
612                 {
613                     return false;
614                 }
615                 if (param.isDisabled(Feature::SupportsNegativeViewport))
616                 {
617                     return false;
618                 }
619                 return true;
620             default:
621                 return false;
622         }
623     }
624 
625     // Unknown platform.
626     return false;
627 }
628 
IsConfigSupported(const PlatformParameters & param)629 bool IsConfigSupported(const PlatformParameters &param)
630 {
631     OSWindow *osWindow = OSWindow::New();
632     bool result        = false;
633     if (osWindow->initialize("CONFIG_TESTER", 1, 1))
634     {
635         switch (param.driver)
636         {
637             case GLESDriverType::AngleEGL:
638                 result = IsAngleEGLConfigSupported(param, osWindow);
639                 break;
640             case GLESDriverType::SystemEGL:
641                 result = IsSystemEGLConfigSupported(param, osWindow);
642                 break;
643             case GLESDriverType::SystemWGL:
644                 result = IsSystemWGLConfigSupported(param, osWindow);
645                 break;
646         }
647 
648         osWindow->destroy();
649     }
650 
651     OSWindow::Delete(&osWindow);
652     return result;
653 }
654 
IsPlatformAvailable(const PlatformParameters & param)655 bool IsPlatformAvailable(const PlatformParameters &param)
656 {
657     // Disable "null" device when not on ANGLE or in D3D9.
658     if (param.getDeviceType() == EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE)
659     {
660         if (param.driver != GLESDriverType::AngleEGL)
661             return false;
662         if (param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE)
663             return false;
664     }
665 
666     switch (param.getRenderer())
667     {
668         case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
669             break;
670 
671         case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE:
672 #if !defined(ANGLE_ENABLE_D3D9)
673             return false;
674 #else
675             break;
676 #endif
677 
678         case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
679 #if !defined(ANGLE_ENABLE_D3D11)
680             return false;
681 #else
682             break;
683 #endif
684 
685         case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
686         case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
687 #if !defined(ANGLE_ENABLE_OPENGL)
688             return false;
689 #else
690             break;
691 #endif
692 
693         case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:
694 #if !defined(ANGLE_ENABLE_VULKAN)
695             return false;
696 #else
697             break;
698 #endif
699 
700         case EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE:
701 #if !defined(ANGLE_ENABLE_METAL)
702             return false;
703 #else
704             break;
705 #endif
706 
707         case EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE:
708 #if !defined(ANGLE_ENABLE_NULL)
709             return false;
710 #else
711             break;
712 #endif
713 
714         default:
715             std::cout << "Unknown test platform: " << param << std::endl;
716             return false;
717     }
718 
719     bool result = false;
720 
721     auto iter = GetAvailabilityCache().find(param);
722     if (iter != GetAvailabilityCache().end())
723     {
724         result = iter->second;
725     }
726     else
727     {
728         if (IsConfigSelected())
729         {
730             std::stringstream strstr;
731             strstr << param;
732             if (strstr.str() == std::string(gSelectedConfig.data()))
733             {
734                 result = true;
735             }
736         }
737         else
738         {
739             const SystemInfo *systemInfo = GetTestSystemInfo();
740 
741             if (systemInfo)
742             {
743                 result = IsConfigAllowlisted(*systemInfo, param);
744             }
745             else
746             {
747                 result = IsConfigSupported(param);
748             }
749         }
750 
751         GetAvailabilityCache()[param] = result;
752 
753         // Enable this unconditionally to print available platforms.
754         if (IsConfigSelected())
755         {
756             if (result)
757             {
758                 std::cout << "Test Config: " << param << "\n";
759             }
760         }
761         else if (!result)
762         {
763             std::cout << "Skipping tests using configuration " << param
764                       << " because it is not available.\n";
765         }
766     }
767     return result;
768 }
769 
GetAvailableTestPlatformNames()770 std::vector<std::string> GetAvailableTestPlatformNames()
771 {
772     std::vector<std::string> platformNames;
773 
774     for (const auto &iter : GetAvailabilityCache())
775     {
776         if (iter.second)
777         {
778             std::stringstream strstr;
779             strstr << iter.first;
780             platformNames.push_back(strstr.str());
781         }
782     }
783 
784     // Keep the list sorted.
785     std::sort(platformNames.begin(), platformNames.end());
786 
787     return platformNames;
788 }
789 
SetSelectedConfig(const char * selectedConfig)790 void SetSelectedConfig(const char *selectedConfig)
791 {
792     gSelectedConfig.fill(0);
793     strncpy(gSelectedConfig.data(), selectedConfig, kMaxConfigNameLen - 1);
794 }
795 }  // namespace angle
796