/*------------------------------------------------------------------------- * 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 Simple surface construction test. *//*--------------------------------------------------------------------*/ #include "teglCreateSurfaceTests.hpp" #include "egluNativeDisplay.hpp" #include "egluNativeWindow.hpp" #include "egluNativePixmap.hpp" #include "egluUtil.hpp" #include "egluUnique.hpp" #include "eglwLibrary.hpp" #include "eglwEnums.hpp" #include "teglSimpleConfigCase.hpp" #include "tcuTestContext.hpp" #include "tcuCommandLine.hpp" #include "tcuTestLog.hpp" #include "deStringUtil.hpp" #include "deSTLUtil.hpp" #include "deUniquePtr.hpp" #include namespace deqp { namespace egl { using std::vector; using tcu::TestLog; using namespace eglw; namespace { #define EGL_MAKE_VERSION(major, minor) (((major) << 12) | (minor)) enum ApiType { LEGACY, EXTENSION, EGL15 }; void checkEGLPlatformSupport (const Library& egl) { const vector extensions = eglu::getClientExtensions(egl); if (!de::contains(extensions.begin(), extensions.end(), "EGL_EXT_platform_base")) throw tcu::NotSupportedError("Platform extension 'EGL_EXT_platform_base' not supported", "", __FILE__, __LINE__); } void checkEGL15Support (const Library& egl, EGLDisplay display) { // The EGL_VERSION string is laid out as follows: // major_version.minor_version space vendor_specific_info // Split version from vendor_specific_info std::vector tokens = de::splitString(egl.queryString(display, EGL_VERSION), ' '); // split version into major & minor std::vector values = de::splitString(tokens[0], '.'); EGLint eglVersion = EGL_MAKE_VERSION(atoi(values[0].c_str()), atoi(values[1].c_str())); if (eglVersion < EGL_MAKE_VERSION(1, 5)) throw tcu::NotSupportedError("EGL 1.5 not supported", "", __FILE__, __LINE__); } EGLSurface createWindowSurface (EGLDisplay display, EGLConfig config, eglu::NativeDisplay& nativeDisplay, eglu::NativeWindow& window, ApiType createType) { const Library& egl = nativeDisplay.getLibrary(); EGLSurface surface = EGL_NO_SURFACE; switch (createType) { case LEGACY: { surface = egl.createWindowSurface(display, config, window.getLegacyNative(), DE_NULL); EGLU_CHECK_MSG(egl, "eglCreateWindowSurface() failed"); } break; case EXTENSION: { checkEGLPlatformSupport(egl); void *nativeWindow = window.getPlatformExtension(); surface = egl.createPlatformWindowSurfaceEXT(display, config, nativeWindow, DE_NULL); EGLU_CHECK_MSG(egl, "eglCreatePlatformWindowSurfaceEXT() failed"); } break; case EGL15: { checkEGL15Support(egl, display); surface = egl.createPlatformWindowSurface(display, config, window.getPlatformNative(), DE_NULL); EGLU_CHECK_MSG(egl, "eglCreatePlatformWindowSurface() failed"); } } return surface; } EGLSurface createPixmapSurface (EGLDisplay display, EGLConfig config, eglu::NativeDisplay& nativeDisplay, eglu::NativePixmap& pixmap, ApiType createType) { const Library& egl = nativeDisplay.getLibrary(); EGLSurface surface = EGL_NO_SURFACE; switch (createType) { case LEGACY: surface = egl.createPixmapSurface(display, config, pixmap.getLegacyNative(), DE_NULL); EGLU_CHECK_MSG(egl, "eglCreatePixmapSurface() failed"); break; case EXTENSION: checkEGLPlatformSupport(egl); surface = egl.createPlatformPixmapSurfaceEXT(display, config, pixmap.getPlatformExtension(), DE_NULL); EGLU_CHECK_MSG(egl, "eglCreatePlatformPixmapSurfaceEXT() failed"); break; case EGL15: surface = egl.createPlatformPixmapSurface(display, config, pixmap.getPlatformNative(), DE_NULL); EGLU_CHECK_MSG(egl, "eglCreatePlatformPixmapSurface() failed"); break; } return surface; } class CreateWindowSurfaceCase : public SimpleConfigCase { public: CreateWindowSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, ApiType createType, const eglu::FilterList& filters) : SimpleConfigCase (eglTestCtx, name, description, filters) , m_createType (createType) { } void executeForConfig (EGLDisplay display, EGLConfig config) { const Library& egl = m_eglTestCtx.getLibrary(); TestLog& log = m_testCtx.getLog(); EGLint id = eglu::getConfigID(egl, display, config); const eglu::NativeWindowFactory& windowFactory = eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine()); // \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT switch (m_createType) { case LEGACY: { if ((windowFactory.getCapabilities() & eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_LEGACY) == 0) TCU_THROW(NotSupportedError, "Native window doesn't support legacy eglCreateWindowSurface()"); } break; case EXTENSION: { if ((windowFactory.getCapabilities() & eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_PLATFORM_EXTENSION) == 0) TCU_THROW(NotSupportedError, "Native window doesn't support eglCreatePlatformWindowSurfaceEXT()"); } break; case EGL15: { if ((windowFactory.getCapabilities() & eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_PLATFORM) == 0) TCU_THROW(NotSupportedError, "Native window doesn't support eglCreatePlatformWindowSurface()"); } break; } log << TestLog::Message << "Creating window surface with config ID " << id << TestLog::EndMessage; EGLU_CHECK_MSG(egl, "init"); { const int width = 64; const int height = 64; de::UniquePtr window (windowFactory.createWindow(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, eglu::WindowParams(width, height, eglu::parseWindowVisibility(m_testCtx.getCommandLine())))); eglu::UniqueSurface surface (egl, display, createWindowSurface(display, config, m_eglTestCtx.getNativeDisplay(), *window, m_createType)); EGLint windowWidth = 0; EGLint windowHeight = 0; EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_WIDTH, &windowWidth)); EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_HEIGHT, &windowHeight)); if (windowWidth <= 0 || windowHeight <= 0) { log << TestLog::Message << " Fail, invalid surface size " << windowWidth << "x" << windowHeight << TestLog::EndMessage; m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid surface size"); } else log << TestLog::Message << " Pass" << TestLog::EndMessage; } } private: ApiType m_createType; }; class CreatePixmapSurfaceCase : public SimpleConfigCase { public: CreatePixmapSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, ApiType createType, const eglu::FilterList& filters) : SimpleConfigCase(eglTestCtx, name, description, filters) , m_createType (createType) { } void executeForConfig (EGLDisplay display, EGLConfig config) { const Library& egl = m_eglTestCtx.getLibrary(); TestLog& log = m_testCtx.getLog(); EGLint id = eglu::getConfigID(egl, display, config); const eglu::NativePixmapFactory& pixmapFactory = eglu::selectNativePixmapFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine()); // \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT switch (m_createType) { case LEGACY: { if ((pixmapFactory.getCapabilities() & eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_LEGACY) == 0) TCU_THROW(NotSupportedError, "Native pixmap doesn't support legacy eglCreatePixmapSurface()"); } break; case EXTENSION: { if ((pixmapFactory.getCapabilities() & eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_PLATFORM_EXTENSION) == 0) TCU_THROW(NotSupportedError, "Native pixmap doesn't support eglCreatePlatformPixmapSurfaceEXT()"); } break; case EGL15: { if ((pixmapFactory.getCapabilities() & eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_PLATFORM) == 0) TCU_THROW(NotSupportedError, "Native pixmap doesn't support eglCreatePlatformPixmapSurface()"); } break; }; log << TestLog::Message << "Creating pixmap surface with config ID " << id << TestLog::EndMessage; EGLU_CHECK_MSG(egl, "init"); { const int width = 64; const int height = 64; de::UniquePtr pixmap (pixmapFactory.createPixmap(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, width, height)); eglu::UniqueSurface surface (egl, display, createPixmapSurface(display, config, m_eglTestCtx.getNativeDisplay(), *pixmap, m_createType)); EGLint pixmapWidth = 0; EGLint pixmapHeight = 0; EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_WIDTH, &pixmapWidth)); EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_HEIGHT, &pixmapHeight)); if (pixmapWidth <= 0 || pixmapHeight <= 0) { log << TestLog::Message << " Fail, invalid surface size " << pixmapWidth << "x" << pixmapHeight << TestLog::EndMessage; m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid surface size"); } else log << TestLog::Message << " Pass" << TestLog::EndMessage; } } private: ApiType m_createType; }; class CreatePbufferSurfaceCase : public SimpleConfigCase { public: CreatePbufferSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters) : SimpleConfigCase(eglTestCtx, name, description, filters) { } void executeForConfig (EGLDisplay display, EGLConfig config) { const Library& egl = m_eglTestCtx.getLibrary(); TestLog& log = m_testCtx.getLog(); EGLint id = eglu::getConfigID(egl, display, config); int width = 64; int height = 64; // \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT log << TestLog::Message << "Creating pbuffer surface with config ID " << id << TestLog::EndMessage; EGLU_CHECK_MSG(egl, "init"); // Clamp to maximums reported by implementation width = deMin32(width, eglu::getConfigAttribInt(egl, display, config, EGL_MAX_PBUFFER_WIDTH)); height = deMin32(height, eglu::getConfigAttribInt(egl, display, config, EGL_MAX_PBUFFER_HEIGHT)); if (width == 0 || height == 0) { log << TestLog::Message << " Fail, maximum pbuffer size of " << width << "x" << height << " reported" << TestLog::EndMessage; m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid maximum pbuffer size"); return; } // \todo [2011-03-23 pyry] Texture-backed variants! const EGLint attribs[] = { EGL_WIDTH, width, EGL_HEIGHT, height, EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE, EGL_NONE }; EGLSurface surface = egl.createPbufferSurface(display, config, attribs); EGLU_CHECK_MSG(egl, "Failed to create pbuffer"); TCU_CHECK(surface != EGL_NO_SURFACE); egl.destroySurface(display, surface); log << TestLog::Message << " Pass" << TestLog::EndMessage; } }; } // anonymous CreateSurfaceTests::CreateSurfaceTests (EglTestContext& eglTestCtx) : TestCaseGroup(eglTestCtx, "create_surface", "Basic surface construction tests") { } CreateSurfaceTests::~CreateSurfaceTests (void) { } template static bool surfaceType (const eglu::CandidateConfig& c) { return (c.surfaceType() & Type) == Type; } void CreateSurfaceTests::init (void) { // Window surfaces { tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "window", "Window surfaces"); addChild(windowGroup); eglu::FilterList baseFilters; baseFilters << surfaceType; vector filterLists; getDefaultFilterLists(filterLists, baseFilters); for (vector::iterator i = filterLists.begin(); i != filterLists.end(); i++) windowGroup->addChild(new CreateWindowSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), LEGACY, *i)); } // Pixmap surfaces { tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "pixmap", "Pixmap surfaces"); addChild(pixmapGroup); eglu::FilterList baseFilters; baseFilters << surfaceType; vector filterLists; getDefaultFilterLists(filterLists, baseFilters); for (vector::iterator i = filterLists.begin(); i != filterLists.end(); i++) pixmapGroup->addChild(new CreatePixmapSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), LEGACY, *i)); } // Pbuffer surfaces { tcu::TestCaseGroup* pbufferGroup = new tcu::TestCaseGroup(m_testCtx, "pbuffer", "Pbuffer surfaces"); addChild(pbufferGroup); eglu::FilterList baseFilters; baseFilters << surfaceType; vector filterLists; getDefaultFilterLists(filterLists, baseFilters); for (vector::iterator i = filterLists.begin(); i != filterLists.end(); i++) pbufferGroup->addChild(new CreatePbufferSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), *i)); } // Window surfaces with new platform extension { tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "platform_ext_window", "Window surfaces with platform extension"); addChild(windowGroup); eglu::FilterList baseFilters; baseFilters << surfaceType; vector filterLists; getDefaultFilterLists(filterLists, baseFilters); for (vector::iterator i = filterLists.begin(); i != filterLists.end(); i++) windowGroup->addChild(new CreateWindowSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), EXTENSION, *i)); } // Pixmap surfaces with new platform extension { tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "platform_ext_pixmap", "Pixmap surfaces with platform extension"); addChild(pixmapGroup); eglu::FilterList baseFilters; baseFilters << surfaceType; vector filterLists; getDefaultFilterLists(filterLists, baseFilters); for (vector::iterator i = filterLists.begin(); i != filterLists.end(); i++) pixmapGroup->addChild(new CreatePixmapSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), EXTENSION, *i)); } // // Window surfaces with EGL 1.5 CreateWindowSurface { tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "platform_window", "Window surfaces with EGL 1.5"); addChild(windowGroup); eglu::FilterList baseFilters; baseFilters << surfaceType; vector filterLists; getDefaultFilterLists(filterLists, baseFilters); for (vector::iterator i = filterLists.begin(); i != filterLists.end(); i++) windowGroup->addChild(new CreateWindowSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), EGL15, *i)); } // Pixmap surfaces with EGL 1.5 CreateWindowSurface { tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "platform_pixmap", "Pixmap surfaces with EGL 1.5"); addChild(pixmapGroup); eglu::FilterList baseFilters; baseFilters << surfaceType; vector filterLists; getDefaultFilterLists(filterLists, baseFilters); for (vector::iterator i = filterLists.begin(); i != filterLists.end(); i++) pixmapGroup->addChild(new CreatePixmapSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), EGL15, *i)); } } } // egl } // deqp