• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
split(std::vector<std::string> & dst,const std::string & src)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 
parseAPI(const std::string & api)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 
EglTestContext(tcu::TestContext & testCtx,const eglu::NativeDisplayFactory & displayFactory,const eglu::NativeWindowFactory * windowFactory,const eglu::NativePixmapFactory * pixmapFactory)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 
~EglTestContext(void)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 
createDefaultDisplay(void)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 
getNativeWindowFactory(void) const188 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 
getNativePixmapFactory(void) const196 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 
destroyDefaultDisplay(void)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 
createNativeWindow(EGLDisplay display,EGLConfig config,const EGLAttrib * attribList,int width,int height,eglu::WindowParams::Visibility visibility)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 
createNativePixmap(EGLDisplay display,EGLConfig config,const EGLAttrib * attribList,int width,int height)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?
makeKey(glu::ApiType apiType)233 static deUint32 makeKey (glu::ApiType apiType)
234 {
235 	return (apiType.getMajorVersion() << 8) | (apiType.getMinorVersion() << 4) | apiType.getProfile();
236 }
237 
getGLLibrary(glu::ApiType apiType) const238 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 
getGLFunction(glu::ApiType apiType,const char * name) const255 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 
getGLFunctions(glw::Functions & gl,glu::ApiType apiType) const262 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 
TestCaseGroup(EglTestContext & eglTestCtx,const char * name,const char * description)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 
~TestCaseGroup(void)277 TestCaseGroup::~TestCaseGroup (void)
278 {
279 }
280 
TestCase(EglTestContext & eglTestCtx,const char * name,const char * description)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 
TestCase(EglTestContext & eglTestCtx,tcu::TestNodeType type,const char * name,const char * description)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 
~TestCase(void)293 TestCase::~TestCase (void)
294 {
295 }
296 
297 } // egl
298 } // deqp
299