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 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 "deSTLUtil.hpp"
     41 #include "deUniquePtr.hpp"
     42 
     43 #include <memory>
     44 
     45 namespace deqp
     46 {
     47 namespace egl
     48 {
     49 
     50 using std::vector;
     51 using tcu::TestLog;
     52 using namespace eglw;
     53 
     54 namespace
     55 {
     56 
     57 void checkEGLPlatformSupport (const Library& egl, const char* platformExt)
     58 {
     59 	std::vector<std::string> extensions = eglu::getClientExtensions(egl);
     60 
     61 	if (!de::contains(extensions.begin(), extensions.end(), platformExt))
     62 		throw tcu::NotSupportedError((std::string("Platform extension '") + platformExt + "' not supported").c_str(), "", __FILE__, __LINE__);
     63 }
     64 
     65 EGLSurface createWindowSurface (EGLDisplay display, EGLConfig config, eglu::NativeDisplay& nativeDisplay, eglu::NativeWindow& window, bool useLegacyCreate)
     66 {
     67 	const Library&	egl		= nativeDisplay.getLibrary();
     68 	EGLSurface		surface	= EGL_NO_SURFACE;
     69 
     70 	if (useLegacyCreate)
     71 	{
     72 		surface = egl.createWindowSurface(display, config, window.getLegacyNative(), DE_NULL);
     73 		EGLU_CHECK_MSG(egl, "eglCreateWindowSurface() failed");
     74 	}
     75 	else
     76 	{
     77 		checkEGLPlatformSupport(egl, nativeDisplay.getPlatformExtensionName());
     78 
     79 		surface = egl.createPlatformWindowSurfaceEXT(display, config, window.getPlatformNative(), DE_NULL);
     80 		EGLU_CHECK_MSG(egl, "eglCreatePlatformWindowSurfaceEXT() failed");
     81 	}
     82 
     83 	return surface;
     84 }
     85 
     86 EGLSurface createPixmapSurface (EGLDisplay display, EGLConfig config, eglu::NativeDisplay& nativeDisplay, eglu::NativePixmap& pixmap, bool useLegacyCreate)
     87 {
     88 	const Library&	egl		= nativeDisplay.getLibrary();
     89 	EGLSurface		surface	= EGL_NO_SURFACE;
     90 
     91 	if (useLegacyCreate)
     92 	{
     93 		surface = egl.createPixmapSurface(display, config, pixmap.getLegacyNative(), DE_NULL);
     94 		EGLU_CHECK_MSG(egl, "eglCreatePixmapSurface() failed");
     95 	}
     96 	else
     97 	{
     98 		checkEGLPlatformSupport(egl, nativeDisplay.getPlatformExtensionName());
     99 
    100 		surface = egl.createPlatformPixmapSurfaceEXT(display, config, pixmap.getPlatformNative(), DE_NULL);
    101 		EGLU_CHECK_MSG(egl, "eglCreatePlatformPixmapSurfaceEXT() failed");
    102 	}
    103 
    104 	return surface;
    105 }
    106 
    107 class CreateWindowSurfaceCase : public SimpleConfigCase
    108 {
    109 public:
    110 	CreateWindowSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, bool useLegacyCreate, const eglu::FilterList& filters)
    111 		: SimpleConfigCase	(eglTestCtx, name, description, filters)
    112 		, m_useLegacyCreate	(useLegacyCreate)
    113 	{
    114 	}
    115 
    116 	void executeForConfig (EGLDisplay display, EGLConfig config)
    117 	{
    118 		const Library&						egl				= m_eglTestCtx.getLibrary();
    119 		TestLog&							log				= m_testCtx.getLog();
    120 		EGLint								id				= eglu::getConfigID(egl, display, config);
    121 		const eglu::NativeWindowFactory&	windowFactory	= eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
    122 
    123 		// \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT
    124 
    125 		if (m_useLegacyCreate)
    126 		{
    127 			if ((windowFactory.getCapabilities() & eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_LEGACY) == 0)
    128 				TCU_THROW(NotSupportedError, "Native window doesn't support legacy eglCreateWindowSurface()");
    129 		}
    130 		else
    131 		{
    132 			if ((windowFactory.getCapabilities() & eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_PLATFORM) == 0)
    133 				TCU_THROW(NotSupportedError, "Native window doesn't support eglCreatePlatformWindowSurfaceEXT()");
    134 		}
    135 
    136 		log << TestLog::Message << "Creating window surface with config ID " << id << TestLog::EndMessage;
    137 		EGLU_CHECK_MSG(egl, "init");
    138 
    139 		{
    140 			const int							width			= 64;
    141 			const int							height			= 64;
    142 			de::UniquePtr<eglu::NativeWindow>	window			(windowFactory.createWindow(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, eglu::WindowParams(width, height, eglu::parseWindowVisibility(m_testCtx.getCommandLine()))));
    143 			eglu::UniqueSurface					surface			(egl, display, createWindowSurface(display, config, m_eglTestCtx.getNativeDisplay(), *window, m_useLegacyCreate));
    144 
    145 			EGLint								windowWidth		= 0;
    146 			EGLint								windowHeight	= 0;
    147 
    148 			EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_WIDTH,		&windowWidth));
    149 			EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_HEIGHT,	&windowHeight));
    150 
    151 			if (windowWidth <= 0 || windowHeight <= 0)
    152 			{
    153 				log << TestLog::Message << "  Fail, invalid surface size " << windowWidth << "x" << windowHeight << TestLog::EndMessage;
    154 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid surface size");
    155 			}
    156 			else
    157 				log << TestLog::Message << "  Pass" << TestLog::EndMessage;
    158 		}
    159 	}
    160 
    161 private:
    162 	bool	m_useLegacyCreate;
    163 };
    164 
    165 class CreatePixmapSurfaceCase : public SimpleConfigCase
    166 {
    167 public:
    168 	CreatePixmapSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, bool useLegacyCreate, const eglu::FilterList& filters)
    169 		: SimpleConfigCase(eglTestCtx, name, description, filters)
    170 		, m_useLegacyCreate	(useLegacyCreate)
    171 	{
    172 	}
    173 
    174 	void executeForConfig (EGLDisplay display, EGLConfig config)
    175 	{
    176 		const Library&						egl				= m_eglTestCtx.getLibrary();
    177 		TestLog&							log				= m_testCtx.getLog();
    178 		EGLint								id				= eglu::getConfigID(egl, display, config);
    179 		const eglu::NativePixmapFactory&	pixmapFactory	= eglu::selectNativePixmapFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
    180 
    181 		// \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT
    182 
    183 		if (m_useLegacyCreate)
    184 		{
    185 			if ((pixmapFactory.getCapabilities() & eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_LEGACY) == 0)
    186 				TCU_THROW(NotSupportedError, "Native pixmap doesn't support legacy eglCreatePixmapSurface()");
    187 		}
    188 		else
    189 		{
    190 			if ((pixmapFactory.getCapabilities() & eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_PLATFORM) == 0)
    191 				TCU_THROW(NotSupportedError, "Native pixmap doesn't support eglCreatePlatformPixmapSurfaceEXT()");
    192 		}
    193 
    194 		log << TestLog::Message << "Creating pixmap surface with config ID " << id << TestLog::EndMessage;
    195 		EGLU_CHECK_MSG(egl, "init");
    196 
    197 		{
    198 			const int							width			= 64;
    199 			const int							height			= 64;
    200 			de::UniquePtr<eglu::NativePixmap>	pixmap			(pixmapFactory.createPixmap(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, width, height));
    201 			eglu::UniqueSurface					surface			(egl, display, createPixmapSurface(display, config, m_eglTestCtx.getNativeDisplay(), *pixmap, m_useLegacyCreate));
    202 			EGLint								pixmapWidth		= 0;
    203 			EGLint								pixmapHeight	= 0;
    204 
    205 			EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_WIDTH,		&pixmapWidth));
    206 			EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_HEIGHT,	&pixmapHeight));
    207 
    208 			if (pixmapWidth <= 0 || pixmapHeight <= 0)
    209 			{
    210 				log << TestLog::Message << "  Fail, invalid surface size " << pixmapWidth << "x" << pixmapHeight << TestLog::EndMessage;
    211 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid surface size");
    212 			}
    213 			else
    214 				log << TestLog::Message << "  Pass" << TestLog::EndMessage;
    215 		}
    216 	}
    217 
    218 private:
    219 	bool	m_useLegacyCreate;
    220 };
    221 
    222 class CreatePbufferSurfaceCase : public SimpleConfigCase
    223 {
    224 public:
    225 	CreatePbufferSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
    226 		: SimpleConfigCase(eglTestCtx, name, description, filters)
    227 	{
    228 	}
    229 
    230 	void executeForConfig (EGLDisplay display, EGLConfig config)
    231 	{
    232 		const Library&	egl		= m_eglTestCtx.getLibrary();
    233 		TestLog&		log		= m_testCtx.getLog();
    234 		EGLint			id		= eglu::getConfigID(egl, display, config);
    235 		int				width	= 64;
    236 		int				height	= 64;
    237 
    238 		// \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT
    239 
    240 		log << TestLog::Message << "Creating pbuffer surface with config ID " << id << TestLog::EndMessage;
    241 		EGLU_CHECK_MSG(egl, "init");
    242 
    243 		// Clamp to maximums reported by implementation
    244 		width	= deMin32(width, eglu::getConfigAttribInt(egl, display, config, EGL_MAX_PBUFFER_WIDTH));
    245 		height	= deMin32(height, eglu::getConfigAttribInt(egl, display, config, EGL_MAX_PBUFFER_HEIGHT));
    246 
    247 		if (width == 0 || height == 0)
    248 		{
    249 			log << TestLog::Message << "  Fail, maximum pbuffer size of " << width << "x" << height << " reported" << TestLog::EndMessage;
    250 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid maximum pbuffer size");
    251 			return;
    252 		}
    253 
    254 		// \todo [2011-03-23 pyry] Texture-backed variants!
    255 
    256 		const EGLint attribs[] =
    257 		{
    258 			EGL_WIDTH,			width,
    259 			EGL_HEIGHT,			height,
    260 			EGL_TEXTURE_FORMAT,	EGL_NO_TEXTURE,
    261 			EGL_NONE
    262 		};
    263 
    264 		EGLSurface surface = egl.createPbufferSurface(display, config, attribs);
    265 		EGLU_CHECK_MSG(egl, "Failed to create pbuffer");
    266 		TCU_CHECK(surface != EGL_NO_SURFACE);
    267 		egl.destroySurface(display, surface);
    268 
    269 		log << TestLog::Message << "  Pass" << TestLog::EndMessage;
    270 	}
    271 };
    272 
    273 } // anonymous
    274 
    275 CreateSurfaceTests::CreateSurfaceTests (EglTestContext& eglTestCtx)
    276 	: TestCaseGroup(eglTestCtx, "create_surface", "Basic surface construction tests")
    277 {
    278 }
    279 
    280 CreateSurfaceTests::~CreateSurfaceTests (void)
    281 {
    282 }
    283 
    284 template <deUint32 Type>
    285 static bool surfaceType (const eglu::CandidateConfig& c)
    286 {
    287 	return (c.surfaceType() & Type) == Type;
    288 }
    289 
    290 void CreateSurfaceTests::init (void)
    291 {
    292 	// Window surfaces
    293 	{
    294 		tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "window", "Window surfaces");
    295 		addChild(windowGroup);
    296 
    297 		eglu::FilterList baseFilters;
    298 		baseFilters << surfaceType<EGL_WINDOW_BIT>;
    299 
    300 		vector<NamedFilterList> filterLists;
    301 		getDefaultFilterLists(filterLists, baseFilters);
    302 
    303 		for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
    304 			windowGroup->addChild(new CreateWindowSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), true, *i));
    305 	}
    306 
    307 	// Pixmap surfaces
    308 	{
    309 		tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "pixmap", "Pixmap surfaces");
    310 		addChild(pixmapGroup);
    311 
    312 		eglu::FilterList baseFilters;
    313 		baseFilters << surfaceType<EGL_PIXMAP_BIT>;
    314 
    315 		vector<NamedFilterList> filterLists;
    316 		getDefaultFilterLists(filterLists, baseFilters);
    317 
    318 		for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
    319 			pixmapGroup->addChild(new CreatePixmapSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), true, *i));
    320 	}
    321 
    322 	// Pbuffer surfaces
    323 	{
    324 		tcu::TestCaseGroup* pbufferGroup = new tcu::TestCaseGroup(m_testCtx, "pbuffer", "Pbuffer surfaces");
    325 		addChild(pbufferGroup);
    326 
    327 		eglu::FilterList baseFilters;
    328 		baseFilters << surfaceType<EGL_PBUFFER_BIT>;
    329 
    330 		vector<NamedFilterList> filterLists;
    331 		getDefaultFilterLists(filterLists, baseFilters);
    332 
    333 		for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
    334 			pbufferGroup->addChild(new CreatePbufferSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), *i));
    335 	}
    336 
    337 	// Window surfaces with new platform extension
    338 	{
    339 		tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "platform_window", "Window surfaces with platform extension");
    340 		addChild(windowGroup);
    341 
    342 		eglu::FilterList baseFilters;
    343 		baseFilters << surfaceType<EGL_WINDOW_BIT>;
    344 
    345 		vector<NamedFilterList> filterLists;
    346 		getDefaultFilterLists(filterLists, baseFilters);
    347 
    348 		for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
    349 			windowGroup->addChild(new CreateWindowSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), false, *i));
    350 	}
    351 
    352 	// Pixmap surfaces with new platform extension
    353 	{
    354 		tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "platform_pixmap", "Pixmap surfaces with platform extension");
    355 		addChild(pixmapGroup);
    356 
    357 		eglu::FilterList baseFilters;
    358 		baseFilters << surfaceType<EGL_PIXMAP_BIT>;
    359 
    360 		vector<NamedFilterList> filterLists;
    361 		getDefaultFilterLists(filterLists, baseFilters);
    362 
    363 		for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
    364 			pixmapGroup->addChild(new CreatePixmapSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), false, *i));
    365 	}
    366 }
    367 
    368 } // egl
    369 } // deqp
    370