xref: /aosp_15_r20/external/deqp/framework/egl/egluUtil.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program Tester Core
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 EGL utilities
22  *//*--------------------------------------------------------------------*/
23 
24 #include "egluUtil.hpp"
25 #include "egluDefs.hpp"
26 #include "egluNativeDisplay.hpp"
27 #include "egluConfigFilter.hpp"
28 #include "eglwLibrary.hpp"
29 #include "eglwEnums.hpp"
30 #include "tcuCommandLine.hpp"
31 #include "deSTLUtil.hpp"
32 #include "deStringUtil.hpp"
33 #include "glwEnums.hpp"
34 
35 #include <algorithm>
36 #include <sstream>
37 
38 using std::string;
39 using std::vector;
40 
41 namespace eglu
42 {
43 
44 using namespace eglw;
45 
attribMapToList(const AttribMap & attribs)46 vector<EGLint> attribMapToList(const AttribMap &attribs)
47 {
48     vector<EGLint> attribList;
49 
50     for (AttribMap::const_iterator it = attribs.begin(); it != attribs.end(); ++it)
51     {
52         attribList.push_back(it->first);
53         attribList.push_back(it->second);
54     }
55 
56     attribList.push_back(EGL_NONE);
57 
58     return attribList;
59 }
60 
getVersion(const Library & egl,EGLDisplay display)61 Version getVersion(const Library &egl, EGLDisplay display)
62 {
63     EGLint major, minor;
64 
65     // eglInitialize on already initialized displays just returns the version.
66     EGLU_CHECK_CALL(egl, initialize(display, &major, &minor));
67 
68     return Version(major, minor);
69 }
70 
getExtensions(const Library & egl,EGLDisplay display)71 vector<string> getExtensions(const Library &egl, EGLDisplay display)
72 {
73     const char *const extensionStr = egl.queryString(display, EGL_EXTENSIONS);
74 
75     EGLU_CHECK_MSG(egl, "Querying extensions failed");
76 
77     return de::splitString(extensionStr, ' ');
78 }
79 
hasExtension(const Library & egl,EGLDisplay display,const string & str)80 bool hasExtension(const Library &egl, EGLDisplay display, const string &str)
81 {
82     const vector<string> extensions = getExtensions(egl, display);
83     return de::contains(extensions.begin(), extensions.end(), str);
84 }
85 
getClientExtensions(const Library & egl)86 vector<string> getClientExtensions(const Library &egl)
87 {
88     const char *const extensionStr = egl.queryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
89     const EGLint eglError          = egl.getError();
90     if (eglError == EGL_BAD_DISPLAY && extensionStr == DE_NULL)
91     {
92         // We do not support client extensions
93         TCU_THROW(NotSupportedError, "EGL_EXT_client_extensions not supported");
94     }
95 
96     EGLU_CHECK_MSG(egl, "Querying extensions failed");
97 
98     return de::splitString(extensionStr, ' ');
99 }
100 
getDisplayExtensions(const Library & egl,EGLDisplay display)101 vector<string> getDisplayExtensions(const Library &egl, EGLDisplay display)
102 {
103     DE_ASSERT(display != EGL_NO_DISPLAY);
104 
105     return getExtensions(egl, display);
106 }
107 
getConfigs(const Library & egl,EGLDisplay display)108 vector<EGLConfig> getConfigs(const Library &egl, EGLDisplay display)
109 {
110     vector<EGLConfig> configs;
111     EGLint configCount = 0;
112     EGLU_CHECK_CALL(egl, getConfigs(display, DE_NULL, 0, &configCount));
113 
114     if (configCount > 0)
115     {
116         configs.resize(configCount);
117         EGLU_CHECK_CALL(egl, getConfigs(display, &(configs[0]), (EGLint)configs.size(), &configCount));
118     }
119 
120     return configs;
121 }
122 
chooseConfigs(const Library & egl,EGLDisplay display,const EGLint * attribList)123 vector<EGLConfig> chooseConfigs(const Library &egl, EGLDisplay display, const EGLint *attribList)
124 {
125     EGLint numConfigs = 0;
126 
127     EGLU_CHECK_CALL(egl, chooseConfig(display, attribList, DE_NULL, 0, &numConfigs));
128 
129     {
130         vector<EGLConfig> configs(numConfigs);
131 
132         if (numConfigs > 0)
133             EGLU_CHECK_CALL(egl, chooseConfig(display, attribList, &configs.front(), numConfigs, &numConfigs));
134 
135         return configs;
136     }
137 }
138 
chooseConfigs(const Library & egl,EGLDisplay display,const FilterList & filters)139 vector<EGLConfig> chooseConfigs(const Library &egl, EGLDisplay display, const FilterList &filters)
140 {
141     const vector<EGLConfig> allConfigs(getConfigs(egl, display));
142     vector<EGLConfig> matchingConfigs;
143 
144     for (vector<EGLConfig>::const_iterator cfg = allConfigs.begin(); cfg != allConfigs.end(); ++cfg)
145     {
146         if (filters.match(egl, display, *cfg))
147             matchingConfigs.push_back(*cfg);
148     }
149 
150     return matchingConfigs;
151 }
152 
chooseSingleConfig(const Library & egl,EGLDisplay display,const FilterList & filters)153 EGLConfig chooseSingleConfig(const Library &egl, EGLDisplay display, const FilterList &filters)
154 {
155     const vector<EGLConfig> allConfigs(getConfigs(egl, display));
156 
157     for (vector<EGLConfig>::const_iterator cfg = allConfigs.begin(); cfg != allConfigs.end(); ++cfg)
158     {
159         if (filters.match(egl, display, *cfg))
160             return *cfg;
161     }
162 
163     TCU_THROW(NotSupportedError, "No matching EGL config found");
164 }
165 
chooseSingleConfig(const Library & egl,EGLDisplay display,const EGLint * attribList)166 EGLConfig chooseSingleConfig(const Library &egl, EGLDisplay display, const EGLint *attribList)
167 {
168     const vector<EGLConfig> configs(chooseConfigs(egl, display, attribList));
169     if (configs.empty())
170         TCU_THROW(NotSupportedError, "No matching EGL config found");
171 
172     return configs.front();
173 }
174 
chooseConfigs(const Library & egl,EGLDisplay display,const AttribMap & attribs)175 vector<EGLConfig> chooseConfigs(const Library &egl, EGLDisplay display, const AttribMap &attribs)
176 {
177     const vector<EGLint> attribList = attribMapToList(attribs);
178     return chooseConfigs(egl, display, &attribList.front());
179 }
180 
chooseSingleConfig(const Library & egl,EGLDisplay display,const AttribMap & attribs)181 EGLConfig chooseSingleConfig(const Library &egl, EGLDisplay display, const AttribMap &attribs)
182 {
183     const vector<EGLint> attribList = attribMapToList(attribs);
184     return chooseSingleConfig(egl, display, &attribList.front());
185 }
186 
chooseConfigByID(const Library & egl,EGLDisplay display,EGLint id)187 EGLConfig chooseConfigByID(const Library &egl, EGLDisplay display, EGLint id)
188 {
189     AttribMap attribs;
190 
191     attribs[EGL_CONFIG_ID]         = id;
192     attribs[EGL_TRANSPARENT_TYPE]  = EGL_DONT_CARE;
193     attribs[EGL_COLOR_BUFFER_TYPE] = EGL_DONT_CARE;
194     attribs[EGL_RENDERABLE_TYPE]   = EGL_DONT_CARE;
195     attribs[EGL_SURFACE_TYPE]      = EGL_DONT_CARE;
196 
197     return chooseSingleConfig(egl, display, attribs);
198 }
199 
getConfigAttribInt(const Library & egl,EGLDisplay display,EGLConfig config,EGLint attrib)200 EGLint getConfigAttribInt(const Library &egl, EGLDisplay display, EGLConfig config, EGLint attrib)
201 {
202     EGLint value = 0;
203     EGLU_CHECK_CALL(egl, getConfigAttrib(display, config, attrib, &value));
204     return value;
205 }
206 
getConfigID(const Library & egl,EGLDisplay display,EGLConfig config)207 EGLint getConfigID(const Library &egl, EGLDisplay display, EGLConfig config)
208 {
209     return getConfigAttribInt(egl, display, config, EGL_CONFIG_ID);
210 }
211 
querySurfaceInt(const Library & egl,EGLDisplay display,EGLSurface surface,EGLint attrib)212 EGLint querySurfaceInt(const Library &egl, EGLDisplay display, EGLSurface surface, EGLint attrib)
213 {
214     EGLint value = 0;
215     EGLU_CHECK_CALL(egl, querySurface(display, surface, attrib, &value));
216     return value;
217 }
218 
getSurfaceSize(const Library & egl,EGLDisplay display,EGLSurface surface)219 tcu::IVec2 getSurfaceSize(const Library &egl, EGLDisplay display, EGLSurface surface)
220 {
221     const EGLint width  = querySurfaceInt(egl, display, surface, EGL_WIDTH);
222     const EGLint height = querySurfaceInt(egl, display, surface, EGL_HEIGHT);
223     return tcu::IVec2(width, height);
224 }
225 
getSurfaceResolution(const Library & egl,EGLDisplay display,EGLSurface surface)226 tcu::IVec2 getSurfaceResolution(const Library &egl, EGLDisplay display, EGLSurface surface)
227 {
228     const EGLint hRes = querySurfaceInt(egl, display, surface, EGL_HORIZONTAL_RESOLUTION);
229     const EGLint vRes = querySurfaceInt(egl, display, surface, EGL_VERTICAL_RESOLUTION);
230 
231     if (hRes == EGL_UNKNOWN || vRes == EGL_UNKNOWN)
232         TCU_THROW(NotSupportedError, "Surface doesn't support pixel density queries");
233     return tcu::IVec2(hRes, vRes);
234 }
235 
236 //! Get EGLdisplay using eglGetDisplay() or eglGetPlatformDisplayEXT()
getDisplay(NativeDisplay & nativeDisplay)237 EGLDisplay getDisplay(NativeDisplay &nativeDisplay)
238 {
239     const Library &egl = nativeDisplay.getLibrary();
240     const bool supportsLegacyGetDisplay =
241         (nativeDisplay.getCapabilities() & NativeDisplay::CAPABILITY_GET_DISPLAY_LEGACY) != 0;
242     bool maySupportPlatformGetDisplay =
243         (nativeDisplay.getCapabilities() & NativeDisplay::CAPABILITY_GET_DISPLAY_PLATFORM) != 0;
244     bool maySupportPlatformGetDisplayEXT =
245         (nativeDisplay.getCapabilities() & NativeDisplay::CAPABILITY_GET_DISPLAY_PLATFORM_EXT) != 0;
246     bool usePlatformExt = false;
247     EGLDisplay display  = EGL_NO_DISPLAY;
248 
249     TCU_CHECK_INTERNAL(supportsLegacyGetDisplay || maySupportPlatformGetDisplay);
250 
251     if (maySupportPlatformGetDisplayEXT)
252     {
253         try
254         {
255             const vector<string> platformExts = eglu::getClientExtensions(egl);
256             usePlatformExt = de::contains(platformExts.begin(), platformExts.end(), string("EGL_EXT_platform_base")) &&
257                              nativeDisplay.getPlatformExtensionName() &&
258                              de::contains(platformExts.begin(), platformExts.end(),
259                                           string(nativeDisplay.getPlatformExtensionName()));
260         }
261         catch (const tcu::NotSupportedError &)
262         {
263             // If we can't get the client extension string we must not have EGL 1.5 support or the appropriate extensions.
264             maySupportPlatformGetDisplay    = false;
265             maySupportPlatformGetDisplayEXT = false;
266             usePlatformExt                  = false;
267         }
268     }
269 
270     if (maySupportPlatformGetDisplay)
271     {
272         display = egl.getPlatformDisplay(nativeDisplay.getPlatformType(), nativeDisplay.getPlatformNative(),
273                                          nativeDisplay.getPlatformAttributes());
274         EGLU_CHECK_MSG(egl, "eglGetPlatformDisplay()");
275         TCU_CHECK(display != EGL_NO_DISPLAY);
276     }
277     else if (usePlatformExt)
278     {
279         const vector<EGLint> legacyAttribs = toLegacyAttribList(nativeDisplay.getPlatformAttributes());
280 
281         display = egl.getPlatformDisplayEXT(nativeDisplay.getPlatformType(), nativeDisplay.getPlatformNative(),
282                                             &legacyAttribs[0]);
283         EGLU_CHECK_MSG(egl, "eglGetPlatformDisplayEXT()");
284         TCU_CHECK(display != EGL_NO_DISPLAY);
285     }
286     else if (supportsLegacyGetDisplay)
287     {
288         display = egl.getDisplay(nativeDisplay.getLegacyNative());
289         EGLU_CHECK_MSG(egl, "eglGetDisplay()");
290         TCU_CHECK(display != EGL_NO_DISPLAY);
291     }
292     else
293         throw tcu::InternalError("No supported way to get EGL display", DE_NULL, __FILE__, __LINE__);
294 
295     DE_ASSERT(display != EGL_NO_DISPLAY);
296     return display;
297 }
298 
getAndInitDisplay(NativeDisplay & nativeDisplay,Version * version)299 EGLDisplay getAndInitDisplay(NativeDisplay &nativeDisplay, Version *version)
300 {
301     const Library &egl = nativeDisplay.getLibrary();
302     EGLDisplay display = getDisplay(nativeDisplay);
303     int major, minor;
304 
305     EGLU_CHECK_CALL(egl, initialize(display, &major, &minor));
306 
307     if (version)
308         *version = Version(major, minor);
309 
310     return display;
311 }
312 
terminateDisplay(const Library & egl,EGLDisplay display)313 void terminateDisplay(const Library &egl, EGLDisplay display)
314 {
315     EGLU_CHECK_CALL(egl, terminate(display));
316 }
317 
318 //! Create EGL window surface using eglCreatePlatformWindowSurface, eglCreateWindowSurface() or eglCreatePlatformWindowSurfaceEXT()
createWindowSurface(NativeDisplay & nativeDisplay,NativeWindow & window,EGLDisplay display,EGLConfig config,const EGLAttrib * attribList)319 EGLSurface createWindowSurface(NativeDisplay &nativeDisplay, NativeWindow &window, EGLDisplay display, EGLConfig config,
320                                const EGLAttrib *attribList)
321 {
322     const Library &egl              = nativeDisplay.getLibrary();
323     const bool supportsLegacyCreate = (window.getCapabilities() & NativeWindow::CAPABILITY_CREATE_SURFACE_LEGACY) != 0;
324     bool maySupportPlatformCreate =
325         ((window.getCapabilities() & NativeWindow::CAPABILITY_CREATE_SURFACE_PLATFORM) != 0 &&
326          eglu::getVersion(egl, display) >= eglu::Version(1, 5));
327     bool maySupportPlatformCreateExtension =
328         (window.getCapabilities() & NativeWindow::CAPABILITY_CREATE_SURFACE_PLATFORM_EXTENSION) != 0;
329     bool usePlatformExt = false;
330     EGLSurface surface  = EGL_NO_SURFACE;
331 
332     TCU_CHECK_INTERNAL(supportsLegacyCreate || maySupportPlatformCreateExtension || maySupportPlatformCreate);
333 
334     if (maySupportPlatformCreateExtension)
335     {
336         try
337         {
338             const vector<string> platformExts = eglu::getClientExtensions(egl);
339             usePlatformExt = de::contains(platformExts.begin(), platformExts.end(), string("EGL_EXT_platform_base")) &&
340                              nativeDisplay.getPlatformExtensionName() &&
341                              de::contains(platformExts.begin(), platformExts.end(),
342                                           string(nativeDisplay.getPlatformExtensionName()));
343         }
344         catch (const tcu::NotSupportedError &)
345         {
346             maySupportPlatformCreate          = false;
347             maySupportPlatformCreateExtension = false;
348             usePlatformExt                    = false;
349         }
350     }
351 
352     if (maySupportPlatformCreate)
353     {
354         surface = egl.createPlatformWindowSurface(display, config, window.getPlatformNative(), attribList);
355         EGLU_CHECK_MSG(egl, "eglCreatePlatformWindowSurface()");
356         TCU_CHECK(surface != EGL_NO_SURFACE);
357     }
358     else if (usePlatformExt)
359     {
360         const vector<EGLint> legacyAttribs = toLegacyAttribList(attribList);
361         surface = egl.createPlatformWindowSurfaceEXT(display, config, window.getPlatformExtension(), &legacyAttribs[0]);
362         EGLU_CHECK_MSG(egl, "eglCreatePlatformWindowSurfaceEXT()");
363         TCU_CHECK(surface != EGL_NO_SURFACE);
364     }
365     else if (supportsLegacyCreate)
366     {
367         const vector<EGLint> legacyAttribs = toLegacyAttribList(attribList);
368         surface = egl.createWindowSurface(display, config, window.getLegacyNative(), &legacyAttribs[0]);
369         EGLU_CHECK_MSG(egl, "eglCreateWindowSurface()");
370         TCU_CHECK(surface != EGL_NO_SURFACE);
371     }
372     else
373         throw tcu::InternalError("No supported way to create EGL window surface", DE_NULL, __FILE__, __LINE__);
374 
375     DE_ASSERT(surface != EGL_NO_SURFACE);
376     return surface;
377 }
378 
379 //! Create EGL pixmap surface using eglCreatePixmapSurface() or eglCreatePlatformPixmapSurfaceEXT()
createPixmapSurface(NativeDisplay & nativeDisplay,NativePixmap & pixmap,EGLDisplay display,EGLConfig config,const EGLAttrib * attribList)380 EGLSurface createPixmapSurface(NativeDisplay &nativeDisplay, NativePixmap &pixmap, EGLDisplay display, EGLConfig config,
381                                const EGLAttrib *attribList)
382 {
383     const Library &egl              = nativeDisplay.getLibrary();
384     const bool supportsLegacyCreate = (pixmap.getCapabilities() & NativePixmap::CAPABILITY_CREATE_SURFACE_LEGACY) != 0;
385     bool maySupportPlatformCreateExtension =
386         (pixmap.getCapabilities() & NativePixmap::CAPABILITY_CREATE_SURFACE_PLATFORM_EXTENSION) != 0;
387     bool maySupportPlatformCreate =
388         ((pixmap.getCapabilities() & NativePixmap::CAPABILITY_CREATE_SURFACE_PLATFORM) != 0 &&
389          eglu::getVersion(egl, display) >= eglu::Version(1, 5));
390     bool usePlatformExt = false;
391     EGLSurface surface  = EGL_NO_SURFACE;
392 
393     TCU_CHECK_INTERNAL(supportsLegacyCreate || maySupportPlatformCreateExtension || maySupportPlatformCreate);
394 
395     if (maySupportPlatformCreateExtension)
396     {
397         try
398         {
399             const vector<string> platformExts = eglu::getClientExtensions(egl);
400             usePlatformExt = de::contains(platformExts.begin(), platformExts.end(), string("EGL_EXT_platform_base")) &&
401                              nativeDisplay.getPlatformExtensionName() &&
402                              de::contains(platformExts.begin(), platformExts.end(),
403                                           string(nativeDisplay.getPlatformExtensionName()));
404         }
405         catch (const tcu::NotSupportedError &)
406         {
407             maySupportPlatformCreate          = false;
408             maySupportPlatformCreateExtension = false;
409             usePlatformExt                    = false;
410         }
411     }
412 
413     if (maySupportPlatformCreate)
414     {
415         surface = egl.createPlatformPixmapSurface(display, config, pixmap.getPlatformNative(), attribList);
416         EGLU_CHECK_MSG(egl, "eglCreatePlatformPixmapSurface()");
417         TCU_CHECK(surface != EGL_NO_SURFACE);
418     }
419     else if (usePlatformExt)
420     {
421         const vector<EGLint> legacyAttribs = toLegacyAttribList(attribList);
422 
423         surface = egl.createPlatformPixmapSurfaceEXT(display, config, pixmap.getPlatformExtension(), &legacyAttribs[0]);
424         EGLU_CHECK_MSG(egl, "eglCreatePlatformPixmapSurfaceEXT()");
425         TCU_CHECK(surface != EGL_NO_SURFACE);
426     }
427     else if (supportsLegacyCreate)
428     {
429         const vector<EGLint> legacyAttribs = toLegacyAttribList(attribList);
430         surface = egl.createPixmapSurface(display, config, pixmap.getLegacyNative(), &legacyAttribs[0]);
431         EGLU_CHECK_MSG(egl, "eglCreatePixmapSurface()");
432         TCU_CHECK(surface != EGL_NO_SURFACE);
433     }
434     else
435         throw tcu::InternalError("No supported way to create EGL pixmap surface", DE_NULL, __FILE__, __LINE__);
436 
437     DE_ASSERT(surface != EGL_NO_SURFACE);
438     return surface;
439 }
440 
getWindowVisibility(tcu::WindowVisibility visibility)441 static WindowParams::Visibility getWindowVisibility(tcu::WindowVisibility visibility)
442 {
443     switch (visibility)
444     {
445     case tcu::WINDOWVISIBILITY_WINDOWED:
446         return WindowParams::VISIBILITY_VISIBLE;
447     case tcu::WINDOWVISIBILITY_FULLSCREEN:
448         return WindowParams::VISIBILITY_FULLSCREEN;
449     case tcu::WINDOWVISIBILITY_HIDDEN:
450         return WindowParams::VISIBILITY_HIDDEN;
451 
452     default:
453         DE_ASSERT(false);
454         return WindowParams::VISIBILITY_DONT_CARE;
455     }
456 }
457 
parseWindowVisibility(const tcu::CommandLine & commandLine)458 WindowParams::Visibility parseWindowVisibility(const tcu::CommandLine &commandLine)
459 {
460     return getWindowVisibility(commandLine.getVisibility());
461 }
462 
parseClientAPI(const std::string & api)463 EGLenum parseClientAPI(const std::string &api)
464 {
465     if (api == "OpenGL")
466         return EGL_OPENGL_API;
467     else if (api == "OpenGL_ES")
468         return EGL_OPENGL_ES_API;
469     else if (api == "OpenVG")
470         return EGL_OPENVG_API;
471     else
472         throw tcu::InternalError("Unknown EGL client API '" + api + "'");
473 }
474 
parseClientAPIs(const std::string & apiList)475 vector<EGLenum> parseClientAPIs(const std::string &apiList)
476 {
477     const vector<string> apiStrs = de::splitString(apiList, ' ');
478     vector<EGLenum> apis;
479 
480     for (vector<string>::const_iterator api = apiStrs.begin(); api != apiStrs.end(); ++api)
481         apis.push_back(parseClientAPI(*api));
482 
483     return apis;
484 }
485 
getClientAPIs(const eglw::Library & egl,eglw::EGLDisplay display)486 vector<EGLenum> getClientAPIs(const eglw::Library &egl, eglw::EGLDisplay display)
487 {
488     return parseClientAPIs(egl.queryString(display, EGL_CLIENT_APIS));
489 }
490 
getRenderableAPIsMask(const eglw::Library & egl,eglw::EGLDisplay display)491 EGLint getRenderableAPIsMask(const eglw::Library &egl, eglw::EGLDisplay display)
492 {
493     const vector<EGLConfig> configs = getConfigs(egl, display);
494     EGLint allAPIs                  = 0;
495 
496     for (vector<EGLConfig>::const_iterator i = configs.begin(); i != configs.end(); ++i)
497         allAPIs |= getConfigAttribInt(egl, display, *i, EGL_RENDERABLE_TYPE);
498 
499     return allAPIs;
500 }
501 
toLegacyAttribList(const EGLAttrib * attribs)502 vector<EGLint> toLegacyAttribList(const EGLAttrib *attribs)
503 {
504     const uint64_t attribMask = 0xffffffffull; //!< Max bits that can be used
505     vector<EGLint> legacyAttribs;
506 
507     if (attribs)
508     {
509         for (const EGLAttrib *attrib = attribs; *attrib != EGL_NONE; attrib += 2)
510         {
511             if ((attrib[0] & ~attribMask) || (attrib[1] & ~attribMask))
512                 throw tcu::InternalError("Failed to translate EGLAttrib to EGLint", DE_NULL, __FILE__, __LINE__);
513 
514             legacyAttribs.push_back((EGLint)attrib[0]);
515             legacyAttribs.push_back((EGLint)attrib[1]);
516         }
517     }
518 
519     legacyAttribs.push_back(EGL_NONE);
520 
521     return legacyAttribs;
522 }
523 
524 template <typename Factory>
selectFactory(const tcu::FactoryRegistry<Factory> & registry,const char * objectTypeName,const char * cmdLineArg)525 static const Factory &selectFactory(const tcu::FactoryRegistry<Factory> &registry, const char *objectTypeName,
526                                     const char *cmdLineArg)
527 {
528     if (cmdLineArg)
529     {
530         const Factory *factory = registry.getFactoryByName(cmdLineArg);
531 
532         if (factory)
533             return *factory;
534         else
535         {
536             tcu::print("ERROR: Unknown or unsupported EGL %s type '%s'", objectTypeName, cmdLineArg);
537             tcu::print("Available EGL %s types:\n", objectTypeName);
538             for (size_t ndx = 0; ndx < registry.getFactoryCount(); ndx++)
539                 tcu::print("  %s: %s\n", registry.getFactoryByIndex(ndx)->getName(),
540                            registry.getFactoryByIndex(ndx)->getDescription());
541 
542             TCU_THROW(NotSupportedError,
543                       (string("Unsupported or unknown EGL ") + objectTypeName + " type '" + cmdLineArg + "'").c_str());
544         }
545     }
546     else if (!registry.empty())
547         return *registry.getDefaultFactory();
548     else
549         TCU_THROW(NotSupportedError, (string("No factory supporting EGL '") + objectTypeName + "' type").c_str());
550 }
551 
selectNativeDisplayFactory(const NativeDisplayFactoryRegistry & registry,const tcu::CommandLine & cmdLine)552 const NativeDisplayFactory &selectNativeDisplayFactory(const NativeDisplayFactoryRegistry &registry,
553                                                        const tcu::CommandLine &cmdLine)
554 {
555     return selectFactory(registry, "display", cmdLine.getEGLDisplayType());
556 }
557 
selectNativeWindowFactory(const NativeDisplayFactory & factory,const tcu::CommandLine & cmdLine)558 const NativeWindowFactory &selectNativeWindowFactory(const NativeDisplayFactory &factory,
559                                                      const tcu::CommandLine &cmdLine)
560 {
561     return selectFactory(factory.getNativeWindowRegistry(), "window", cmdLine.getEGLWindowType());
562 }
563 
selectNativePixmapFactory(const NativeDisplayFactory & factory,const tcu::CommandLine & cmdLine)564 const NativePixmapFactory &selectNativePixmapFactory(const NativeDisplayFactory &factory,
565                                                      const tcu::CommandLine &cmdLine)
566 {
567     return selectFactory(factory.getNativePixmapRegistry(), "pixmap", cmdLine.getEGLPixmapType());
568 }
569 
570 } // namespace eglu
571