13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Tester Core
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ----------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief GL context factory using EGL.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "egluGLContextFactory.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuPlatform.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuCommandLine.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluDefs.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "egluDefs.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "egluUtil.hpp"
3453365959f2740e7b9ed59c51adbb73372f908a09Mika Isojärvi#include "egluGLUtil.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "egluNativeWindow.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "egluNativePixmap.hpp"
371bdf526ea422474296d2b88392e8f24dd4f31a99Pyry Haulos#include "egluStrUtil.hpp"
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
393c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos#include "eglwLibrary.hpp"
403c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos#include "eglwEnums.hpp"
413c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwInitFunctions.hpp"
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwInitES20Direct.hpp"
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwInitES30Direct.hpp"
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deDynamicLibrary.hpp"
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deSTLUtil.hpp"
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <string>
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <string>
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <sstream>
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \todo [2014-03-12 pyry] Use command line arguments for libraries?
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Default library names
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if !defined(DEQP_GLES2_LIBRARY_PATH)
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#	if (DE_OS == DE_OS_WIN32)
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#		define DEQP_GLES2_LIBRARY_PATH "libGLESv2.dll"
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#	else
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#		define DEQP_GLES2_LIBRARY_PATH "libGLESv2.so"
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#	endif
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if !defined(DEQP_GLES3_LIBRARY_PATH)
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#	define DEQP_GLES3_LIBRARY_PATH DEQP_GLES2_LIBRARY_PATH
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if !defined(DEQP_OPENGL_LIBRARY_PATH)
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#	if (DE_OS == DE_OS_WIN32)
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#		define DEQP_OPENGL_LIBRARY_PATH "opengl32.dll"
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#	else
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#		define DEQP_OPENGL_LIBRARY_PATH "libGL.so"
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#	endif
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace eglu
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
823c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulosusing namespace eglw;
833c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DEFAULT_OFFSCREEN_WIDTH		= 512,
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DEFAULT_OFFSCREEN_HEIGHT	= 512
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GetProcFuncLoader : public glw::FunctionLoader
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
963c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	GetProcFuncLoader (const Library& egl)
973c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		: m_egl(egl)
983c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	{
993c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	}
1003c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glw::GenericFuncType get (const char* name) const
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1033c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		return (glw::GenericFuncType)m_egl.getProcAddress(name);
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1053c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos
1063c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulosprotected:
1073c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	const Library& m_egl;
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass DynamicFuncLoader : public glw::FunctionLoader
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DynamicFuncLoader	(de::DynamicLibrary* library)
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: m_library(library)
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glw::GenericFuncType get (const char* name) const
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return (glw::GenericFuncType)m_library->getFunction(name);
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::DynamicLibrary*	m_library;
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass RenderContext : public GLRenderContext
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										RenderContext			(const NativeDisplayFactory* displayFactory, const NativeWindowFactory* windowFactory, const NativePixmapFactory* pixmapFactory, const glu::RenderConfig& config);
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual								~RenderContext			(void);
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
133217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos	virtual glu::ContextType			getType					(void) const { return m_renderConfig.type;	}
134217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos	virtual const glw::Functions&		getFunctions			(void) const { return m_glFunctions;		}
135217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos	virtual const tcu::RenderTarget&	getRenderTarget			(void) const { return m_glRenderTarget;		}
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void						postIterate				(void);
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
138217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos	virtual EGLDisplay					getEGLDisplay			(void) const { return m_eglDisplay;			}
139217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos	virtual EGLContext					getEGLContext			(void) const { return m_eglContext;			}
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void								create					(const NativeDisplayFactory* displayFactory, const NativeWindowFactory* windowFactory, const NativePixmapFactory* pixmapFactory, const glu::RenderConfig& config);
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void								destroy					(void);
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
145217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos	const glu::RenderConfig				m_renderConfig;
146217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos	const NativeWindowFactory* const	m_nativeWindowFactory;	// Stored in case window must be re-created
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	NativeDisplay*						m_display;
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	NativeWindow*						m_window;
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	NativePixmap*						m_pixmap;
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	EGLDisplay							m_eglDisplay;
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	EGLConfig							m_eglConfig;
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	EGLSurface							m_eglSurface;
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	EGLContext							m_eglContext;
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::RenderTarget					m_glRenderTarget;
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::DynamicLibrary*					m_dynamicGLLibrary;
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glw::Functions						m_glFunctions;
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1623c827367444ee418f129b2c238299f49d3264554Jarkko PoyryRenderContext::RenderContext (const NativeDisplayFactory* displayFactory, const NativeWindowFactory* windowFactory, const NativePixmapFactory* pixmapFactory, const glu::RenderConfig& config)
163217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos	: m_renderConfig		(config)
164217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos	, m_nativeWindowFactory	(windowFactory)
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_display				(DE_NULL)
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_window				(DE_NULL)
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_pixmap				(DE_NULL)
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_eglDisplay			(EGL_NO_DISPLAY)
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_eglSurface			(EGL_NO_SURFACE)
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_eglContext			(EGL_NO_CONTEXT)
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_dynamicGLLibrary	(DE_NULL)
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(displayFactory);
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		create(displayFactory, windowFactory, pixmapFactory, config);
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (...)
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		destroy();
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw;
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1883c827367444ee418f129b2c238299f49d3264554Jarkko PoyryRenderContext::~RenderContext(void)
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		destroy();
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (...)
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// destroy() calls EGL functions that are checked and may throw exceptions
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_window;
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_pixmap;
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_display;
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_dynamicGLLibrary;
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic WindowParams::Visibility getNativeWindowVisibility (glu::RenderConfig::Visibility visibility)
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using glu::RenderConfig;
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (visibility)
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case RenderConfig::VISIBILITY_HIDDEN:		return WindowParams::VISIBILITY_HIDDEN;
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case RenderConfig::VISIBILITY_VISIBLE:		return WindowParams::VISIBILITY_VISIBLE;
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case RenderConfig::VISIBILITY_FULLSCREEN:	return WindowParams::VISIBILITY_FULLSCREEN;
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
21524ceed3e1acf66512ee25ee75002198b6672879dJarkko Pöyry			DE_ASSERT((int)visibility == RenderConfig::DONT_CARE);
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return WindowParams::VISIBILITY_DONT_CARE;
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef std::pair<NativeWindow*, EGLSurface> WindowSurfacePair;
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef std::pair<NativePixmap*, EGLSurface> PixmapSurfacePair;
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2233c827367444ee418f129b2c238299f49d3264554Jarkko PoyryWindowSurfacePair createWindow (NativeDisplay* nativeDisplay, const NativeWindowFactory* windowFactory, EGLDisplay eglDisplay, EGLConfig eglConfig, const glu::RenderConfig& config)
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						width			= (config.width		== glu::RenderConfig::DONT_CARE ? WindowParams::SIZE_DONT_CARE	: config.width);
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						height			= (config.height	== glu::RenderConfig::DONT_CARE ? WindowParams::SIZE_DONT_CARE	: config.height);
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const WindowParams::Visibility	visibility		= getNativeWindowVisibility(config.windowVisibility);
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	NativeWindow*					nativeWindow	= DE_NULL;
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	EGLSurface						surface			= EGL_NO_SURFACE;
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const EGLAttrib					attribList[]	= { EGL_NONE };
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	nativeWindow = windowFactory->createWindow(nativeDisplay, eglDisplay, eglConfig, &attribList[0], WindowParams(width, height, visibility));
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		surface = eglu::createWindowSurface(*nativeDisplay, *nativeWindow, eglDisplay, eglConfig, attribList);
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (...)
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete nativeWindow;
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw;
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return WindowSurfacePair(nativeWindow, surface);
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2473c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPixmapSurfacePair createPixmap (NativeDisplay* nativeDisplay, const NativePixmapFactory* pixmapFactory, EGLDisplay eglDisplay, EGLConfig eglConfig, const glu::RenderConfig& config)
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			width			= (config.width		== glu::RenderConfig::DONT_CARE ? DEFAULT_OFFSCREEN_WIDTH	: config.width);
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			height			= (config.height	== glu::RenderConfig::DONT_CARE ? DEFAULT_OFFSCREEN_HEIGHT	: config.height);
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	NativePixmap*		nativePixmap	= DE_NULL;
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	EGLSurface			surface			= EGL_NO_SURFACE;
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const EGLAttrib		attribList[]	= { EGL_NONE };
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	nativePixmap = pixmapFactory->createPixmap(nativeDisplay, eglDisplay, eglConfig, &attribList[0], width, height);
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		surface = eglu::createPixmapSurface(*nativeDisplay, *nativePixmap, eglDisplay, eglConfig, attribList);
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (...)
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete nativePixmap;
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw;
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return PixmapSurfacePair(nativePixmap, surface);
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2703c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry HaulosEGLSurface createPBuffer (const Library& egl, EGLDisplay display, EGLConfig eglConfig, const glu::RenderConfig& config)
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		width			= (config.width		== glu::RenderConfig::DONT_CARE ? DEFAULT_OFFSCREEN_WIDTH	: config.width);
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		height			= (config.height	== glu::RenderConfig::DONT_CARE ? DEFAULT_OFFSCREEN_HEIGHT	: config.height);
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	EGLSurface		surface;
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const EGLint	attribList[]	=
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		EGL_WIDTH,	width,
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		EGL_HEIGHT,	height,
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		EGL_NONE
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2823c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	surface = egl.createPbufferSurface(display, eglConfig, &(attribList[0]));
2833c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	EGLU_CHECK_MSG(egl, "eglCreatePbufferSurface()");
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return surface;
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid RenderContext::create (const NativeDisplayFactory* displayFactory, const NativeWindowFactory* windowFactory, const NativePixmapFactory* pixmapFactory, const glu::RenderConfig& config)
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::RenderConfig::SurfaceType	surfaceType	= config.surfaceType;
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(displayFactory);
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_display		= displayFactory->createDisplay();
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_eglDisplay	= eglu::getDisplay(*m_display);
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2973c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	const Library& egl = m_display->getLibrary();
2983c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		EGLint major = 0;
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		EGLint minor = 0;
3023c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		EGLU_CHECK_CALL(egl, initialize(m_eglDisplay, &major, &minor));
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3053c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	m_eglConfig	= chooseConfig(egl, m_eglDisplay, config);
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (surfaceType == glu::RenderConfig::SURFACETYPE_DONT_CARE)
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Choose based on what selected configuration supports
3103c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		const EGLint supportedTypes = eglu::getConfigAttribInt(egl, m_eglDisplay, m_eglConfig, EGL_SURFACE_TYPE);
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if ((supportedTypes & EGL_WINDOW_BIT) != 0)
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			surfaceType = glu::RenderConfig::SURFACETYPE_WINDOW;
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if ((supportedTypes & EGL_PBUFFER_BIT) != 0)
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			surfaceType = glu::RenderConfig::SURFACETYPE_OFFSCREEN_GENERIC;
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if ((supportedTypes & EGL_PIXMAP_BIT) != 0)
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			surfaceType = glu::RenderConfig::SURFACETYPE_OFFSCREEN_NATIVE;
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError("Selected EGL config doesn't support any surface types", DE_NULL, __FILE__, __LINE__);
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (surfaceType)
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::RenderConfig::SURFACETYPE_WINDOW:
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (windowFactory)
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const WindowSurfacePair windowSurface = createWindow(m_display, windowFactory, m_eglDisplay, m_eglConfig, config);
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_window		= windowSurface.first;
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_eglSurface	= windowSurface.second;
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				throw tcu::NotSupportedError("EGL platform doesn't support windows", DE_NULL, __FILE__, __LINE__);
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::RenderConfig::SURFACETYPE_OFFSCREEN_NATIVE:
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (pixmapFactory)
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const PixmapSurfacePair pixmapSurface = createPixmap(m_display, pixmapFactory, m_eglDisplay, m_eglConfig, config);
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_pixmap		= pixmapSurface.first;
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_eglSurface	= pixmapSurface.second;
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				throw tcu::NotSupportedError("EGL platform doesn't support pixmaps", DE_NULL, __FILE__, __LINE__);
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::RenderConfig::SURFACETYPE_OFFSCREEN_GENERIC:
3513c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos			m_eglSurface = createPBuffer(egl, m_eglDisplay, m_eglConfig, config);
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::InternalError("Invalid surface type");
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3583c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	m_eglContext = createGLContext(egl, m_eglDisplay, m_eglConfig, config.type);
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3603c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext));
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
362ade588f3b2b1b6d007b9681e95434dc4a4bd46caJarkko Pöyry	// Init core functions
363ade588f3b2b1b6d007b9681e95434dc4a4bd46caJarkko Pöyry
3643c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	if (hasExtension(egl, m_eglDisplay, "EGL_KHR_get_all_proc_addresses"))
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
366ade588f3b2b1b6d007b9681e95434dc4a4bd46caJarkko Pöyry		// Use eglGetProcAddress() for core functions
3673c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		GetProcFuncLoader funcLoader(egl);
368ade588f3b2b1b6d007b9681e95434dc4a4bd46caJarkko Pöyry		glu::initCoreFunctions(&m_glFunctions, &funcLoader, config.type.getAPI());
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if !defined(DEQP_GLES2_RUNTIME_LOAD)
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (config.type.getAPI() == glu::ApiType::es(2,0))
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glw::initES20Direct(&m_glFunctions);
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if !defined(DEQP_GLES3_RUNTIME_LOAD)
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (config.type.getAPI() == glu::ApiType::es(3,0))
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glw::initES30Direct(&m_glFunctions);
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char* libraryPath = DE_NULL;
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isContextTypeES(config.type))
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (config.type.getMinorVersion() <= 2)
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				libraryPath = DEQP_GLES2_LIBRARY_PATH;
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				libraryPath = DEQP_GLES3_LIBRARY_PATH;
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			libraryPath = DEQP_OPENGL_LIBRARY_PATH;
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_dynamicGLLibrary = new de::DynamicLibrary(libraryPath);
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DynamicFuncLoader funcLoader(m_dynamicGLLibrary);
399ade588f3b2b1b6d007b9681e95434dc4a4bd46caJarkko Pöyry		glu::initCoreFunctions(&m_glFunctions, &funcLoader, config.type.getAPI());
400ade588f3b2b1b6d007b9681e95434dc4a4bd46caJarkko Pöyry	}
401ade588f3b2b1b6d007b9681e95434dc4a4bd46caJarkko Pöyry
402ade588f3b2b1b6d007b9681e95434dc4a4bd46caJarkko Pöyry	// Init extension functions
403ade588f3b2b1b6d007b9681e95434dc4a4bd46caJarkko Pöyry	{
4043c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		GetProcFuncLoader extLoader(egl);
405ade588f3b2b1b6d007b9681e95434dc4a4bd46caJarkko Pöyry		glu::initExtensionFunctions(&m_glFunctions, &extLoader, config.type.getAPI());
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		EGLint				width, height, depthBits, stencilBits, numSamples;
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::PixelFormat	pixelFmt;
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4123c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		egl.querySurface(m_eglDisplay, m_eglSurface, EGL_WIDTH,		&width);
4133c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		egl.querySurface(m_eglDisplay, m_eglSurface, EGL_HEIGHT,	&height);
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4153c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		egl.getConfigAttrib(m_eglDisplay, m_eglConfig, EGL_RED_SIZE,		&pixelFmt.redBits);
4163c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		egl.getConfigAttrib(m_eglDisplay, m_eglConfig, EGL_GREEN_SIZE,		&pixelFmt.greenBits);
4173c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		egl.getConfigAttrib(m_eglDisplay, m_eglConfig, EGL_BLUE_SIZE,		&pixelFmt.blueBits);
4183c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		egl.getConfigAttrib(m_eglDisplay, m_eglConfig, EGL_ALPHA_SIZE,		&pixelFmt.alphaBits);
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4203c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		egl.getConfigAttrib(m_eglDisplay, m_eglConfig, EGL_DEPTH_SIZE,		&depthBits);
4213c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		egl.getConfigAttrib(m_eglDisplay, m_eglConfig, EGL_STENCIL_SIZE,	&stencilBits);
4223c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		egl.getConfigAttrib(m_eglDisplay, m_eglConfig, EGL_SAMPLES,			&numSamples);
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4243c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		EGLU_CHECK_MSG(egl, "Failed to query config attributes");
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_glRenderTarget = tcu::RenderTarget(width, height, pixelFmt, depthBits, stencilBits, numSamples);
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid RenderContext::destroy (void)
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4323c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	const Library& egl = m_display->getLibrary();
4333c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_eglDisplay != EGL_NO_DISPLAY)
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4363c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_eglSurface != EGL_NO_SURFACE)
4393c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos			EGLU_CHECK_CALL(egl, destroySurface(m_eglDisplay, m_eglSurface));
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_eglContext != EGL_NO_CONTEXT)
4423c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos			EGLU_CHECK_CALL(egl, destroyContext(m_eglDisplay, m_eglContext));
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4443c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		EGLU_CHECK_CALL(egl, terminate(m_eglDisplay));
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_eglDisplay	= EGL_NO_DISPLAY;
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_eglSurface	= EGL_NO_SURFACE;
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_eglContext	= EGL_NO_CONTEXT;
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_window;
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_pixmap;
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_display;
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_dynamicGLLibrary;
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_window			= DE_NULL;
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_pixmap			= DE_NULL;
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_display			= DE_NULL;
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_dynamicGLLibrary	= DE_NULL;
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid RenderContext::postIterate (void)
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4643c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	const Library& egl = m_display->getLibrary();
4653c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_window)
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4683c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		EGLBoolean	swapOk		= egl.swapBuffers(m_eglDisplay, m_eglSurface);
4693c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		EGLint		error		= egl.getError();
4701bdf526ea422474296d2b88392e8f24dd4f31a99Pyry Haulos		const bool	badWindow	= error == EGL_BAD_SURFACE || error == EGL_BAD_NATIVE_WINDOW;
471217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos
4721bdf526ea422474296d2b88392e8f24dd4f31a99Pyry Haulos		if (!swapOk && !badWindow)
4731bdf526ea422474296d2b88392e8f24dd4f31a99Pyry Haulos			throw tcu::ResourceError(string("eglSwapBuffers() failed: ") + getErrorStr(error).toString());
474217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos
475217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos		try
476217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos		{
477217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos			m_window->processEvents();
478217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos		}
479217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos		catch (const WindowDestroyedError&)
480217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos		{
481217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos			tcu::print("Warning: Window destroyed, recreating...\n");
482217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos
4833c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos			EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
4843c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos			EGLU_CHECK_CALL(egl, destroySurface(m_eglDisplay, m_eglSurface));
485217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos			m_eglSurface = EGL_NO_SURFACE;
486217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos
487217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos			delete m_window;
488217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos			m_window = DE_NULL;
489217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos
490217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos			try
491217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos			{
492217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos				WindowSurfacePair windowSurface = createWindow(m_display, m_nativeWindowFactory, m_eglDisplay, m_eglConfig, m_renderConfig);
493217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos				m_window		= windowSurface.first;
494217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos				m_eglSurface	= windowSurface.second;
495217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos
4963c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos				EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext));
497217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos
498217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos				swapOk	= EGL_TRUE;
499217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos				error	= EGL_SUCCESS;
500217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos			}
501217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos			catch (const std::exception& e)
502217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos			{
503217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos				if (m_eglSurface)
504217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos				{
5053c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos					egl.makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
5063c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos					egl.destroySurface(m_eglDisplay, m_eglSurface);
507217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos					m_eglSurface = EGL_NO_SURFACE;
508217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos				}
509217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos
510217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos				delete m_window;
511217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos				m_window = DE_NULL;
512217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos
513217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos				throw tcu::ResourceError(string("Failed to re-create window: ") + e.what());
514217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos			}
515217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos		}
516217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos
517217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos		if (!swapOk)
518217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos		{
5191bdf526ea422474296d2b88392e8f24dd4f31a99Pyry Haulos			DE_ASSERT(badWindow);
5201bdf526ea422474296d2b88392e8f24dd4f31a99Pyry Haulos			throw tcu::ResourceError(string("eglSwapBuffers() failed: ") + getErrorStr(error).toString());
521217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos		}
522217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos
523217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos		// Refresh dimensions
524217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos		{
525217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos			int	newWidth	= 0;
526217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos			int	newHeight	= 0;
527217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos
5283c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos			egl.querySurface(m_eglDisplay, m_eglSurface, EGL_WIDTH,		&newWidth);
5293c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos			egl.querySurface(m_eglDisplay, m_eglSurface, EGL_HEIGHT,	&newHeight);
5303c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos			EGLU_CHECK_MSG(egl, "Failed to query window size");
531217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos
532217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos			if (newWidth	!= m_glRenderTarget.getWidth() ||
533217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos				newHeight	!= m_glRenderTarget.getHeight())
534217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos			{
535217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos				tcu::print("Warning: Window size changed (%dx%d -> %dx%d), test results might be invalid!\n",
536217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos						   m_glRenderTarget.getWidth(), m_glRenderTarget.getHeight(), newWidth, newHeight);
537217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos
538217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos				m_glRenderTarget = tcu::RenderTarget(newWidth, newHeight,
539217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos													 m_glRenderTarget.getPixelFormat(),
540217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos													 m_glRenderTarget.getDepthBits(),
541217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos													 m_glRenderTarget.getStencilBits(),
542217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos													 m_glRenderTarget.getNumSamples());
543217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos			}
544217426c2d19d5247e094e363615d7a0b84daf3a7Pyry Haulos		}
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_glFunctions.flush();
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5523c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGLContextFactory::GLContextFactory (const NativeDisplayFactoryRegistry& displayFactoryRegistry)
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: glu::ContextFactory		("egl", "EGL OpenGL Context")
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_displayFactoryRegistry	(displayFactoryRegistry)
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglu::RenderContext* GLContextFactory::createContext (const glu::RenderConfig& config, const tcu::CommandLine& cmdLine) const
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
560485844e764f2821545146b832726a36012f86238Mika Isojärvi	const NativeDisplayFactory& displayFactory = selectNativeDisplayFactory(m_displayFactoryRegistry, cmdLine);
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
562485844e764f2821545146b832726a36012f86238Mika Isojärvi	const NativeWindowFactory*	windowFactory;
563485844e764f2821545146b832726a36012f86238Mika Isojärvi	const NativePixmapFactory*	pixmapFactory;
564485844e764f2821545146b832726a36012f86238Mika Isojärvi
565485844e764f2821545146b832726a36012f86238Mika Isojärvi	try
566485844e764f2821545146b832726a36012f86238Mika Isojärvi	{
567485844e764f2821545146b832726a36012f86238Mika Isojärvi		windowFactory = &selectNativeWindowFactory(displayFactory, cmdLine);
568485844e764f2821545146b832726a36012f86238Mika Isojärvi	}
569485844e764f2821545146b832726a36012f86238Mika Isojärvi	catch (const tcu::NotSupportedError&)
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
571485844e764f2821545146b832726a36012f86238Mika Isojärvi		windowFactory = DE_NULL;
572485844e764f2821545146b832726a36012f86238Mika Isojärvi	}
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
574485844e764f2821545146b832726a36012f86238Mika Isojärvi	try
575485844e764f2821545146b832726a36012f86238Mika Isojärvi	{
576485844e764f2821545146b832726a36012f86238Mika Isojärvi		pixmapFactory = &selectNativePixmapFactory(displayFactory, cmdLine);
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
578485844e764f2821545146b832726a36012f86238Mika Isojärvi	catch (const tcu::NotSupportedError&)
579485844e764f2821545146b832726a36012f86238Mika Isojärvi	{
580485844e764f2821545146b832726a36012f86238Mika Isojärvi		pixmapFactory = DE_NULL;
581485844e764f2821545146b832726a36012f86238Mika Isojärvi	}
582485844e764f2821545146b832726a36012f86238Mika Isojärvi
583485844e764f2821545146b832726a36012f86238Mika Isojärvi	return new RenderContext(&displayFactory, windowFactory, pixmapFactory, config);
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // eglu
587