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 GL context factory using EGL.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "egluGLContextFactory.hpp"
25 
26 #include "tcuRenderTarget.hpp"
27 #include "tcuPlatform.hpp"
28 #include "tcuCommandLine.hpp"
29 
30 #include "gluDefs.hpp"
31 
32 #include "egluDefs.hpp"
33 #include "egluUtil.hpp"
34 #include "egluGLUtil.hpp"
35 #include "egluNativeWindow.hpp"
36 #include "egluNativePixmap.hpp"
37 #include "egluStrUtil.hpp"
38 
39 #include "eglwLibrary.hpp"
40 #include "eglwEnums.hpp"
41 
42 #include "glwInitFunctions.hpp"
43 #include "glwInitES20Direct.hpp"
44 #include "glwInitES30Direct.hpp"
45 
46 #include "deDynamicLibrary.hpp"
47 #include "deSTLUtil.hpp"
48 
49 #include <string>
50 #include <string>
51 #include <sstream>
52 
53 using std::string;
54 using std::vector;
55 
56 // \todo [2014-03-12 pyry] Use command line arguments for libraries?
57 
58 // Default library names
59 #if !defined(DEQP_GLES2_LIBRARY_PATH)
60 #	if (DE_OS == DE_OS_WIN32)
61 #		define DEQP_GLES2_LIBRARY_PATH "libGLESv2.dll"
62 #	else
63 #		define DEQP_GLES2_LIBRARY_PATH "libGLESv2.so"
64 #	endif
65 #endif
66 
67 #if !defined(DEQP_GLES3_LIBRARY_PATH)
68 #	define DEQP_GLES3_LIBRARY_PATH DEQP_GLES2_LIBRARY_PATH
69 #endif
70 
71 #if !defined(DEQP_OPENGL_LIBRARY_PATH)
72 #	if (DE_OS == DE_OS_WIN32)
73 #		define DEQP_OPENGL_LIBRARY_PATH "opengl32.dll"
74 #	else
75 #		define DEQP_OPENGL_LIBRARY_PATH "libGL.so"
76 #	endif
77 #endif
78 
79 namespace eglu
80 {
81 
82 using namespace eglw;
83 
84 namespace
85 {
86 
87 enum
88 {
89 	DEFAULT_OFFSCREEN_WIDTH		= 512,
90 	DEFAULT_OFFSCREEN_HEIGHT	= 512
91 };
92 
93 class GetProcFuncLoader : public glw::FunctionLoader
94 {
95 public:
GetProcFuncLoader(const Library & egl)96 	GetProcFuncLoader (const Library& egl)
97 		: m_egl(egl)
98 	{
99 	}
100 
get(const char * name) const101 	glw::GenericFuncType get (const char* name) const
102 	{
103 		return (glw::GenericFuncType)m_egl.getProcAddress(name);
104 	}
105 
106 protected:
107 	const Library& m_egl;
108 };
109 
110 class DynamicFuncLoader : public glw::FunctionLoader
111 {
112 public:
DynamicFuncLoader(de::DynamicLibrary * library)113 	DynamicFuncLoader	(de::DynamicLibrary* library)
114 		: m_library(library)
115 	{
116 	}
117 
get(const char * name) const118 	glw::GenericFuncType get (const char* name) const
119 	{
120 		return (glw::GenericFuncType)m_library->getFunction(name);
121 	}
122 
123 private:
124 	de::DynamicLibrary*	m_library;
125 };
126 
127 class RenderContext : public GLRenderContext
128 {
129 public:
130 										RenderContext			(const NativeDisplayFactory* displayFactory, const NativeWindowFactory* windowFactory, const NativePixmapFactory* pixmapFactory, const glu::RenderConfig& config);
131 	virtual								~RenderContext			(void);
132 
getType(void) const133 	virtual glu::ContextType			getType					(void) const { return m_renderConfig.type;	}
getFunctions(void) const134 	virtual const glw::Functions&		getFunctions			(void) const { return m_glFunctions;		}
getRenderTarget(void) const135 	virtual const tcu::RenderTarget&	getRenderTarget			(void) const { return m_glRenderTarget;		}
136 	virtual void						postIterate				(void);
137 
getEGLDisplay(void) const138 	virtual EGLDisplay					getEGLDisplay			(void) const { return m_eglDisplay;			}
getEGLContext(void) const139 	virtual EGLContext					getEGLContext			(void) const { return m_eglContext;			}
140 
141 private:
142 	void								create					(const NativeDisplayFactory* displayFactory, const NativeWindowFactory* windowFactory, const NativePixmapFactory* pixmapFactory, const glu::RenderConfig& config);
143 	void								destroy					(void);
144 
145 	const glu::RenderConfig				m_renderConfig;
146 	const NativeWindowFactory* const	m_nativeWindowFactory;	// Stored in case window must be re-created
147 
148 	NativeDisplay*						m_display;
149 	NativeWindow*						m_window;
150 	NativePixmap*						m_pixmap;
151 
152 	EGLDisplay							m_eglDisplay;
153 	EGLConfig							m_eglConfig;
154 	EGLSurface							m_eglSurface;
155 	EGLContext							m_eglContext;
156 
157 	tcu::RenderTarget					m_glRenderTarget;
158 	de::DynamicLibrary*					m_dynamicGLLibrary;
159 	glw::Functions						m_glFunctions;
160 };
161 
RenderContext(const NativeDisplayFactory * displayFactory,const NativeWindowFactory * windowFactory,const NativePixmapFactory * pixmapFactory,const glu::RenderConfig & config)162 RenderContext::RenderContext (const NativeDisplayFactory* displayFactory, const NativeWindowFactory* windowFactory, const NativePixmapFactory* pixmapFactory, const glu::RenderConfig& config)
163 	: m_renderConfig		(config)
164 	, m_nativeWindowFactory	(windowFactory)
165 	, m_display				(DE_NULL)
166 	, m_window				(DE_NULL)
167 	, m_pixmap				(DE_NULL)
168 
169 	, m_eglDisplay			(EGL_NO_DISPLAY)
170 	, m_eglSurface			(EGL_NO_SURFACE)
171 	, m_eglContext			(EGL_NO_CONTEXT)
172 
173 	, m_dynamicGLLibrary	(DE_NULL)
174 {
175 	DE_ASSERT(displayFactory);
176 
177 	try
178 	{
179 		create(displayFactory, windowFactory, pixmapFactory, config);
180 	}
181 	catch (...)
182 	{
183 		destroy();
184 		throw;
185 	}
186 }
187 
~RenderContext(void)188 RenderContext::~RenderContext(void)
189 {
190 	try
191 	{
192 		destroy();
193 	}
194 	catch (...)
195 	{
196 		// destroy() calls EGL functions that are checked and may throw exceptions
197 	}
198 
199 	delete m_window;
200 	delete m_pixmap;
201 	delete m_display;
202 	delete m_dynamicGLLibrary;
203 }
204 
getNativeWindowVisibility(glu::RenderConfig::Visibility visibility)205 static WindowParams::Visibility getNativeWindowVisibility (glu::RenderConfig::Visibility visibility)
206 {
207 	using glu::RenderConfig;
208 
209 	switch (visibility)
210 	{
211 		case RenderConfig::VISIBILITY_HIDDEN:		return WindowParams::VISIBILITY_HIDDEN;
212 		case RenderConfig::VISIBILITY_VISIBLE:		return WindowParams::VISIBILITY_VISIBLE;
213 		case RenderConfig::VISIBILITY_FULLSCREEN:	return WindowParams::VISIBILITY_FULLSCREEN;
214 		default:
215 			DE_ASSERT((int)visibility == RenderConfig::DONT_CARE);
216 			return WindowParams::VISIBILITY_DONT_CARE;
217 	}
218 }
219 
220 typedef std::pair<NativeWindow*, EGLSurface> WindowSurfacePair;
221 typedef std::pair<NativePixmap*, EGLSurface> PixmapSurfacePair;
222 
createWindow(NativeDisplay * nativeDisplay,const NativeWindowFactory * windowFactory,EGLDisplay eglDisplay,EGLConfig eglConfig,const glu::RenderConfig & config)223 WindowSurfacePair createWindow (NativeDisplay* nativeDisplay, const NativeWindowFactory* windowFactory, EGLDisplay eglDisplay, EGLConfig eglConfig, const glu::RenderConfig& config)
224 {
225 	const int						width			= (config.width		== glu::RenderConfig::DONT_CARE ? WindowParams::SIZE_DONT_CARE	: config.width);
226 	const int						height			= (config.height	== glu::RenderConfig::DONT_CARE ? WindowParams::SIZE_DONT_CARE	: config.height);
227 	const WindowParams::Visibility	visibility		= getNativeWindowVisibility(config.windowVisibility);
228 	NativeWindow*					nativeWindow	= DE_NULL;
229 	EGLSurface						surface			= EGL_NO_SURFACE;
230 	const EGLAttrib					attribList[]	= { EGL_NONE };
231 
232 	nativeWindow = windowFactory->createWindow(nativeDisplay, eglDisplay, eglConfig, &attribList[0], WindowParams(width, height, visibility));
233 
234 	try
235 	{
236 		surface = eglu::createWindowSurface(*nativeDisplay, *nativeWindow, eglDisplay, eglConfig, attribList);
237 	}
238 	catch (...)
239 	{
240 		delete nativeWindow;
241 		throw;
242 	}
243 
244 	return WindowSurfacePair(nativeWindow, surface);
245 }
246 
createPixmap(NativeDisplay * nativeDisplay,const NativePixmapFactory * pixmapFactory,EGLDisplay eglDisplay,EGLConfig eglConfig,const glu::RenderConfig & config)247 PixmapSurfacePair createPixmap (NativeDisplay* nativeDisplay, const NativePixmapFactory* pixmapFactory, EGLDisplay eglDisplay, EGLConfig eglConfig, const glu::RenderConfig& config)
248 {
249 	const int			width			= (config.width		== glu::RenderConfig::DONT_CARE ? DEFAULT_OFFSCREEN_WIDTH	: config.width);
250 	const int			height			= (config.height	== glu::RenderConfig::DONT_CARE ? DEFAULT_OFFSCREEN_HEIGHT	: config.height);
251 	NativePixmap*		nativePixmap	= DE_NULL;
252 	EGLSurface			surface			= EGL_NO_SURFACE;
253 	const EGLAttrib		attribList[]	= { EGL_NONE };
254 
255 	nativePixmap = pixmapFactory->createPixmap(nativeDisplay, eglDisplay, eglConfig, &attribList[0], width, height);
256 
257 	try
258 	{
259 		surface = eglu::createPixmapSurface(*nativeDisplay, *nativePixmap, eglDisplay, eglConfig, attribList);
260 	}
261 	catch (...)
262 	{
263 		delete nativePixmap;
264 		throw;
265 	}
266 
267 	return PixmapSurfacePair(nativePixmap, surface);
268 }
269 
createPBuffer(const Library & egl,EGLDisplay display,EGLConfig eglConfig,const glu::RenderConfig & config)270 EGLSurface createPBuffer (const Library& egl, EGLDisplay display, EGLConfig eglConfig, const glu::RenderConfig& config)
271 {
272 	const int		width			= (config.width		== glu::RenderConfig::DONT_CARE ? DEFAULT_OFFSCREEN_WIDTH	: config.width);
273 	const int		height			= (config.height	== glu::RenderConfig::DONT_CARE ? DEFAULT_OFFSCREEN_HEIGHT	: config.height);
274 	EGLSurface		surface;
275 	const EGLint	attribList[]	=
276 	{
277 		EGL_WIDTH,	width,
278 		EGL_HEIGHT,	height,
279 		EGL_NONE
280 	};
281 
282 	surface = egl.createPbufferSurface(display, eglConfig, &(attribList[0]));
283 	EGLU_CHECK_MSG(egl, "eglCreatePbufferSurface()");
284 
285 	return surface;
286 }
287 
create(const NativeDisplayFactory * displayFactory,const NativeWindowFactory * windowFactory,const NativePixmapFactory * pixmapFactory,const glu::RenderConfig & config)288 void RenderContext::create (const NativeDisplayFactory* displayFactory, const NativeWindowFactory* windowFactory, const NativePixmapFactory* pixmapFactory, const glu::RenderConfig& config)
289 {
290 	glu::RenderConfig::SurfaceType	surfaceType	= config.surfaceType;
291 
292 	DE_ASSERT(displayFactory);
293 
294 	m_display		= displayFactory->createDisplay();
295 	m_eglDisplay	= eglu::getDisplay(*m_display);
296 
297 	const Library& egl = m_display->getLibrary();
298 
299 	{
300 		EGLint major = 0;
301 		EGLint minor = 0;
302 		EGLU_CHECK_CALL(egl, initialize(m_eglDisplay, &major, &minor));
303 	}
304 
305 	m_eglConfig	= chooseConfig(egl, m_eglDisplay, config);
306 
307 	if (surfaceType == glu::RenderConfig::SURFACETYPE_DONT_CARE)
308 	{
309 		// Choose based on what selected configuration supports
310 		const EGLint supportedTypes = eglu::getConfigAttribInt(egl, m_eglDisplay, m_eglConfig, EGL_SURFACE_TYPE);
311 
312 		if ((supportedTypes & EGL_WINDOW_BIT) != 0)
313 			surfaceType = glu::RenderConfig::SURFACETYPE_WINDOW;
314 		else if ((supportedTypes & EGL_PBUFFER_BIT) != 0)
315 			surfaceType = glu::RenderConfig::SURFACETYPE_OFFSCREEN_GENERIC;
316 		else if ((supportedTypes & EGL_PIXMAP_BIT) != 0)
317 			surfaceType = glu::RenderConfig::SURFACETYPE_OFFSCREEN_NATIVE;
318 		else
319 			throw tcu::NotSupportedError("Selected EGL config doesn't support any surface types", DE_NULL, __FILE__, __LINE__);
320 	}
321 
322 	switch (surfaceType)
323 	{
324 		case glu::RenderConfig::SURFACETYPE_WINDOW:
325 		{
326 			if (windowFactory)
327 			{
328 				const WindowSurfacePair windowSurface = createWindow(m_display, windowFactory, m_eglDisplay, m_eglConfig, config);
329 				m_window		= windowSurface.first;
330 				m_eglSurface	= windowSurface.second;
331 			}
332 			else
333 				throw tcu::NotSupportedError("EGL platform doesn't support windows", DE_NULL, __FILE__, __LINE__);
334 			break;
335 		}
336 
337 		case glu::RenderConfig::SURFACETYPE_OFFSCREEN_NATIVE:
338 		{
339 			if (pixmapFactory)
340 			{
341 				const PixmapSurfacePair pixmapSurface = createPixmap(m_display, pixmapFactory, m_eglDisplay, m_eglConfig, config);
342 				m_pixmap		= pixmapSurface.first;
343 				m_eglSurface	= pixmapSurface.second;
344 			}
345 			else
346 				throw tcu::NotSupportedError("EGL platform doesn't support pixmaps", DE_NULL, __FILE__, __LINE__);
347 			break;
348 		}
349 
350 		case glu::RenderConfig::SURFACETYPE_OFFSCREEN_GENERIC:
351 			m_eglSurface = createPBuffer(egl, m_eglDisplay, m_eglConfig, config);
352 			break;
353 
354 		default:
355 			throw tcu::InternalError("Invalid surface type");
356 	}
357 
358 	m_eglContext = createGLContext(egl, m_eglDisplay, m_eglConfig, config.type);
359 
360 	EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext));
361 
362 	// Init core functions
363 
364 	if (hasExtension(egl, m_eglDisplay, "EGL_KHR_get_all_proc_addresses"))
365 	{
366 		// Use eglGetProcAddress() for core functions
367 		GetProcFuncLoader funcLoader(egl);
368 		glu::initCoreFunctions(&m_glFunctions, &funcLoader, config.type.getAPI());
369 	}
370 #if !defined(DEQP_GLES2_RUNTIME_LOAD)
371 	else if (config.type.getAPI() == glu::ApiType::es(2,0))
372 	{
373 		glw::initES20Direct(&m_glFunctions);
374 	}
375 #endif
376 #if !defined(DEQP_GLES3_RUNTIME_LOAD)
377 	else if (config.type.getAPI() == glu::ApiType::es(3,0))
378 	{
379 		glw::initES30Direct(&m_glFunctions);
380 	}
381 #endif
382 	else
383 	{
384 		const char* libraryPath = DE_NULL;
385 
386 		if (glu::isContextTypeES(config.type))
387 		{
388 			if (config.type.getMinorVersion() <= 2)
389 				libraryPath = DEQP_GLES2_LIBRARY_PATH;
390 			else
391 				libraryPath = DEQP_GLES3_LIBRARY_PATH;
392 		}
393 		else
394 			libraryPath = DEQP_OPENGL_LIBRARY_PATH;
395 
396 		m_dynamicGLLibrary = new de::DynamicLibrary(libraryPath);
397 
398 		DynamicFuncLoader funcLoader(m_dynamicGLLibrary);
399 		glu::initCoreFunctions(&m_glFunctions, &funcLoader, config.type.getAPI());
400 	}
401 
402 	// Init extension functions
403 	{
404 		GetProcFuncLoader extLoader(egl);
405 		glu::initExtensionFunctions(&m_glFunctions, &extLoader, config.type.getAPI());
406 	}
407 
408 	{
409 		EGLint				width, height, depthBits, stencilBits, numSamples;
410 		tcu::PixelFormat	pixelFmt;
411 
412 		egl.querySurface(m_eglDisplay, m_eglSurface, EGL_WIDTH,		&width);
413 		egl.querySurface(m_eglDisplay, m_eglSurface, EGL_HEIGHT,	&height);
414 
415 		egl.getConfigAttrib(m_eglDisplay, m_eglConfig, EGL_RED_SIZE,		&pixelFmt.redBits);
416 		egl.getConfigAttrib(m_eglDisplay, m_eglConfig, EGL_GREEN_SIZE,		&pixelFmt.greenBits);
417 		egl.getConfigAttrib(m_eglDisplay, m_eglConfig, EGL_BLUE_SIZE,		&pixelFmt.blueBits);
418 		egl.getConfigAttrib(m_eglDisplay, m_eglConfig, EGL_ALPHA_SIZE,		&pixelFmt.alphaBits);
419 
420 		egl.getConfigAttrib(m_eglDisplay, m_eglConfig, EGL_DEPTH_SIZE,		&depthBits);
421 		egl.getConfigAttrib(m_eglDisplay, m_eglConfig, EGL_STENCIL_SIZE,	&stencilBits);
422 		egl.getConfigAttrib(m_eglDisplay, m_eglConfig, EGL_SAMPLES,			&numSamples);
423 
424 		EGLU_CHECK_MSG(egl, "Failed to query config attributes");
425 
426 		m_glRenderTarget = tcu::RenderTarget(width, height, pixelFmt, depthBits, stencilBits, numSamples);
427 	}
428 }
429 
destroy(void)430 void RenderContext::destroy (void)
431 {
432 	const Library& egl = m_display->getLibrary();
433 
434 	if (m_eglDisplay != EGL_NO_DISPLAY)
435 	{
436 		EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
437 
438 		if (m_eglSurface != EGL_NO_SURFACE)
439 			EGLU_CHECK_CALL(egl, destroySurface(m_eglDisplay, m_eglSurface));
440 
441 		if (m_eglContext != EGL_NO_CONTEXT)
442 			EGLU_CHECK_CALL(egl, destroyContext(m_eglDisplay, m_eglContext));
443 
444 		EGLU_CHECK_CALL(egl, terminate(m_eglDisplay));
445 
446 		m_eglDisplay	= EGL_NO_DISPLAY;
447 		m_eglSurface	= EGL_NO_SURFACE;
448 		m_eglContext	= EGL_NO_CONTEXT;
449 	}
450 
451 	delete m_window;
452 	delete m_pixmap;
453 	delete m_display;
454 	delete m_dynamicGLLibrary;
455 
456 	m_window			= DE_NULL;
457 	m_pixmap			= DE_NULL;
458 	m_display			= DE_NULL;
459 	m_dynamicGLLibrary	= DE_NULL;
460 }
461 
postIterate(void)462 void RenderContext::postIterate (void)
463 {
464 	const Library& egl = m_display->getLibrary();
465 
466 	if (m_window)
467 	{
468 		EGLBoolean	swapOk		= egl.swapBuffers(m_eglDisplay, m_eglSurface);
469 		EGLint		error		= egl.getError();
470 		const bool	badWindow	= error == EGL_BAD_SURFACE || error == EGL_BAD_NATIVE_WINDOW;
471 
472 		if (!swapOk && !badWindow)
473 			throw tcu::ResourceError(string("eglSwapBuffers() failed: ") + getErrorStr(error).toString());
474 
475 		try
476 		{
477 			m_window->processEvents();
478 		}
479 		catch (const WindowDestroyedError&)
480 		{
481 			tcu::print("Warning: Window destroyed, recreating...\n");
482 
483 			EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
484 			EGLU_CHECK_CALL(egl, destroySurface(m_eglDisplay, m_eglSurface));
485 			m_eglSurface = EGL_NO_SURFACE;
486 
487 			delete m_window;
488 			m_window = DE_NULL;
489 
490 			try
491 			{
492 				WindowSurfacePair windowSurface = createWindow(m_display, m_nativeWindowFactory, m_eglDisplay, m_eglConfig, m_renderConfig);
493 				m_window		= windowSurface.first;
494 				m_eglSurface	= windowSurface.second;
495 
496 				EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext));
497 
498 				swapOk	= EGL_TRUE;
499 				error	= EGL_SUCCESS;
500 			}
501 			catch (const std::exception& e)
502 			{
503 				if (m_eglSurface)
504 				{
505 					egl.makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
506 					egl.destroySurface(m_eglDisplay, m_eglSurface);
507 					m_eglSurface = EGL_NO_SURFACE;
508 				}
509 
510 				delete m_window;
511 				m_window = DE_NULL;
512 
513 				throw tcu::ResourceError(string("Failed to re-create window: ") + e.what());
514 			}
515 		}
516 
517 		if (!swapOk)
518 		{
519 			DE_ASSERT(badWindow);
520 			throw tcu::ResourceError(string("eglSwapBuffers() failed: ") + getErrorStr(error).toString());
521 		}
522 
523 		// Refresh dimensions
524 		{
525 			int	newWidth	= 0;
526 			int	newHeight	= 0;
527 
528 			egl.querySurface(m_eglDisplay, m_eglSurface, EGL_WIDTH,		&newWidth);
529 			egl.querySurface(m_eglDisplay, m_eglSurface, EGL_HEIGHT,	&newHeight);
530 			EGLU_CHECK_MSG(egl, "Failed to query window size");
531 
532 			if (newWidth	!= m_glRenderTarget.getWidth() ||
533 				newHeight	!= m_glRenderTarget.getHeight())
534 			{
535 				tcu::print("Warning: Window size changed (%dx%d -> %dx%d), test results might be invalid!\n",
536 						   m_glRenderTarget.getWidth(), m_glRenderTarget.getHeight(), newWidth, newHeight);
537 
538 				m_glRenderTarget = tcu::RenderTarget(newWidth, newHeight,
539 													 m_glRenderTarget.getPixelFormat(),
540 													 m_glRenderTarget.getDepthBits(),
541 													 m_glRenderTarget.getStencilBits(),
542 													 m_glRenderTarget.getNumSamples());
543 			}
544 		}
545 	}
546 	else
547 		m_glFunctions.flush();
548 }
549 
550 } // anonymous
551 
GLContextFactory(const NativeDisplayFactoryRegistry & displayFactoryRegistry)552 GLContextFactory::GLContextFactory (const NativeDisplayFactoryRegistry& displayFactoryRegistry)
553 	: glu::ContextFactory		("egl", "EGL OpenGL Context")
554 	, m_displayFactoryRegistry	(displayFactoryRegistry)
555 {
556 }
557 
createContext(const glu::RenderConfig & config,const tcu::CommandLine & cmdLine) const558 glu::RenderContext* GLContextFactory::createContext (const glu::RenderConfig& config, const tcu::CommandLine& cmdLine) const
559 {
560 	const NativeDisplayFactory& displayFactory = selectNativeDisplayFactory(m_displayFactoryRegistry, cmdLine);
561 
562 	const NativeWindowFactory*	windowFactory;
563 	const NativePixmapFactory*	pixmapFactory;
564 
565 	try
566 	{
567 		windowFactory = &selectNativeWindowFactory(displayFactory, cmdLine);
568 	}
569 	catch (const tcu::NotSupportedError&)
570 	{
571 		windowFactory = DE_NULL;
572 	}
573 
574 	try
575 	{
576 		pixmapFactory = &selectNativePixmapFactory(displayFactory, cmdLine);
577 	}
578 	catch (const tcu::NotSupportedError&)
579 	{
580 		pixmapFactory = DE_NULL;
581 	}
582 
583 	return new RenderContext(&displayFactory, windowFactory, pixmapFactory, config);
584 }
585 
586 } // eglu
587