• 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 Simple surface construction test.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "teglCreateSurfaceTests.hpp"
25 
26 #include "egluNativeDisplay.hpp"
27 #include "egluNativeWindow.hpp"
28 #include "egluNativePixmap.hpp"
29 #include "egluUtil.hpp"
30 #include "egluUnique.hpp"
31 
32 #include "eglwLibrary.hpp"
33 #include "eglwEnums.hpp"
34 
35 #include "teglSimpleConfigCase.hpp"
36 #include "tcuTestContext.hpp"
37 #include "tcuCommandLine.hpp"
38 #include "tcuTestLog.hpp"
39 
40 #include "deStringUtil.hpp"
41 #include "deSTLUtil.hpp"
42 #include "deUniquePtr.hpp"
43 
44 #include <memory>
45 
46 namespace deqp
47 {
48 namespace egl
49 {
50 
51 using std::vector;
52 using tcu::TestLog;
53 using namespace eglw;
54 
55 namespace
56 {
57 
58 #define EGL_MAKE_VERSION(major, minor) (((major) << 12) | (minor))
59 
60 enum ApiType
61 {
62 	LEGACY,
63 	EXTENSION,
64 	EGL15
65 };
66 
checkEGLPlatformSupport(const Library & egl)67 void checkEGLPlatformSupport (const Library& egl)
68 {
69 	const vector<std::string>	extensions	= eglu::getClientExtensions(egl);
70 	if (!de::contains(extensions.begin(), extensions.end(), "EGL_EXT_platform_base"))
71 		throw tcu::NotSupportedError("Platform extension 'EGL_EXT_platform_base' not supported", "", __FILE__, __LINE__);
72 }
73 
checkEGL15Support(const Library & egl,EGLDisplay display)74 void checkEGL15Support (const Library& egl, EGLDisplay display)
75 {
76 	// The EGL_VERSION string is laid out as follows:
77 	// major_version.minor_version space vendor_specific_info
78 	// Split version from vendor_specific_info
79 	std::vector<std::string> tokens = de::splitString(egl.queryString(display, EGL_VERSION), ' ');
80 	// split version into major & minor
81 	std::vector<std::string> values = de::splitString(tokens[0], '.');
82 	EGLint eglVersion = EGL_MAKE_VERSION(atoi(values[0].c_str()), atoi(values[1].c_str()));
83 	if (eglVersion < EGL_MAKE_VERSION(1, 5))
84 		throw tcu::NotSupportedError("EGL 1.5 not supported", "", __FILE__, __LINE__);
85 }
86 
createWindowSurface(EGLDisplay display,EGLConfig config,eglu::NativeDisplay & nativeDisplay,eglu::NativeWindow & window,ApiType createType)87 EGLSurface createWindowSurface (EGLDisplay display, EGLConfig config, eglu::NativeDisplay& nativeDisplay, eglu::NativeWindow& window, ApiType createType)
88 {
89 	const Library&	egl		= nativeDisplay.getLibrary();
90 	EGLSurface		surface	= EGL_NO_SURFACE;
91 
92 	switch (createType)
93 	{
94 		case LEGACY:
95 		{
96 			surface = egl.createWindowSurface(display, config, window.getLegacyNative(), DE_NULL);
97 			EGLU_CHECK_MSG(egl, "eglCreateWindowSurface() failed");
98 		}
99 		break;
100 		case EXTENSION:
101 		{
102 			checkEGLPlatformSupport(egl);
103 			void *nativeWindow = window.getPlatformExtension();
104 			surface = egl.createPlatformWindowSurfaceEXT(display, config, nativeWindow, DE_NULL);
105 			EGLU_CHECK_MSG(egl, "eglCreatePlatformWindowSurfaceEXT() failed");
106 		}
107 		break;
108 		case EGL15:
109 		{
110 			checkEGL15Support(egl, display);
111 			surface = egl.createPlatformWindowSurface(display, config, window.getPlatformNative(), DE_NULL);
112 			EGLU_CHECK_MSG(egl, "eglCreatePlatformWindowSurface() failed");
113 		}
114 	}
115 
116 	return surface;
117 }
118 
createPixmapSurface(EGLDisplay display,EGLConfig config,eglu::NativeDisplay & nativeDisplay,eglu::NativePixmap & pixmap,ApiType createType)119 EGLSurface createPixmapSurface (EGLDisplay display, EGLConfig config, eglu::NativeDisplay& nativeDisplay, eglu::NativePixmap& pixmap, ApiType createType)
120 {
121 	const Library&	egl		= nativeDisplay.getLibrary();
122 	EGLSurface		surface	= EGL_NO_SURFACE;
123 
124 	switch (createType)
125 	{
126 		case LEGACY:
127 			surface = egl.createPixmapSurface(display, config, pixmap.getLegacyNative(), DE_NULL);
128 			EGLU_CHECK_MSG(egl, "eglCreatePixmapSurface() failed");
129 		break;
130 		case EXTENSION:
131 			checkEGLPlatformSupport(egl);
132 			surface = egl.createPlatformPixmapSurfaceEXT(display, config, pixmap.getPlatformExtension(), DE_NULL);
133 			EGLU_CHECK_MSG(egl, "eglCreatePlatformPixmapSurfaceEXT() failed");
134 		break;
135 		case EGL15:
136 			checkEGL15Support(egl, display);
137 			surface = egl.createPlatformPixmapSurface(display, config, pixmap.getPlatformNative(), DE_NULL);
138 			EGLU_CHECK_MSG(egl, "eglCreatePlatformPixmapSurface() failed");
139 		break;
140 	}
141 
142 	return surface;
143 }
144 
145 class CreateWindowSurfaceCase : public SimpleConfigCase
146 {
147 public:
CreateWindowSurfaceCase(EglTestContext & eglTestCtx,const char * name,const char * description,ApiType createType,const eglu::FilterList & filters)148 	CreateWindowSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, ApiType createType, const eglu::FilterList& filters)
149 		: SimpleConfigCase	(eglTestCtx, name, description, filters)
150 		, m_createType	(createType)
151 	{
152 	}
153 
executeForConfig(EGLDisplay display,EGLConfig config)154 	void executeForConfig (EGLDisplay display, EGLConfig config)
155 	{
156 		const Library&						egl				= m_eglTestCtx.getLibrary();
157 		TestLog&							log				= m_testCtx.getLog();
158 		EGLint								id				= eglu::getConfigID(egl, display, config);
159 		const eglu::NativeWindowFactory&	windowFactory	= eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
160 
161 		// \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT
162 
163 		switch (m_createType)
164 		{
165 			case LEGACY:
166 			{
167 				if ((windowFactory.getCapabilities() & eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_LEGACY) == 0)
168 					TCU_THROW(NotSupportedError, "Native window doesn't support legacy eglCreateWindowSurface()");
169 			}
170 			break;
171 			case EXTENSION:
172 			{
173 				if ((windowFactory.getCapabilities() & eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_PLATFORM_EXTENSION) == 0)
174 					TCU_THROW(NotSupportedError, "Native window doesn't support eglCreatePlatformWindowSurfaceEXT()");
175 			}
176 			break;
177 			case EGL15:
178 			{
179 				if ((windowFactory.getCapabilities() & eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_PLATFORM) == 0)
180 					TCU_THROW(NotSupportedError, "Native window doesn't support eglCreatePlatformWindowSurface()");
181 			}
182 			break;
183 		}
184 
185 		log << TestLog::Message << "Creating window surface with config ID " << id << TestLog::EndMessage;
186 		EGLU_CHECK_MSG(egl, "init");
187 
188 		{
189 			const int							width			= 64;
190 			const int							height			= 64;
191 			de::UniquePtr<eglu::NativeWindow>	window			(windowFactory.createWindow(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, eglu::WindowParams(width, height, eglu::parseWindowVisibility(m_testCtx.getCommandLine()))));
192 			eglu::UniqueSurface					surface			(egl, display, createWindowSurface(display, config, m_eglTestCtx.getNativeDisplay(), *window, m_createType));
193 
194 			EGLint								windowWidth		= 0;
195 			EGLint								windowHeight	= 0;
196 
197 			EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_WIDTH,		&windowWidth));
198 			EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_HEIGHT,	&windowHeight));
199 
200 			if (windowWidth <= 0 || windowHeight <= 0)
201 			{
202 				log << TestLog::Message << "  Fail, invalid surface size " << windowWidth << "x" << windowHeight << TestLog::EndMessage;
203 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid surface size");
204 			}
205 			else
206 				log << TestLog::Message << "  Pass" << TestLog::EndMessage;
207 		}
208 	}
209 
210 private:
211 	ApiType		m_createType;
212 };
213 
214 class CreatePixmapSurfaceCase : public SimpleConfigCase
215 {
216 public:
CreatePixmapSurfaceCase(EglTestContext & eglTestCtx,const char * name,const char * description,ApiType createType,const eglu::FilterList & filters)217 	CreatePixmapSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, ApiType createType, const eglu::FilterList& filters)
218 		: SimpleConfigCase(eglTestCtx, name, description, filters)
219 		, m_createType	(createType)
220 	{
221 	}
222 
executeForConfig(EGLDisplay display,EGLConfig config)223 	void executeForConfig (EGLDisplay display, EGLConfig config)
224 	{
225 		const Library&						egl				= m_eglTestCtx.getLibrary();
226 		TestLog&							log				= m_testCtx.getLog();
227 		EGLint								id				= eglu::getConfigID(egl, display, config);
228 		const eglu::NativePixmapFactory&	pixmapFactory	= eglu::selectNativePixmapFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
229 
230 		// \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT
231 
232 		switch (m_createType)
233 		{
234 			case LEGACY:
235 			{
236 				if ((pixmapFactory.getCapabilities() & eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_LEGACY) == 0)
237 					TCU_THROW(NotSupportedError, "Native pixmap doesn't support legacy eglCreatePixmapSurface()");
238 			}
239 			break;
240 			case EXTENSION:
241 			{
242 				if ((pixmapFactory.getCapabilities() & eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_PLATFORM_EXTENSION) == 0)
243 					TCU_THROW(NotSupportedError, "Native pixmap doesn't support eglCreatePlatformPixmapSurfaceEXT()");
244 			}
245 			break;
246 			case EGL15:
247 			{
248 				if ((pixmapFactory.getCapabilities() & eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_PLATFORM) == 0)
249 					TCU_THROW(NotSupportedError, "Native pixmap doesn't support eglCreatePlatformPixmapSurface()");
250 			}
251 			break;
252 		}
253 
254 		log << TestLog::Message << "Creating pixmap surface with config ID " << id << TestLog::EndMessage;
255 		EGLU_CHECK_MSG(egl, "init");
256 
257 		{
258 			const int							width			= 64;
259 			const int							height			= 64;
260 			de::UniquePtr<eglu::NativePixmap>	pixmap			(pixmapFactory.createPixmap(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, width, height));
261 			eglu::UniqueSurface					surface			(egl, display, createPixmapSurface(display, config, m_eglTestCtx.getNativeDisplay(), *pixmap, m_createType));
262 			EGLint								pixmapWidth		= 0;
263 			EGLint								pixmapHeight	= 0;
264 
265 			EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_WIDTH,		&pixmapWidth));
266 			EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_HEIGHT,	&pixmapHeight));
267 
268 			if (pixmapWidth <= 0 || pixmapHeight <= 0)
269 			{
270 				log << TestLog::Message << "  Fail, invalid surface size " << pixmapWidth << "x" << pixmapHeight << TestLog::EndMessage;
271 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid surface size");
272 			}
273 			else
274 				log << TestLog::Message << "  Pass" << TestLog::EndMessage;
275 		}
276 	}
277 
278 private:
279 	ApiType		m_createType;
280 };
281 
282 class CreatePbufferSurfaceCase : public SimpleConfigCase
283 {
284 public:
CreatePbufferSurfaceCase(EglTestContext & eglTestCtx,const char * name,const char * description,const eglu::FilterList & filters)285 	CreatePbufferSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
286 		: SimpleConfigCase(eglTestCtx, name, description, filters)
287 	{
288 	}
289 
executeForConfig(EGLDisplay display,EGLConfig config)290 	void executeForConfig (EGLDisplay display, EGLConfig config)
291 	{
292 		const Library&	egl		= m_eglTestCtx.getLibrary();
293 		TestLog&		log		= m_testCtx.getLog();
294 		EGLint			id		= eglu::getConfigID(egl, display, config);
295 		int				width	= 64;
296 		int				height	= 64;
297 
298 		// \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT
299 
300 		log << TestLog::Message << "Creating pbuffer surface with config ID " << id << TestLog::EndMessage;
301 		EGLU_CHECK_MSG(egl, "init");
302 
303 		// Clamp to maximums reported by implementation
304 		width	= deMin32(width, eglu::getConfigAttribInt(egl, display, config, EGL_MAX_PBUFFER_WIDTH));
305 		height	= deMin32(height, eglu::getConfigAttribInt(egl, display, config, EGL_MAX_PBUFFER_HEIGHT));
306 
307 		if (width == 0 || height == 0)
308 		{
309 			log << TestLog::Message << "  Fail, maximum pbuffer size of " << width << "x" << height << " reported" << TestLog::EndMessage;
310 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid maximum pbuffer size");
311 			return;
312 		}
313 
314 		// \todo [2011-03-23 pyry] Texture-backed variants!
315 
316 		const EGLint attribs[] =
317 		{
318 			EGL_WIDTH,			width,
319 			EGL_HEIGHT,			height,
320 			EGL_TEXTURE_FORMAT,	EGL_NO_TEXTURE,
321 			EGL_NONE
322 		};
323 
324 		EGLSurface surface = egl.createPbufferSurface(display, config, attribs);
325 		EGLU_CHECK_MSG(egl, "Failed to create pbuffer");
326 		TCU_CHECK(surface != EGL_NO_SURFACE);
327 		egl.destroySurface(display, surface);
328 
329 		log << TestLog::Message << "  Pass" << TestLog::EndMessage;
330 	}
331 };
332 
333 } // anonymous
334 
CreateSurfaceTests(EglTestContext & eglTestCtx)335 CreateSurfaceTests::CreateSurfaceTests (EglTestContext& eglTestCtx)
336 	: TestCaseGroup(eglTestCtx, "create_surface", "Basic surface construction tests")
337 {
338 }
339 
~CreateSurfaceTests(void)340 CreateSurfaceTests::~CreateSurfaceTests (void)
341 {
342 }
343 
344 template <deUint32 Type>
surfaceType(const eglu::CandidateConfig & c)345 static bool surfaceType (const eglu::CandidateConfig& c)
346 {
347 	return (c.surfaceType() & Type) == Type;
348 }
349 
init(void)350 void CreateSurfaceTests::init (void)
351 {
352 	// Window surfaces
353 	{
354 		tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "window", "Window surfaces");
355 		addChild(windowGroup);
356 
357 		eglu::FilterList baseFilters;
358 		baseFilters << surfaceType<EGL_WINDOW_BIT>;
359 
360 		vector<NamedFilterList> filterLists;
361 		getDefaultFilterLists(filterLists, baseFilters);
362 
363 		for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
364 			windowGroup->addChild(new CreateWindowSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), LEGACY, *i));
365 	}
366 
367 	// Pixmap surfaces
368 	{
369 		tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "pixmap", "Pixmap surfaces");
370 		addChild(pixmapGroup);
371 
372 		eglu::FilterList baseFilters;
373 		baseFilters << surfaceType<EGL_PIXMAP_BIT>;
374 
375 		vector<NamedFilterList> filterLists;
376 		getDefaultFilterLists(filterLists, baseFilters);
377 
378 		for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
379 			pixmapGroup->addChild(new CreatePixmapSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), LEGACY, *i));
380 	}
381 
382 	// Pbuffer surfaces
383 	{
384 		tcu::TestCaseGroup* pbufferGroup = new tcu::TestCaseGroup(m_testCtx, "pbuffer", "Pbuffer surfaces");
385 		addChild(pbufferGroup);
386 
387 		eglu::FilterList baseFilters;
388 		baseFilters << surfaceType<EGL_PBUFFER_BIT>;
389 
390 		vector<NamedFilterList> filterLists;
391 		getDefaultFilterLists(filterLists, baseFilters);
392 
393 		for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
394 			pbufferGroup->addChild(new CreatePbufferSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), *i));
395 	}
396 
397 	// Window surfaces with new platform extension
398 	{
399 		tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "platform_ext_window", "Window surfaces with platform extension");
400 		addChild(windowGroup);
401 
402 		eglu::FilterList baseFilters;
403 		baseFilters << surfaceType<EGL_WINDOW_BIT>;
404 
405 		vector<NamedFilterList> filterLists;
406 		getDefaultFilterLists(filterLists, baseFilters);
407 
408 		for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
409 			windowGroup->addChild(new CreateWindowSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), EXTENSION, *i));
410 	}
411 
412 	// Pixmap surfaces with new platform extension
413 	{
414 		tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "platform_ext_pixmap", "Pixmap surfaces with platform extension");
415 		addChild(pixmapGroup);
416 
417 		eglu::FilterList baseFilters;
418 		baseFilters << surfaceType<EGL_PIXMAP_BIT>;
419 
420 		vector<NamedFilterList> filterLists;
421 		getDefaultFilterLists(filterLists, baseFilters);
422 
423 		for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
424 			pixmapGroup->addChild(new CreatePixmapSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), EXTENSION, *i));
425 	}
426 	//
427 	// Window surfaces with EGL 1.5 CreateWindowSurface
428 	{
429 		tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "platform_window", "Window surfaces with EGL 1.5");
430 		addChild(windowGroup);
431 
432 		eglu::FilterList baseFilters;
433 		baseFilters << surfaceType<EGL_WINDOW_BIT>;
434 
435 		vector<NamedFilterList> filterLists;
436 		getDefaultFilterLists(filterLists, baseFilters);
437 
438 		for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
439 			windowGroup->addChild(new CreateWindowSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), EGL15, *i));
440 	}
441 
442 	// Pixmap surfaces with EGL 1.5 CreateWindowSurface
443 	{
444 		tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "platform_pixmap", "Pixmap surfaces with EGL 1.5");
445 		addChild(pixmapGroup);
446 
447 		eglu::FilterList baseFilters;
448 		baseFilters << surfaceType<EGL_PIXMAP_BIT>;
449 
450 		vector<NamedFilterList> filterLists;
451 		getDefaultFilterLists(filterLists, baseFilters);
452 
453 		for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
454 			pixmapGroup->addChild(new CreatePixmapSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), EGL15, *i));
455 	}
456 }
457 
458 } // egl
459 } // deqp
460