| /*------------------------------------------------------------------------- |
| * drawElements Quality Program EGL Module |
| * --------------------------------------- |
| * |
| * Copyright 2014 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| *//*! |
| * \file |
| * \brief EGL Test Case |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "teglTestCase.hpp" |
| |
| #include "tcuPlatform.hpp" |
| |
| #include "egluUtil.hpp" |
| #include "egluGLFunctionLoader.hpp" |
| #include "egluPlatform.hpp" |
| |
| #include "gluRenderContext.hpp" |
| #include "glwInitFunctions.hpp" |
| |
| #include <set> |
| |
| using std::vector; |
| using std::set; |
| |
| namespace deqp |
| { |
| namespace egl |
| { |
| |
| namespace |
| { |
| |
| void split (std::vector<std::string>& dst, const std::string& src) |
| { |
| size_t start = 0; |
| size_t end = std::string::npos; |
| |
| while ((end = src.find(' ', start)) != std::string::npos) |
| { |
| dst.push_back(src.substr(start, end-start)); |
| start = end+1; |
| } |
| |
| if (start < end) |
| dst.push_back(src.substr(start, end-start)); |
| } |
| |
| EGLint parseAPI (const std::string& api) |
| { |
| if (api == "OpenGL") |
| return EGL_OPENGL_API; |
| else if (api == "OpenGL_ES") |
| return EGL_OPENGL_ES_API; |
| else if (api == "OpenVG") |
| return EGL_OPENVG_API; |
| else |
| { |
| tcu::print("Warning: Unknown API '%s'", api.c_str()); |
| return 0; |
| } |
| } |
| |
| } // anonymous |
| |
| EglTestContext::EglTestContext (tcu::TestContext& testCtx, const eglu::NativeDisplayFactory& displayFactory, const eglu::NativeWindowFactory* windowFactory, const eglu::NativePixmapFactory* pixmapFactory) |
| : m_testCtx (testCtx) |
| , m_displayFactory (displayFactory) |
| , m_windowFactory (windowFactory) |
| , m_pixmapFactory (pixmapFactory) |
| , m_defaultNativeDisplay (DE_NULL) |
| , m_defaultEGLDisplay (DE_NULL) |
| { |
| // Temporarily allocate default display for storing config list |
| try |
| { |
| EGLDisplay eglDisplay = EGL_NO_DISPLAY; |
| EGLint majorVersion; |
| EGLint minorVersion; |
| |
| m_defaultNativeDisplay = m_displayFactory.createDisplay(); |
| |
| eglDisplay = eglu::getDisplay(*m_defaultNativeDisplay); |
| TCU_CHECK_EGL_CALL(eglInitialize(eglDisplay, &majorVersion, &minorVersion)); |
| |
| m_defaultEGLDisplay = new tcu::egl::Display(eglDisplay, majorVersion, minorVersion); |
| |
| // Create config list |
| { |
| vector<EGLConfig> configs; |
| set<EGLint> idSet; // For checking for duplicate config IDs |
| |
| m_defaultEGLDisplay->getConfigs(configs); |
| |
| m_configs.resize(configs.size()); |
| for (int ndx = 0; ndx < (int)configs.size(); ndx++) |
| { |
| m_defaultEGLDisplay->describeConfig(configs[ndx], m_configs[ndx]); |
| |
| EGLint id = m_configs[ndx].configId; |
| if (idSet.find(id) != idSet.end()) |
| tcu::print("Warning: Duplicate config ID %d\n", id); |
| idSet.insert(id); |
| } |
| } |
| |
| // Query supported APIs |
| { |
| const char* clientAPIs = eglQueryString(eglDisplay, EGL_CLIENT_APIS); |
| std::vector<std::string> apis; |
| TCU_CHECK(clientAPIs); |
| |
| split(apis, clientAPIs); |
| for (std::vector<std::string>::const_iterator apiIter = apis.begin(); apiIter != apis.end(); apiIter++) |
| { |
| EGLint parsedAPI = parseAPI(*apiIter); |
| if (parsedAPI != 0) |
| m_supportedAPIs.insert(parsedAPI); |
| } |
| } |
| |
| delete m_defaultEGLDisplay; |
| m_defaultEGLDisplay = DE_NULL; |
| delete m_defaultNativeDisplay; |
| m_defaultNativeDisplay = DE_NULL; |
| } |
| catch (...) |
| { |
| delete m_defaultEGLDisplay; |
| m_defaultEGLDisplay = DE_NULL; |
| delete m_defaultNativeDisplay; |
| m_defaultNativeDisplay = DE_NULL; |
| throw; |
| } |
| } |
| |
| EglTestContext::~EglTestContext (void) |
| { |
| for (GLLibraryMap::iterator iter = m_glLibraries.begin(); iter != m_glLibraries.end(); ++iter) |
| delete iter->second; |
| |
| delete m_defaultEGLDisplay; |
| delete m_defaultNativeDisplay; |
| } |
| |
| void EglTestContext::createDefaultDisplay (void) |
| { |
| EGLDisplay eglDisplay = EGL_NO_DISPLAY; |
| EGLint majorVersion; |
| EGLint minorVersion; |
| |
| DE_ASSERT(!m_defaultEGLDisplay); |
| DE_ASSERT(!m_defaultNativeDisplay); |
| |
| try |
| { |
| m_defaultNativeDisplay = m_displayFactory.createDisplay(); |
| |
| eglDisplay = eglu::getDisplay(*m_defaultNativeDisplay); |
| TCU_CHECK_EGL_CALL(eglInitialize(eglDisplay, &majorVersion, &minorVersion)); |
| |
| m_defaultEGLDisplay = new tcu::egl::Display(eglDisplay, majorVersion, minorVersion); |
| } |
| catch (const std::exception&) |
| { |
| delete m_defaultEGLDisplay; |
| m_defaultEGLDisplay = DE_NULL; |
| delete m_defaultNativeDisplay; |
| m_defaultNativeDisplay = DE_NULL; |
| throw; |
| } |
| } |
| |
| const eglu::NativeWindowFactory& EglTestContext::getNativeWindowFactory (void) const |
| { |
| if (m_windowFactory) |
| return *m_windowFactory; |
| else |
| throw tcu::NotSupportedError("No default native window factory available", "", __FILE__, __LINE__); |
| } |
| |
| const eglu::NativePixmapFactory& EglTestContext::getNativePixmapFactory (void) const |
| { |
| if (m_pixmapFactory) |
| return *m_pixmapFactory; |
| else |
| throw tcu::NotSupportedError("No default native pixmap factory available", "", __FILE__, __LINE__); |
| } |
| |
| void EglTestContext::destroyDefaultDisplay (void) |
| { |
| DE_ASSERT(m_defaultEGLDisplay); |
| DE_ASSERT(m_defaultNativeDisplay); |
| |
| delete m_defaultEGLDisplay; |
| m_defaultEGLDisplay = DE_NULL; |
| |
| delete m_defaultNativeDisplay; |
| m_defaultNativeDisplay = DE_NULL; |
| } |
| |
| eglu::NativeWindow* EglTestContext::createNativeWindow (EGLDisplay display, EGLConfig config, const EGLAttrib* attribList, int width, int height, eglu::WindowParams::Visibility visibility) |
| { |
| if (!m_windowFactory) |
| throw tcu::NotSupportedError("Windows not supported", "", __FILE__, __LINE__); |
| |
| return m_windowFactory->createWindow(m_defaultNativeDisplay, display, config, attribList, eglu::WindowParams(width, height, visibility)); |
| } |
| |
| eglu::NativePixmap* EglTestContext::createNativePixmap (EGLDisplay display, EGLConfig config, const EGLAttrib* attribList, int width, int height) |
| { |
| if (!m_pixmapFactory) |
| throw tcu::NotSupportedError("Pixmaps not supported", "", __FILE__, __LINE__); |
| |
| return m_pixmapFactory->createPixmap(m_defaultNativeDisplay, display, config, attribList, width, height); |
| } |
| |
| // \todo [2014-10-06 pyry] Quite hacky, expose ApiType internals? |
| static deUint32 makeKey (glu::ApiType apiType) |
| { |
| return (apiType.getMajorVersion() << 8) | (apiType.getMinorVersion() << 4) | apiType.getProfile(); |
| } |
| |
| const tcu::FunctionLibrary* EglTestContext::getGLLibrary (glu::ApiType apiType) const |
| { |
| tcu::FunctionLibrary* library = DE_NULL; |
| const deUint32 key = makeKey(apiType); |
| GLLibraryMap::iterator iter = m_glLibraries.find(key); |
| |
| if (iter == m_glLibraries.end()) |
| { |
| library = m_testCtx.getPlatform().getEGLPlatform().createDefaultGLFunctionLibrary(apiType, m_testCtx.getCommandLine()); |
| m_glLibraries.insert(std::make_pair(key, library)); |
| } |
| else |
| library = iter->second; |
| |
| return library; |
| } |
| |
| deFunctionPtr EglTestContext::getGLFunction (glu::ApiType apiType, const char* name) const |
| { |
| // \todo [2014-03-11 pyry] This requires fall-back to eglGetProcAddress(), right? |
| const tcu::FunctionLibrary* const library = getGLLibrary(apiType); |
| return library->getFunction(name); |
| } |
| |
| void EglTestContext::getGLFunctions (glw::Functions& gl, glu::ApiType apiType) const |
| { |
| const tcu::FunctionLibrary* const library = getGLLibrary(apiType); |
| const eglu::GLFunctionLoader loader (library); |
| |
| // \note There may not be current context, so we can't use initFunctions(). |
| glu::initCoreFunctions(&gl, &loader, apiType); |
| } |
| |
| TestCaseGroup::TestCaseGroup (EglTestContext& eglTestCtx, const char* name, const char* description) |
| : tcu::TestCaseGroup (eglTestCtx.getTestContext(), name, description) |
| , m_eglTestCtx (eglTestCtx) |
| { |
| } |
| |
| TestCaseGroup::~TestCaseGroup (void) |
| { |
| } |
| |
| TestCase::TestCase (EglTestContext& eglTestCtx, const char* name, const char* description) |
| : tcu::TestCase (eglTestCtx.getTestContext(), name, description) |
| , m_eglTestCtx (eglTestCtx) |
| { |
| } |
| |
| TestCase::TestCase (EglTestContext& eglTestCtx, tcu::TestNodeType type, const char* name, const char* description) |
| : tcu::TestCase (eglTestCtx.getTestContext(), type, name, description) |
| , m_eglTestCtx (eglTestCtx) |
| { |
| } |
| |
| TestCase::~TestCase (void) |
| { |
| } |
| |
| } // egl |
| } // deqp |