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