Home | History | Annotate | Download | only in egl
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program EGL Module
      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 Test Case
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "teglTestCase.hpp"
     25 
     26 #include "tcuPlatform.hpp"
     27 
     28 #include "egluUtil.hpp"
     29 #include "egluGLFunctionLoader.hpp"
     30 #include "egluPlatform.hpp"
     31 
     32 #include "gluRenderContext.hpp"
     33 #include "glwInitFunctions.hpp"
     34 
     35 #include <set>
     36 
     37 using std::vector;
     38 using std::set;
     39 
     40 namespace deqp
     41 {
     42 namespace egl
     43 {
     44 
     45 namespace
     46 {
     47 
     48 void split (std::vector<std::string>& dst, const std::string& src)
     49 {
     50 	size_t start = 0;
     51 	size_t end	 = std::string::npos;
     52 
     53 	while ((end = src.find(' ', start)) != std::string::npos)
     54 	{
     55 		dst.push_back(src.substr(start, end-start));
     56 		start = end+1;
     57 	}
     58 
     59 	if (start < end)
     60 		dst.push_back(src.substr(start, end-start));
     61 }
     62 
     63 EGLint parseAPI (const std::string& api)
     64 {
     65 	if (api == "OpenGL")
     66 		return EGL_OPENGL_API;
     67 	else if (api == "OpenGL_ES")
     68 		return EGL_OPENGL_ES_API;
     69 	else if (api == "OpenVG")
     70 		return EGL_OPENVG_API;
     71 	else
     72 	{
     73 		tcu::print("Warning: Unknown API '%s'", api.c_str());
     74 		return 0;
     75 	}
     76 }
     77 
     78 } // anonymous
     79 
     80 EglTestContext::EglTestContext (tcu::TestContext& testCtx, const eglu::NativeDisplayFactory& displayFactory, const eglu::NativeWindowFactory* windowFactory, const eglu::NativePixmapFactory* pixmapFactory)
     81 	: m_testCtx					(testCtx)
     82 	, m_displayFactory			(displayFactory)
     83 	, m_windowFactory			(windowFactory)
     84 	, m_pixmapFactory			(pixmapFactory)
     85 	, m_defaultNativeDisplay	(DE_NULL)
     86 	, m_defaultEGLDisplay		(DE_NULL)
     87 {
     88 	// Temporarily allocate default display for storing config list
     89 	try
     90 	{
     91 		EGLDisplay	eglDisplay	= EGL_NO_DISPLAY;
     92 		EGLint		majorVersion;
     93 		EGLint		minorVersion;
     94 
     95 		m_defaultNativeDisplay	= m_displayFactory.createDisplay();
     96 
     97 		eglDisplay = eglu::getDisplay(*m_defaultNativeDisplay);
     98 		TCU_CHECK_EGL_CALL(eglInitialize(eglDisplay, &majorVersion, &minorVersion));
     99 
    100 		m_defaultEGLDisplay = new tcu::egl::Display(eglDisplay, majorVersion, minorVersion);
    101 
    102 		// Create config list
    103 		{
    104 			vector<EGLConfig>	configs;
    105 			set<EGLint>			idSet; // For checking for duplicate config IDs
    106 
    107 			m_defaultEGLDisplay->getConfigs(configs);
    108 
    109 			m_configs.resize(configs.size());
    110 			for (int ndx = 0; ndx < (int)configs.size(); ndx++)
    111 			{
    112 				m_defaultEGLDisplay->describeConfig(configs[ndx], m_configs[ndx]);
    113 
    114 				EGLint id = m_configs[ndx].configId;
    115 				if (idSet.find(id) != idSet.end())
    116 					tcu::print("Warning: Duplicate config ID %d\n", id);
    117 				idSet.insert(id);
    118 			}
    119 		}
    120 
    121 		// Query supported APIs
    122 		{
    123 			const char*					clientAPIs	= eglQueryString(eglDisplay, EGL_CLIENT_APIS);
    124 			std::vector<std::string>	apis;
    125 			TCU_CHECK(clientAPIs);
    126 
    127 			split(apis, clientAPIs);
    128 			for (std::vector<std::string>::const_iterator apiIter = apis.begin(); apiIter != apis.end(); apiIter++)
    129 			{
    130 				EGLint parsedAPI = parseAPI(*apiIter);
    131 				if (parsedAPI != 0)
    132 					m_supportedAPIs.insert(parsedAPI);
    133 			}
    134 		}
    135 
    136 		delete m_defaultEGLDisplay;
    137 		m_defaultEGLDisplay = DE_NULL;
    138 		delete m_defaultNativeDisplay;
    139 		m_defaultNativeDisplay = DE_NULL;
    140 	}
    141 	catch (...)
    142 	{
    143 		delete m_defaultEGLDisplay;
    144 		m_defaultEGLDisplay = DE_NULL;
    145 		delete m_defaultNativeDisplay;
    146 		m_defaultNativeDisplay = DE_NULL;
    147 		throw;
    148 	}
    149 }
    150 
    151 EglTestContext::~EglTestContext (void)
    152 {
    153 	for (GLLibraryMap::iterator iter = m_glLibraries.begin(); iter != m_glLibraries.end(); ++iter)
    154 		delete iter->second;
    155 
    156 	delete m_defaultEGLDisplay;
    157 	delete m_defaultNativeDisplay;
    158 }
    159 
    160 void EglTestContext::createDefaultDisplay (void)
    161 {
    162 	EGLDisplay	eglDisplay	= EGL_NO_DISPLAY;
    163 	EGLint		majorVersion;
    164 	EGLint		minorVersion;
    165 
    166 	DE_ASSERT(!m_defaultEGLDisplay);
    167 	DE_ASSERT(!m_defaultNativeDisplay);
    168 
    169 	try
    170 	{
    171 		m_defaultNativeDisplay	= m_displayFactory.createDisplay();
    172 
    173 		eglDisplay = eglu::getDisplay(*m_defaultNativeDisplay);
    174 		TCU_CHECK_EGL_CALL(eglInitialize(eglDisplay, &majorVersion, &minorVersion));
    175 
    176 		m_defaultEGLDisplay = new tcu::egl::Display(eglDisplay, majorVersion, minorVersion);
    177 	}
    178 	catch (const std::exception&)
    179 	{
    180 		delete m_defaultEGLDisplay;
    181 		m_defaultEGLDisplay = DE_NULL;
    182 		delete m_defaultNativeDisplay;
    183 		m_defaultNativeDisplay = DE_NULL;
    184 		throw;
    185 	}
    186 }
    187 
    188 const eglu::NativeWindowFactory& EglTestContext::getNativeWindowFactory (void) const
    189 {
    190 	if (m_windowFactory)
    191 		return *m_windowFactory;
    192 	else
    193 		throw tcu::NotSupportedError("No default native window factory available", "", __FILE__, __LINE__);
    194 }
    195 
    196 const eglu::NativePixmapFactory& EglTestContext::getNativePixmapFactory (void) const
    197 {
    198 	if (m_pixmapFactory)
    199 		return *m_pixmapFactory;
    200 	else
    201 		throw tcu::NotSupportedError("No default native pixmap factory available", "", __FILE__, __LINE__);
    202 }
    203 
    204 void EglTestContext::destroyDefaultDisplay (void)
    205 {
    206 	DE_ASSERT(m_defaultEGLDisplay);
    207 	DE_ASSERT(m_defaultNativeDisplay);
    208 
    209 	delete m_defaultEGLDisplay;
    210 	m_defaultEGLDisplay = DE_NULL;
    211 
    212 	delete m_defaultNativeDisplay;
    213 	m_defaultNativeDisplay = DE_NULL;
    214 }
    215 
    216 eglu::NativeWindow* EglTestContext::createNativeWindow (EGLDisplay display, EGLConfig config, const EGLAttrib* attribList, int width, int height, eglu::WindowParams::Visibility visibility)
    217 {
    218 	if (!m_windowFactory)
    219 		throw tcu::NotSupportedError("Windows not supported", "", __FILE__, __LINE__);
    220 
    221 	return m_windowFactory->createWindow(m_defaultNativeDisplay, display, config, attribList, eglu::WindowParams(width, height, visibility));
    222 }
    223 
    224 eglu::NativePixmap* EglTestContext::createNativePixmap (EGLDisplay display, EGLConfig config, const EGLAttrib* attribList, int width, int height)
    225 {
    226 	if (!m_pixmapFactory)
    227 		throw tcu::NotSupportedError("Pixmaps not supported", "", __FILE__, __LINE__);
    228 
    229 	return m_pixmapFactory->createPixmap(m_defaultNativeDisplay, display, config, attribList, width, height);
    230 }
    231 
    232 // \todo [2014-10-06 pyry] Quite hacky, expose ApiType internals?
    233 static deUint32 makeKey (glu::ApiType apiType)
    234 {
    235 	return (apiType.getMajorVersion() << 8) | (apiType.getMinorVersion() << 4) | apiType.getProfile();
    236 }
    237 
    238 const tcu::FunctionLibrary* EglTestContext::getGLLibrary (glu::ApiType apiType) const
    239 {
    240 	tcu::FunctionLibrary*		library	= DE_NULL;
    241 	const deUint32				key		= makeKey(apiType);
    242 	GLLibraryMap::iterator		iter	= m_glLibraries.find(key);
    243 
    244 	if (iter == m_glLibraries.end())
    245 	{
    246 		library = m_testCtx.getPlatform().getEGLPlatform().createDefaultGLFunctionLibrary(apiType, m_testCtx.getCommandLine());
    247 		m_glLibraries.insert(std::make_pair(key, library));
    248 	}
    249 	else
    250 		library = iter->second;
    251 
    252 	return library;
    253 }
    254 
    255 deFunctionPtr EglTestContext::getGLFunction (glu::ApiType apiType, const char* name) const
    256 {
    257 	// \todo [2014-03-11 pyry] This requires fall-back to eglGetProcAddress(), right?
    258 	const tcu::FunctionLibrary* const	library	= getGLLibrary(apiType);
    259 	return library->getFunction(name);
    260 }
    261 
    262 void EglTestContext::getGLFunctions (glw::Functions& gl, glu::ApiType apiType) const
    263 {
    264 	const tcu::FunctionLibrary* const	library		= getGLLibrary(apiType);
    265 	const eglu::GLFunctionLoader		loader		(library);
    266 
    267 	// \note There may not be current context, so we can't use initFunctions().
    268 	glu::initCoreFunctions(&gl, &loader, apiType);
    269 }
    270 
    271 TestCaseGroup::TestCaseGroup (EglTestContext& eglTestCtx, const char* name, const char* description)
    272 	: tcu::TestCaseGroup	(eglTestCtx.getTestContext(), name, description)
    273 	, m_eglTestCtx			(eglTestCtx)
    274 {
    275 }
    276 
    277 TestCaseGroup::~TestCaseGroup (void)
    278 {
    279 }
    280 
    281 TestCase::TestCase (EglTestContext& eglTestCtx, const char* name, const char* description)
    282 	: tcu::TestCase		(eglTestCtx.getTestContext(), name, description)
    283 	, m_eglTestCtx		(eglTestCtx)
    284 {
    285 }
    286 
    287 TestCase::TestCase (EglTestContext& eglTestCtx, tcu::TestNodeType type,  const char* name, const char* description)
    288 	: tcu::TestCase		(eglTestCtx.getTestContext(), type, name, description)
    289 	, m_eglTestCtx		(eglTestCtx)
    290 {
    291 }
    292 
    293 TestCase::~TestCase (void)
    294 {
    295 }
    296 
    297 } // egl
    298 } // deqp
    299