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 				nativeDisplay.getPlatformExtensionName() &&
254 				de::contains(platformExts.begin(), platformExts.end(), string(nativeDisplay.getPlatformExtensionName()));
255 
256 		}
257 		catch (const tcu::NotSupportedError&)
258 		{
259 			// If we can't get the client extension string we must not have EGL 1.5 support or the appropriate extensions.
260 			maySupportPlatformGetDisplay = false;
261 			maySupportPlatformGetDisplayEXT = false;
262 			usePlatformExt = false;
263 		}
264 	}
265 
266 	if (maySupportPlatformGetDisplay)
267 	{
268 		display = egl.getPlatformDisplay(nativeDisplay.getPlatformType(), nativeDisplay.getPlatformNative(), nativeDisplay.getPlatformAttributes());
269 		EGLU_CHECK_MSG(egl, "eglGetPlatformDisplay()");
270 		TCU_CHECK(display != EGL_NO_DISPLAY);
271 	}
272 	else if (usePlatformExt)
273 	{
274 		const vector<EGLint>	legacyAttribs	= toLegacyAttribList(nativeDisplay.getPlatformAttributes());
275 
276 		display = egl.getPlatformDisplayEXT(nativeDisplay.getPlatformType(), nativeDisplay.getPlatformNative(), &legacyAttribs[0]);
277 		EGLU_CHECK_MSG(egl, "eglGetPlatformDisplayEXT()");
278 		TCU_CHECK(display != EGL_NO_DISPLAY);
279 	}
280 	else if (supportsLegacyGetDisplay)
281 	{
282 		display = egl.getDisplay(nativeDisplay.getLegacyNative());
283 		EGLU_CHECK_MSG(egl, "eglGetDisplay()");
284 		TCU_CHECK(display != EGL_NO_DISPLAY);
285 	}
286 	else
287 		throw tcu::InternalError("No supported way to get EGL display", DE_NULL, __FILE__, __LINE__);
288 
289 	DE_ASSERT(display != EGL_NO_DISPLAY);
290 	return display;
291 }
292 
getAndInitDisplay(NativeDisplay & nativeDisplay,Version * version)293 EGLDisplay getAndInitDisplay (NativeDisplay& nativeDisplay, Version* version)
294 {
295 	const Library&	egl		= nativeDisplay.getLibrary();
296 	EGLDisplay		display	= getDisplay(nativeDisplay);
297 	int				major, minor;
298 
299 	EGLU_CHECK_CALL(egl, initialize(display, &major, &minor));
300 
301 	if (version)
302 		*version = Version(major, minor);
303 
304 	return display;
305 }
306 
terminateDisplay(const Library & egl,EGLDisplay display)307 void terminateDisplay(const Library& egl, EGLDisplay display)
308 {
309 	EGLU_CHECK_CALL(egl, terminate(display));
310 }
311 
312 //! Create EGL window surface using eglCreatePlatformWindowSurface, eglCreateWindowSurface() or eglCreatePlatformWindowSurfaceEXT()
createWindowSurface(NativeDisplay & nativeDisplay,NativeWindow & window,EGLDisplay display,EGLConfig config,const EGLAttrib * attribList)313 EGLSurface createWindowSurface (NativeDisplay& nativeDisplay, NativeWindow& window, EGLDisplay display, EGLConfig config, const EGLAttrib* attribList)
314 {
315 	const Library&	egl									= nativeDisplay.getLibrary();
316 	const bool		supportsLegacyCreate				= (window.getCapabilities() & NativeWindow::CAPABILITY_CREATE_SURFACE_LEGACY) != 0;
317 	bool			maySupportPlatformCreate				= ((window.getCapabilities() & NativeWindow::CAPABILITY_CREATE_SURFACE_PLATFORM) != 0
318 														   && eglu::getVersion(egl, display) >= eglu::Version(1, 5));
319 	bool			maySupportPlatformCreateExtension		= (window.getCapabilities() & NativeWindow::CAPABILITY_CREATE_SURFACE_PLATFORM_EXTENSION) != 0;
320 	bool			usePlatformExt						= false;
321 	EGLSurface		surface								= EGL_NO_SURFACE;
322 
323 	TCU_CHECK_INTERNAL(supportsLegacyCreate || maySupportPlatformCreateExtension || maySupportPlatformCreate);
324 
325 	if (maySupportPlatformCreateExtension)
326 	{
327 		try
328 		{
329 			const vector<string> platformExts = eglu::getClientExtensions(egl);
330 			usePlatformExt = de::contains(platformExts.begin(), platformExts.end(), string("EGL_EXT_platform_base")) &&
331 				nativeDisplay.getPlatformExtensionName() &&
332 				de::contains(platformExts.begin(), platformExts.end(), string(nativeDisplay.getPlatformExtensionName()));
333 
334 		}
335 		catch (const tcu::NotSupportedError&)
336 		{
337 			maySupportPlatformCreate = false;
338 			maySupportPlatformCreateExtension = false;
339 			usePlatformExt = false;
340 		}
341 	}
342 
343 	if (maySupportPlatformCreate)
344 	{
345 		surface = egl.createPlatformWindowSurface(display, config, window.getPlatformNative(), attribList);
346 		EGLU_CHECK_MSG(egl, "eglCreatePlatformWindowSurface()");
347 		TCU_CHECK(surface != EGL_NO_SURFACE);
348 	}
349 	else if (usePlatformExt)
350 	{
351 		const vector<EGLint>	legacyAttribs	= toLegacyAttribList(attribList);
352 		surface = egl.createPlatformWindowSurfaceEXT(display, config, window.getPlatformExtension(), &legacyAttribs[0]);
353 		EGLU_CHECK_MSG(egl, "eglCreatePlatformWindowSurfaceEXT()");
354 		TCU_CHECK(surface != EGL_NO_SURFACE);
355 	}
356 	else if (supportsLegacyCreate)
357 	{
358 		const vector<EGLint> legacyAttribs = toLegacyAttribList(attribList);
359 		surface = egl.createWindowSurface(display, config, window.getLegacyNative(), &legacyAttribs[0]);
360 		EGLU_CHECK_MSG(egl, "eglCreateWindowSurface()");
361 		TCU_CHECK(surface != EGL_NO_SURFACE);
362 	}
363 	else
364 		throw tcu::InternalError("No supported way to create EGL window surface", DE_NULL, __FILE__, __LINE__);
365 
366 	DE_ASSERT(surface != EGL_NO_SURFACE);
367 	return surface;
368 }
369 
370 //! Create EGL pixmap surface using eglCreatePixmapSurface() or eglCreatePlatformPixmapSurfaceEXT()
createPixmapSurface(NativeDisplay & nativeDisplay,NativePixmap & pixmap,EGLDisplay display,EGLConfig config,const EGLAttrib * attribList)371 EGLSurface createPixmapSurface (NativeDisplay& nativeDisplay, NativePixmap& pixmap, EGLDisplay display, EGLConfig config, const EGLAttrib* attribList)
372 {
373 	const Library&	egl									= nativeDisplay.getLibrary();
374 	const bool		supportsLegacyCreate				= (pixmap.getCapabilities() & NativePixmap::CAPABILITY_CREATE_SURFACE_LEGACY) != 0;
375 	bool			maySupportPlatformCreateExtension	= (pixmap.getCapabilities() & NativePixmap::CAPABILITY_CREATE_SURFACE_PLATFORM_EXTENSION) != 0;
376 	bool			maySupportPlatformCreate			= ((pixmap.getCapabilities() & NativePixmap::CAPABILITY_CREATE_SURFACE_PLATFORM) != 0
377 														   && eglu::getVersion(egl, display) >= eglu::Version(1, 5));
378 	bool			usePlatformExt						= false;
379 	EGLSurface		surface								= EGL_NO_SURFACE;
380 
381 	TCU_CHECK_INTERNAL(supportsLegacyCreate || maySupportPlatformCreateExtension || maySupportPlatformCreate);
382 
383 	if (maySupportPlatformCreateExtension)
384 	{
385 		try
386 		{
387 			const vector<string> platformExts = eglu::getClientExtensions(egl);
388 			usePlatformExt = de::contains(platformExts.begin(), platformExts.end(), string("EGL_EXT_platform_base")) &&
389 				nativeDisplay.getPlatformExtensionName() &&
390 				de::contains(platformExts.begin(), platformExts.end(), string(nativeDisplay.getPlatformExtensionName()));
391 
392 		}
393 		catch (const tcu::NotSupportedError&)
394 		{
395 			maySupportPlatformCreate = false;
396 			maySupportPlatformCreateExtension = false;
397 			usePlatformExt = false;
398 		}
399 	}
400 
401 	if (maySupportPlatformCreate)
402 	{
403 		surface = egl.createPlatformPixmapSurface(display, config, pixmap.getPlatformNative(), attribList);
404 		EGLU_CHECK_MSG(egl, "eglCreatePlatformPixmapSurface()");
405 		TCU_CHECK(surface != EGL_NO_SURFACE);
406 	}
407 	else if (usePlatformExt)
408 	{
409 		const vector<EGLint>	legacyAttribs	= toLegacyAttribList(attribList);
410 
411 		surface = egl.createPlatformPixmapSurfaceEXT(display, config, pixmap.getPlatformExtension(), &legacyAttribs[0]);
412 		EGLU_CHECK_MSG(egl, "eglCreatePlatformPixmapSurfaceEXT()");
413 		TCU_CHECK(surface != EGL_NO_SURFACE);
414 	}
415 	else if (supportsLegacyCreate)
416 	{
417 		const vector<EGLint> legacyAttribs = toLegacyAttribList(attribList);
418 		surface = egl.createPixmapSurface(display, config, pixmap.getLegacyNative(), &legacyAttribs[0]);
419 		EGLU_CHECK_MSG(egl, "eglCreatePixmapSurface()");
420 		TCU_CHECK(surface != EGL_NO_SURFACE);
421 	}
422 	else
423 		throw tcu::InternalError("No supported way to create EGL pixmap surface", DE_NULL, __FILE__, __LINE__);
424 
425 	DE_ASSERT(surface != EGL_NO_SURFACE);
426 	return surface;
427 }
428 
getWindowVisibility(tcu::WindowVisibility visibility)429 static WindowParams::Visibility getWindowVisibility (tcu::WindowVisibility visibility)
430 {
431 	switch (visibility)
432 	{
433 		case tcu::WINDOWVISIBILITY_WINDOWED:	return WindowParams::VISIBILITY_VISIBLE;
434 		case tcu::WINDOWVISIBILITY_FULLSCREEN:	return WindowParams::VISIBILITY_FULLSCREEN;
435 		case tcu::WINDOWVISIBILITY_HIDDEN:		return WindowParams::VISIBILITY_HIDDEN;
436 
437 		default:
438 			DE_ASSERT(false);
439 			return WindowParams::VISIBILITY_DONT_CARE;
440 	}
441 }
442 
parseWindowVisibility(const tcu::CommandLine & commandLine)443 WindowParams::Visibility parseWindowVisibility (const tcu::CommandLine& commandLine)
444 {
445 	return getWindowVisibility(commandLine.getVisibility());
446 }
447 
parseClientAPI(const std::string & api)448 EGLenum parseClientAPI (const std::string& api)
449 {
450 	if (api == "OpenGL")
451 		return EGL_OPENGL_API;
452 	else if (api == "OpenGL_ES")
453 		return EGL_OPENGL_ES_API;
454 	else if (api == "OpenVG")
455 		return EGL_OPENVG_API;
456 	else
457 		throw tcu::InternalError("Unknown EGL client API '" + api + "'");
458 }
459 
parseClientAPIs(const std::string & apiList)460 vector<EGLenum> parseClientAPIs (const std::string& apiList)
461 {
462 	const vector<string>	apiStrs	= de::splitString(apiList, ' ');
463 	vector<EGLenum>			apis;
464 
465 	for (vector<string>::const_iterator api = apiStrs.begin(); api != apiStrs.end(); ++api)
466 		apis.push_back(parseClientAPI(*api));
467 
468 	return apis;
469 }
470 
getClientAPIs(const eglw::Library & egl,eglw::EGLDisplay display)471 vector<EGLenum> getClientAPIs (const eglw::Library& egl, eglw::EGLDisplay display)
472 {
473 	return parseClientAPIs(egl.queryString(display, EGL_CLIENT_APIS));
474 }
475 
getRenderableAPIsMask(const eglw::Library & egl,eglw::EGLDisplay display)476 EGLint getRenderableAPIsMask (const eglw::Library& egl, eglw::EGLDisplay display)
477 {
478 	const vector<EGLConfig>	configs	= getConfigs(egl, display);
479 	EGLint					allAPIs	= 0;
480 
481 	for (vector<EGLConfig>::const_iterator i = configs.begin(); i != configs.end(); ++i)
482 		allAPIs |= getConfigAttribInt(egl, display, *i, EGL_RENDERABLE_TYPE);
483 
484 	return allAPIs;
485 }
486 
toLegacyAttribList(const EGLAttrib * attribs)487 vector<EGLint> toLegacyAttribList (const EGLAttrib* attribs)
488 {
489 	const deUint64	attribMask		= 0xffffffffull;	//!< Max bits that can be used
490 	vector<EGLint>	legacyAttribs;
491 
492 	if (attribs)
493 	{
494 		for (const EGLAttrib* attrib = attribs; *attrib != EGL_NONE; attrib += 2)
495 		{
496 			if ((attrib[0] & ~attribMask) || (attrib[1] & ~attribMask))
497 				throw tcu::InternalError("Failed to translate EGLAttrib to EGLint", DE_NULL, __FILE__, __LINE__);
498 
499 			legacyAttribs.push_back((EGLint)attrib[0]);
500 			legacyAttribs.push_back((EGLint)attrib[1]);
501 		}
502 	}
503 
504 	legacyAttribs.push_back(EGL_NONE);
505 
506 	return legacyAttribs;
507 }
508 
509 template<typename Factory>
selectFactory(const tcu::FactoryRegistry<Factory> & registry,const char * objectTypeName,const char * cmdLineArg)510 static const Factory& selectFactory (const tcu::FactoryRegistry<Factory>& registry, const char* objectTypeName, const char* cmdLineArg)
511 {
512 	if (cmdLineArg)
513 	{
514 		const Factory* factory = registry.getFactoryByName(cmdLineArg);
515 
516 		if (factory)
517 			return *factory;
518 		else
519 		{
520 			tcu::print("ERROR: Unknown or unsupported EGL %s type '%s'", objectTypeName, cmdLineArg);
521 			tcu::print("Available EGL %s types:\n", objectTypeName);
522 			for (size_t ndx = 0; ndx < registry.getFactoryCount(); ndx++)
523 				tcu::print("  %s: %s\n", registry.getFactoryByIndex(ndx)->getName(), registry.getFactoryByIndex(ndx)->getDescription());
524 
525 			TCU_THROW(NotSupportedError, (string("Unsupported or unknown EGL ") + objectTypeName + " type '" + cmdLineArg + "'").c_str());
526 		}
527 	}
528 	else if (!registry.empty())
529 		return *registry.getDefaultFactory();
530 	else
531 		TCU_THROW(NotSupportedError, (string("No factory supporting EGL '") + objectTypeName + "' type").c_str());
532 }
533 
selectNativeDisplayFactory(const NativeDisplayFactoryRegistry & registry,const tcu::CommandLine & cmdLine)534 const NativeDisplayFactory& selectNativeDisplayFactory (const NativeDisplayFactoryRegistry& registry, const tcu::CommandLine& cmdLine)
535 {
536 	return selectFactory(registry, "display", cmdLine.getEGLDisplayType());
537 }
538 
selectNativeWindowFactory(const NativeDisplayFactory & factory,const tcu::CommandLine & cmdLine)539 const NativeWindowFactory& selectNativeWindowFactory (const NativeDisplayFactory& factory, const tcu::CommandLine& cmdLine)
540 {
541 	return selectFactory(factory.getNativeWindowRegistry(), "window", cmdLine.getEGLWindowType());
542 }
543 
selectNativePixmapFactory(const NativeDisplayFactory & factory,const tcu::CommandLine & cmdLine)544 const NativePixmapFactory& selectNativePixmapFactory (const NativeDisplayFactory& factory, const tcu::CommandLine& cmdLine)
545 {
546 	return selectFactory(factory.getNativePixmapRegistry(), "pixmap", cmdLine.getEGLPixmapType());
547 }
548 
549 } // eglu
550