teglTestCase.cpp revision 3c827367444ee418f129b2c238299f49d3264554
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*-------------------------------------------------------------------------
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * drawElements Quality Program EGL Module
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * ---------------------------------------
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2014 The Android Open Source Project
6ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com *
7ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com * Licensed under the Apache License, Version 2.0 (the "License");
8ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com * you may not use this file except in compliance with the License.
9ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com * You may obtain a copy of the License at
10ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com *
11ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com *      http://www.apache.org/licenses/LICENSE-2.0
12ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com *
13ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com * Unless required by applicable law or agreed to in writing, software
1407f3ee10d34f09342abb93d758b5e151ff78f7a5reed@google.com * distributed under the License is distributed on an "AS IS" BASIS,
15ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com * See the License for the specific language governing permissions and
17ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com * limitations under the License.
18ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com *
19ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com *//*!
20ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com * \file
2153e1e4d88a06db62898a3bf75751c042729d7160commit-bot@chromium.org * \brief EGL Test Case
22ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com *//*--------------------------------------------------------------------*/
23a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org
24ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "teglTestCase.hpp"
25fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com
26fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com#include "tcuPlatform.hpp"
27ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
2898539c607b05f7e25406ae873bf1b24154a36a6freed@google.com#include "egluUtil.hpp"
29fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org#include "egluGLFunctionLoader.hpp"
30ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "egluPlatform.hpp"
31ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
32762cd804375ff8478427dba4fe29379562b8fb60commit-bot@chromium.org#include "gluRenderContext.hpp"
33762cd804375ff8478427dba4fe29379562b8fb60commit-bot@chromium.org#include "glwInitFunctions.hpp"
34762cd804375ff8478427dba4fe29379562b8fb60commit-bot@chromium.org
35762cd804375ff8478427dba4fe29379562b8fb60commit-bot@chromium.org#include <set>
36762cd804375ff8478427dba4fe29379562b8fb60commit-bot@chromium.org
37762cd804375ff8478427dba4fe29379562b8fb60commit-bot@chromium.orgusing std::vector;
3807f3ee10d34f09342abb93d758b5e151ff78f7a5reed@google.comusing std::set;
39fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com
40fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.comnamespace deqp
41a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org{
42ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comnamespace egl
43ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com{
44ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
45namespace
46{
47
48void 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
63EGLint 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
80EglTestContext::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
151EglTestContext::~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
160void 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
188const 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
196const 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
204void 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
216eglu::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
224eglu::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?
233static deUint32 makeKey (glu::ApiType apiType)
234{
235	return (apiType.getMajorVersion() << 8) | (apiType.getMinorVersion() << 4) | apiType.getProfile();
236}
237
238const 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
255deFunctionPtr 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
262void 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
271TestCaseGroup::TestCaseGroup (EglTestContext& eglTestCtx, const char* name, const char* description)
272	: tcu::TestCaseGroup	(eglTestCtx.getTestContext(), name, description)
273	, m_eglTestCtx			(eglTestCtx)
274{
275}
276
277TestCaseGroup::~TestCaseGroup (void)
278{
279}
280
281TestCase::TestCase (EglTestContext& eglTestCtx, const char* name, const char* description)
282	: tcu::TestCase		(eglTestCtx.getTestContext(), name, description)
283	, m_eglTestCtx		(eglTestCtx)
284{
285}
286
287TestCase::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
293TestCase::~TestCase (void)
294{
295}
296
297} // egl
298} // deqp
299