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 Extension function pointer query tests.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "teglGetProcAddressTests.hpp"
     25 #include "teglTestCase.hpp"
     26 #include "egluCallLogWrapper.hpp"
     27 #include "egluStrUtil.hpp"
     28 #include "egluUtil.hpp"
     29 #include "eglwLibrary.hpp"
     30 #include "eglwEnums.hpp"
     31 #include "tcuTestLog.hpp"
     32 #include "deSTLUtil.hpp"
     33 #include "deStringUtil.hpp"
     34 
     35 namespace deqp
     36 {
     37 namespace egl
     38 {
     39 
     40 namespace
     41 {
     42 
     43 using tcu::TestLog;
     44 using namespace eglw;
     45 
     46 // Function name strings generated from API headers
     47 
     48 #include "teglGetProcAddressTests.inl"
     49 
     50 struct FunctionNames
     51 {
     52 	int					numFunctions;
     53 	const char* const*	functions;
     54 
     55 	FunctionNames (int numFunctions_, const char* const* functions_)
     56 		: numFunctions	(numFunctions_)
     57 		, functions		(functions_)
     58 	{
     59 	}
     60 };
     61 
     62 FunctionNames getExtFunctionNames (const std::string& extName)
     63 {
     64 	for (int ndx = 0; ndx <= DE_LENGTH_OF_ARRAY(s_extensions); ndx++)
     65 	{
     66 		if (extName == s_extensions[ndx].name)
     67 			return FunctionNames(s_extensions[ndx].numFunctions, s_extensions[ndx].functions);
     68 	}
     69 
     70 	DE_ASSERT(false);
     71 	return FunctionNames(0, DE_NULL);
     72 }
     73 
     74 FunctionNames getCoreFunctionNames (EGLint apiBit)
     75 {
     76 	switch (apiBit)
     77 	{
     78 		case 0:							return FunctionNames(DE_LENGTH_OF_ARRAY(s_EGL14),	s_EGL14);
     79 		case EGL_OPENGL_ES_BIT:			return FunctionNames(DE_LENGTH_OF_ARRAY(s_GLES10),	s_GLES10);
     80 		case EGL_OPENGL_ES2_BIT:		return FunctionNames(DE_LENGTH_OF_ARRAY(s_GLES20),	s_GLES20);
     81 		case EGL_OPENGL_ES3_BIT_KHR:	return FunctionNames(DE_LENGTH_OF_ARRAY(s_GLES30),	s_GLES30);
     82 		default:
     83 			DE_ASSERT(false);
     84 	}
     85 
     86 	return FunctionNames(0, DE_NULL);
     87 }
     88 
     89 } // anonymous
     90 
     91 // Base class for eglGetProcAddress() test cases
     92 
     93 class GetProcAddressCase : public TestCase, protected eglu::CallLogWrapper
     94 {
     95 public:
     96 								GetProcAddressCase		(EglTestContext& eglTestCtx, const char* name, const char* description);
     97 	virtual						~GetProcAddressCase		(void);
     98 
     99 	void						init					(void);
    100 	void						deinit					(void);
    101 	IterateResult				iterate					(void);
    102 
    103 	bool						isSupported				(const std::string& extName);
    104 
    105 	virtual void				executeTest				(void) = 0;
    106 
    107 protected:
    108 	EGLDisplay					m_display;
    109 
    110 private:
    111 	std::vector<std::string>	m_supported;
    112 };
    113 
    114 GetProcAddressCase::GetProcAddressCase (EglTestContext& eglTestCtx, const char* name, const char* description)
    115 	: TestCase			(eglTestCtx, name, description)
    116 	, CallLogWrapper	(eglTestCtx.getLibrary(), eglTestCtx.getTestContext().getLog())
    117 	, m_display			(EGL_NO_DISPLAY)
    118 {
    119 }
    120 
    121 GetProcAddressCase::~GetProcAddressCase (void)
    122 {
    123 }
    124 
    125 void GetProcAddressCase::init (void)
    126 {
    127 	try
    128 	{
    129 		m_supported = eglu::getClientExtensions(m_eglTestCtx.getLibrary());
    130 	}
    131 	catch (const eglu::Error& error)
    132 	{
    133 		// EGL_BAD_DISPLAY is generated if client extensions are not supported.
    134 		if (error.getError() != EGL_BAD_DISPLAY)
    135 			throw;
    136 	}
    137 
    138 	DE_ASSERT(m_display == EGL_NO_DISPLAY);
    139 
    140 	m_display = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
    141 
    142 	{
    143 		const std::vector<std::string> displayExtensios = eglu::getDisplayExtensions(m_eglTestCtx.getLibrary(), m_display);
    144 		m_supported.insert(m_supported.end(), displayExtensios.begin(), displayExtensios.end());
    145 	}
    146 
    147 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    148 }
    149 
    150 void GetProcAddressCase::deinit (void)
    151 {
    152 	m_eglTestCtx.getLibrary().terminate(m_display);
    153 	m_display = EGL_NO_DISPLAY;
    154 }
    155 
    156 tcu::TestNode::IterateResult GetProcAddressCase::iterate (void)
    157 {
    158 	enableLogging(true);
    159 
    160 	executeTest();
    161 
    162 	enableLogging(false);
    163 
    164 	return STOP;
    165 }
    166 
    167 bool GetProcAddressCase::isSupported (const std::string& extName)
    168 {
    169 	return de::contains(m_supported.begin(), m_supported.end(), extName);
    170 }
    171 
    172 // Test by extension
    173 
    174 class GetProcAddressExtensionCase : public GetProcAddressCase
    175 {
    176 public:
    177 	GetProcAddressExtensionCase (EglTestContext& eglTestCtx, const char* name, const char* description, const std::string& extName)
    178 		: GetProcAddressCase	(eglTestCtx, name, description)
    179 		, m_extName				(extName)
    180 	{
    181 	}
    182 
    183 	virtual ~GetProcAddressExtensionCase (void)
    184 	{
    185 	}
    186 
    187 	void executeTest (void)
    188 	{
    189 		TestLog&				log			= m_testCtx.getLog();
    190 		bool					supported	= isSupported(m_extName);
    191 		const FunctionNames		funcNames	= getExtFunctionNames(m_extName);
    192 
    193 		DE_ASSERT(funcNames.numFunctions > 0);
    194 
    195 		log << TestLog::Message << m_extName << ": " << (supported ? "supported" : "not supported") << TestLog::EndMessage;
    196 		log << TestLog::Message << TestLog::EndMessage;
    197 
    198 		for (int funcNdx = 0; funcNdx < funcNames.numFunctions; funcNdx++)
    199 		{
    200 			const char*	funcName		= funcNames.functions[funcNdx];
    201 			void		(*funcPtr)(void);
    202 
    203 			funcPtr = eglGetProcAddress(funcName);
    204 			eglu::checkError(eglGetError(), "eglGetProcAddress()", __FILE__, __LINE__);
    205 
    206 			if (supported && funcPtr == 0)
    207 			{
    208 				log << TestLog::Message << "Fail, received null pointer for supported extension function: " << funcName << TestLog::EndMessage;
    209 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected null pointer");
    210 			}
    211 		}
    212 	}
    213 
    214 private:
    215 	std::string	m_extName;
    216 };
    217 
    218 // Test core functions
    219 
    220 class GetProcAddressCoreFunctionsCase : public GetProcAddressCase
    221 {
    222 public:
    223 	GetProcAddressCoreFunctionsCase (EglTestContext& eglTestCtx, const char* name, const char* description, const EGLint apiBit)
    224 		: GetProcAddressCase	(eglTestCtx, name, description)
    225 		, m_apiBit				(apiBit)
    226 	{
    227 	}
    228 
    229 	virtual ~GetProcAddressCoreFunctionsCase (void)
    230 	{
    231 	}
    232 
    233 	void executeTest (void)
    234 	{
    235 		TestLog&				log					= m_testCtx.getLog();
    236 		const bool				funcPtrSupported	= isSupported("EGL_KHR_get_all_proc_addresses");
    237 		const bool				apiSupported		= (eglu::getRenderableAPIsMask(m_eglTestCtx.getLibrary(), m_display) & m_apiBit) == m_apiBit;
    238 		const FunctionNames		funcNames			= getCoreFunctionNames(m_apiBit);
    239 
    240 		log << TestLog::Message << "EGL_KHR_get_all_proc_addresses: " << (funcPtrSupported ? "supported" : "not supported") << TestLog::EndMessage;
    241 		log << TestLog::Message << TestLog::EndMessage;
    242 
    243 		if (!apiSupported)
    244 		{
    245 			log << TestLog::Message << eglu::getConfigAttribValueStr(EGL_RENDERABLE_TYPE, m_apiBit) << " not supported by any available configuration." << TestLog::EndMessage;
    246 			log << TestLog::Message << TestLog::EndMessage;
    247 		}
    248 
    249 		for (int funcNdx = 0; funcNdx < funcNames.numFunctions; funcNdx++)
    250 		{
    251 			const char*	funcName			= funcNames.functions[funcNdx];
    252 			void		(*funcPtr)(void);
    253 
    254 			funcPtr = eglGetProcAddress(funcName);
    255 			eglu::checkError(eglGetError(), "eglGetProcAddress()", __FILE__, __LINE__);
    256 
    257 			if (apiSupported && funcPtrSupported && (funcPtr == 0))
    258 			{
    259 				log << TestLog::Message << "Fail, received null pointer for supported function: " << funcName << TestLog::EndMessage;
    260 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected null pointer");
    261 			}
    262 			else if (!apiSupported && (funcPtr != 0))
    263 			{
    264 				log << TestLog::Message << "Warning, received non-null value for unsupported function: " << funcName << TestLog::EndMessage;
    265 				m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, "Non-null value for unsupported function");
    266 			}
    267 		}
    268 	}
    269 
    270 private:
    271 	const EGLint	m_apiBit;
    272 };
    273 
    274 GetProcAddressTests::GetProcAddressTests (EglTestContext& eglTestCtx)
    275 	: TestCaseGroup(eglTestCtx, "get_proc_address", "eglGetProcAddress() tests")
    276 {
    277 }
    278 
    279 GetProcAddressTests::~GetProcAddressTests (void)
    280 {
    281 }
    282 
    283 void GetProcAddressTests::init (void)
    284 {
    285 	// extensions
    286 	{
    287 		tcu::TestCaseGroup* extensionsGroup = new tcu::TestCaseGroup(m_testCtx, "extension", "Test EGL extensions");
    288 		addChild(extensionsGroup);
    289 
    290 		for (int extNdx = 0; extNdx < DE_LENGTH_OF_ARRAY(s_extensions); extNdx++)
    291 		{
    292 			const std::string&		extName		= s_extensions[extNdx].name;
    293 			std::string				testName	(extName);
    294 
    295 			for (size_t ndx = 0; ndx < extName.length(); ndx++)
    296 				testName[ndx] = de::toLower(extName[ndx]);
    297 
    298 			extensionsGroup->addChild(new GetProcAddressExtensionCase(m_eglTestCtx, testName.c_str(), ("Test " + extName).c_str(), extName));
    299 		}
    300 	}
    301 
    302 	// core functions
    303 	{
    304 		tcu::TestCaseGroup* coreFuncGroup = new tcu::TestCaseGroup(m_testCtx, "core", "Test core functions");
    305 		addChild(coreFuncGroup);
    306 
    307 		coreFuncGroup->addChild(new GetProcAddressCoreFunctionsCase	(m_eglTestCtx,	"egl",		"Test EGL core functions",			0));
    308 		coreFuncGroup->addChild(new GetProcAddressCoreFunctionsCase	(m_eglTestCtx,	"gles",		"Test OpenGL ES core functions",	EGL_OPENGL_ES_BIT));
    309 		coreFuncGroup->addChild(new GetProcAddressCoreFunctionsCase	(m_eglTestCtx,	"gles2",	"Test OpenGL ES 2 core functions",	EGL_OPENGL_ES2_BIT));
    310 		coreFuncGroup->addChild(new GetProcAddressCoreFunctionsCase	(m_eglTestCtx,	"gles3",	"Test OpenGL ES 3 core functions",	EGL_OPENGL_ES3_BIT_KHR));
    311 	}
    312 }
    313 
    314 } // egl
    315 } // deqp
    316