| /*------------------------------------------------------------------------- |
| * drawElements Quality Program Tester Core |
| * ---------------------------------------- |
| * |
| * 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 GL context factory using EGL. |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "egluGLContextFactory.hpp" |
| |
| #include "tcuRenderTarget.hpp" |
| #include "tcuPlatform.hpp" |
| #include "tcuCommandLine.hpp" |
| |
| #include "gluDefs.hpp" |
| |
| #include "egluDefs.hpp" |
| #include "egluUtil.hpp" |
| #include "egluGLUtil.hpp" |
| #include "egluNativeWindow.hpp" |
| #include "egluNativePixmap.hpp" |
| #include "egluStrUtil.hpp" |
| |
| #include "eglwLibrary.hpp" |
| #include "eglwEnums.hpp" |
| |
| #include "glwInitFunctions.hpp" |
| #include "glwInitES20Direct.hpp" |
| #include "glwInitES30Direct.hpp" |
| #include "glwInitES31Direct.hpp" |
| #include "glwInitES32Direct.hpp" |
| |
| #include "deDynamicLibrary.hpp" |
| #include "deSTLUtil.hpp" |
| #include "deSharedPtr.hpp" |
| |
| #include <string> |
| #include <string> |
| #include <sstream> |
| |
| using std::string; |
| using std::vector; |
| |
| // \todo [2014-03-12 pyry] Use command line arguments for libraries? |
| |
| // Default library names |
| #if !defined(DEQP_GLES2_LIBRARY_PATH) |
| # if (DE_OS == DE_OS_WIN32) |
| # define DEQP_GLES2_LIBRARY_PATH "libGLESv2.dll" |
| # else |
| # define DEQP_GLES2_LIBRARY_PATH "libGLESv2.so" |
| # endif |
| #endif |
| |
| #if !defined(DEQP_GLES3_LIBRARY_PATH) |
| # define DEQP_GLES3_LIBRARY_PATH DEQP_GLES2_LIBRARY_PATH |
| #endif |
| |
| #if !defined(DEQP_OPENGL_LIBRARY_PATH) |
| # if (DE_OS == DE_OS_WIN32) |
| # define DEQP_OPENGL_LIBRARY_PATH "opengl32.dll" |
| # else |
| # define DEQP_OPENGL_LIBRARY_PATH "libGL.so" |
| # endif |
| #endif |
| |
| namespace eglu |
| { |
| |
| using namespace eglw; |
| |
| namespace |
| { |
| |
| enum |
| { |
| DEFAULT_OFFSCREEN_WIDTH = 512, |
| DEFAULT_OFFSCREEN_HEIGHT = 512 |
| }; |
| |
| class GetProcFuncLoader : public glw::FunctionLoader |
| { |
| public: |
| GetProcFuncLoader (const Library& egl) |
| : m_egl(egl) |
| { |
| } |
| |
| glw::GenericFuncType get (const char* name) const |
| { |
| return (glw::GenericFuncType)m_egl.getProcAddress(name); |
| } |
| |
| protected: |
| const Library& m_egl; |
| }; |
| |
| class DynamicFuncLoader : public glw::FunctionLoader |
| { |
| public: |
| DynamicFuncLoader (de::DynamicLibrary* library) |
| : m_library(library) |
| { |
| } |
| |
| glw::GenericFuncType get (const char* name) const |
| { |
| return (glw::GenericFuncType)m_library->getFunction(name); |
| } |
| |
| private: |
| de::DynamicLibrary* m_library; |
| }; |
| |
| class RenderContext : public GLRenderContext |
| { |
| public: |
| RenderContext (const NativeDisplayFactory* displayFactory, const NativeWindowFactory* windowFactory, const NativePixmapFactory* pixmapFactory, const glu::RenderConfig& config, const glu::RenderContext* sharedContext = DE_NULL); |
| virtual ~RenderContext (void); |
| |
| virtual glu::ContextType getType (void) const { return m_renderConfig.type; } |
| virtual const glw::Functions& getFunctions (void) const { return m_glFunctions; } |
| virtual const tcu::RenderTarget& getRenderTarget (void) const { return m_glRenderTarget; } |
| virtual void postIterate (void); |
| |
| virtual EGLDisplay getEGLDisplay (void) const { return m_eglDisplay; } |
| virtual EGLContext getEGLContext (void) const { return m_eglContext; } |
| virtual EGLConfig getEGLConfig (void) const { return m_eglConfig; } |
| virtual const eglw::Library& getLibrary (void) const { return m_display->getLibrary(); } |
| |
| virtual eglw::GenericFuncType getProcAddress (const char* name) const; |
| |
| virtual void makeCurrent (void); |
| |
| private: |
| void create (const NativeDisplayFactory* displayFactory, const NativeWindowFactory* windowFactory, const NativePixmapFactory* pixmapFactory, const glu::RenderConfig& config, const glu::RenderContext* sharedContext); |
| void destroy (void); |
| |
| const glu::RenderConfig m_renderConfig; |
| const NativeWindowFactory* const m_nativeWindowFactory; // Stored in case window must be re-created |
| |
| de::SharedPtr<NativeDisplay> m_display; |
| NativeWindow* m_window; |
| NativePixmap* m_pixmap; |
| |
| EGLDisplay m_eglDisplay; |
| EGLConfig m_eglConfig; |
| EGLSurface m_eglSurface; |
| EGLContext m_eglContext; |
| EGLContext m_eglSharedContext; |
| |
| tcu::RenderTarget m_glRenderTarget; |
| de::DynamicLibrary* m_dynamicGLLibrary; |
| glw::Functions m_glFunctions; |
| }; |
| |
| RenderContext::RenderContext (const NativeDisplayFactory* displayFactory, const NativeWindowFactory* windowFactory, const NativePixmapFactory* pixmapFactory, const glu::RenderConfig& config, const glu::RenderContext* sharedContext) |
| : m_renderConfig (config) |
| , m_nativeWindowFactory (windowFactory) |
| , m_display (DE_NULL) |
| , m_window (DE_NULL) |
| , m_pixmap (DE_NULL) |
| |
| , m_eglDisplay (EGL_NO_DISPLAY) |
| , m_eglSurface (EGL_NO_SURFACE) |
| , m_eglContext (EGL_NO_CONTEXT) |
| , m_eglSharedContext (EGL_NO_CONTEXT) |
| |
| , m_dynamicGLLibrary (DE_NULL) |
| { |
| DE_ASSERT(displayFactory); |
| |
| try |
| { |
| create(displayFactory, windowFactory, pixmapFactory, config, sharedContext); |
| } |
| catch (...) |
| { |
| destroy(); |
| throw; |
| } |
| } |
| |
| RenderContext::~RenderContext(void) |
| { |
| try |
| { |
| destroy(); |
| } |
| catch (...) |
| { |
| // destroy() calls EGL functions that are checked and may throw exceptions |
| } |
| |
| delete m_window; |
| delete m_pixmap; |
| delete m_dynamicGLLibrary; |
| } |
| |
| static WindowParams::Visibility getNativeWindowVisibility (glu::RenderConfig::Visibility visibility) |
| { |
| using glu::RenderConfig; |
| |
| switch (visibility) |
| { |
| case RenderConfig::VISIBILITY_HIDDEN: return WindowParams::VISIBILITY_HIDDEN; |
| case RenderConfig::VISIBILITY_VISIBLE: return WindowParams::VISIBILITY_VISIBLE; |
| case RenderConfig::VISIBILITY_FULLSCREEN: return WindowParams::VISIBILITY_FULLSCREEN; |
| default: |
| DE_ASSERT((int)visibility == RenderConfig::DONT_CARE); |
| return WindowParams::VISIBILITY_DONT_CARE; |
| } |
| } |
| |
| typedef std::pair<NativeWindow*, EGLSurface> WindowSurfacePair; |
| typedef std::pair<NativePixmap*, EGLSurface> PixmapSurfacePair; |
| |
| WindowSurfacePair createWindow (NativeDisplay* nativeDisplay, const NativeWindowFactory* windowFactory, EGLDisplay eglDisplay, EGLConfig eglConfig, const glu::RenderConfig& config) |
| { |
| const int width = (config.width == glu::RenderConfig::DONT_CARE ? WindowParams::SIZE_DONT_CARE : config.width); |
| const int height = (config.height == glu::RenderConfig::DONT_CARE ? WindowParams::SIZE_DONT_CARE : config.height); |
| const WindowParams::Visibility visibility = getNativeWindowVisibility(config.windowVisibility); |
| NativeWindow* nativeWindow = DE_NULL; |
| EGLSurface surface = EGL_NO_SURFACE; |
| const EGLAttrib attribList[] = { EGL_NONE }; |
| |
| nativeWindow = windowFactory->createWindow(nativeDisplay, eglDisplay, eglConfig, &attribList[0], WindowParams(width, height, visibility)); |
| |
| try |
| { |
| surface = eglu::createWindowSurface(*nativeDisplay, *nativeWindow, eglDisplay, eglConfig, attribList); |
| } |
| catch (...) |
| { |
| delete nativeWindow; |
| throw; |
| } |
| |
| return WindowSurfacePair(nativeWindow, surface); |
| } |
| |
| PixmapSurfacePair createPixmap (NativeDisplay* nativeDisplay, const NativePixmapFactory* pixmapFactory, EGLDisplay eglDisplay, EGLConfig eglConfig, const glu::RenderConfig& config) |
| { |
| const int width = (config.width == glu::RenderConfig::DONT_CARE ? DEFAULT_OFFSCREEN_WIDTH : config.width); |
| const int height = (config.height == glu::RenderConfig::DONT_CARE ? DEFAULT_OFFSCREEN_HEIGHT : config.height); |
| NativePixmap* nativePixmap = DE_NULL; |
| EGLSurface surface = EGL_NO_SURFACE; |
| const EGLAttrib attribList[] = { EGL_NONE }; |
| |
| nativePixmap = pixmapFactory->createPixmap(nativeDisplay, eglDisplay, eglConfig, &attribList[0], width, height); |
| |
| try |
| { |
| surface = eglu::createPixmapSurface(*nativeDisplay, *nativePixmap, eglDisplay, eglConfig, attribList); |
| } |
| catch (...) |
| { |
| delete nativePixmap; |
| throw; |
| } |
| |
| return PixmapSurfacePair(nativePixmap, surface); |
| } |
| |
| EGLSurface createPBuffer (const Library& egl, EGLDisplay display, EGLConfig eglConfig, const glu::RenderConfig& config) |
| { |
| const int width = (config.width == glu::RenderConfig::DONT_CARE ? DEFAULT_OFFSCREEN_WIDTH : config.width); |
| const int height = (config.height == glu::RenderConfig::DONT_CARE ? DEFAULT_OFFSCREEN_HEIGHT : config.height); |
| EGLSurface surface; |
| const EGLint attribList[] = |
| { |
| EGL_WIDTH, width, |
| EGL_HEIGHT, height, |
| EGL_NONE |
| }; |
| |
| surface = egl.createPbufferSurface(display, eglConfig, &(attribList[0])); |
| EGLU_CHECK_MSG(egl, "eglCreatePbufferSurface()"); |
| |
| return surface; |
| } |
| |
| void RenderContext::makeCurrent (void) |
| { |
| const Library& egl = m_display->getLibrary(); |
| |
| EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext)); |
| } |
| |
| glw::GenericFuncType RenderContext::getProcAddress (const char* name) const |
| { |
| return (glw::GenericFuncType)m_display->getLibrary().getProcAddress(name); |
| } |
| |
| void RenderContext::create (const NativeDisplayFactory* displayFactory, const NativeWindowFactory* windowFactory, const NativePixmapFactory* pixmapFactory, const glu::RenderConfig& config, const glu::RenderContext *sharedContext) |
| { |
| glu::RenderConfig::SurfaceType surfaceType = config.surfaceType; |
| |
| DE_ASSERT(displayFactory); |
| |
| if (DE_NULL == sharedContext) |
| m_display = de::SharedPtr<NativeDisplay>(displayFactory->createDisplay()); |
| else |
| { |
| const RenderContext* context = dynamic_cast<const RenderContext*>(sharedContext); |
| m_eglSharedContext = context->m_eglContext; |
| m_display = context->m_display; |
| } |
| |
| m_eglDisplay = eglu::getDisplay(*m_display); |
| const Library& egl = m_display->getLibrary(); |
| |
| { |
| EGLint major = 0; |
| EGLint minor = 0; |
| EGLU_CHECK_CALL(egl, initialize(m_eglDisplay, &major, &minor)); |
| } |
| |
| m_eglConfig = chooseConfig(egl, m_eglDisplay, config); |
| |
| if (surfaceType == glu::RenderConfig::SURFACETYPE_DONT_CARE) |
| { |
| // Choose based on what selected configuration supports |
| const EGLint supportedTypes = eglu::getConfigAttribInt(egl, m_eglDisplay, m_eglConfig, EGL_SURFACE_TYPE); |
| |
| if ((supportedTypes & EGL_WINDOW_BIT) != 0) |
| surfaceType = glu::RenderConfig::SURFACETYPE_WINDOW; |
| else if ((supportedTypes & EGL_PBUFFER_BIT) != 0) |
| surfaceType = glu::RenderConfig::SURFACETYPE_OFFSCREEN_GENERIC; |
| else if ((supportedTypes & EGL_PIXMAP_BIT) != 0) |
| surfaceType = glu::RenderConfig::SURFACETYPE_OFFSCREEN_NATIVE; |
| else |
| throw tcu::NotSupportedError("Selected EGL config doesn't support any surface types", DE_NULL, __FILE__, __LINE__); |
| } |
| |
| switch (surfaceType) |
| { |
| case glu::RenderConfig::SURFACETYPE_WINDOW: |
| { |
| if (windowFactory) |
| { |
| const WindowSurfacePair windowSurface = createWindow(m_display.get(), windowFactory, m_eglDisplay, m_eglConfig, config); |
| m_window = windowSurface.first; |
| m_eglSurface = windowSurface.second; |
| } |
| else |
| throw tcu::NotSupportedError("EGL platform doesn't support windows", DE_NULL, __FILE__, __LINE__); |
| break; |
| } |
| |
| case glu::RenderConfig::SURFACETYPE_OFFSCREEN_NATIVE: |
| { |
| if (pixmapFactory) |
| { |
| const PixmapSurfacePair pixmapSurface = createPixmap(m_display.get(), pixmapFactory, m_eglDisplay, m_eglConfig, config); |
| m_pixmap = pixmapSurface.first; |
| m_eglSurface = pixmapSurface.second; |
| } |
| else |
| throw tcu::NotSupportedError("EGL platform doesn't support pixmaps", DE_NULL, __FILE__, __LINE__); |
| break; |
| } |
| |
| case glu::RenderConfig::SURFACETYPE_OFFSCREEN_GENERIC: |
| m_eglSurface = createPBuffer(egl, m_eglDisplay, m_eglConfig, config); |
| break; |
| |
| default: |
| throw tcu::InternalError("Invalid surface type"); |
| } |
| |
| m_eglContext = createGLContext(egl, m_eglDisplay, m_eglConfig, config.type, m_eglSharedContext, config.resetNotificationStrategy); |
| |
| EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext)); |
| |
| // Init core functions |
| |
| if (hasExtension(egl, m_eglDisplay, "EGL_KHR_get_all_proc_addresses")) |
| { |
| // Use eglGetProcAddress() for core functions |
| GetProcFuncLoader funcLoader(egl); |
| glu::initCoreFunctions(&m_glFunctions, &funcLoader, config.type.getAPI()); |
| } |
| #if defined(DEQP_GLES2_DIRECT_LINK) |
| else if (config.type.getAPI() == glu::ApiType::es(2,0)) |
| { |
| glw::initES20Direct(&m_glFunctions); |
| } |
| #endif |
| #if defined(DEQP_GLES3_DIRECT_LINK) |
| else if (config.type.getAPI() == glu::ApiType::es(3,0)) |
| { |
| glw::initES30Direct(&m_glFunctions); |
| } |
| #endif |
| #if defined(DEQP_GLES31_DIRECT_LINK) |
| else if (config.type.getAPI() == glu::ApiType::es(3,1)) |
| { |
| glw::initES31Direct(&m_glFunctions); |
| } |
| #endif |
| #if defined(DEQP_GLES32_DIRECT_LINK) |
| else if (config.type.getAPI() == glu::ApiType::es(3,2)) |
| { |
| glw::initES32Direct(&m_glFunctions); |
| } |
| #endif |
| else |
| { |
| const char* libraryPath = DE_NULL; |
| |
| if (glu::isContextTypeES(config.type)) |
| { |
| if (config.type.getMinorVersion() <= 2) |
| libraryPath = DEQP_GLES2_LIBRARY_PATH; |
| else |
| libraryPath = DEQP_GLES3_LIBRARY_PATH; |
| } |
| else |
| libraryPath = DEQP_OPENGL_LIBRARY_PATH; |
| |
| m_dynamicGLLibrary = new de::DynamicLibrary(libraryPath); |
| |
| DynamicFuncLoader funcLoader(m_dynamicGLLibrary); |
| glu::initCoreFunctions(&m_glFunctions, &funcLoader, config.type.getAPI()); |
| } |
| |
| // Init extension functions |
| { |
| GetProcFuncLoader extLoader(egl); |
| glu::initExtensionFunctions(&m_glFunctions, &extLoader, config.type.getAPI()); |
| } |
| |
| { |
| EGLint width, height, depthBits, stencilBits, numSamples; |
| tcu::PixelFormat pixelFmt; |
| |
| egl.querySurface(m_eglDisplay, m_eglSurface, EGL_WIDTH, &width); |
| egl.querySurface(m_eglDisplay, m_eglSurface, EGL_HEIGHT, &height); |
| |
| egl.getConfigAttrib(m_eglDisplay, m_eglConfig, EGL_RED_SIZE, &pixelFmt.redBits); |
| egl.getConfigAttrib(m_eglDisplay, m_eglConfig, EGL_GREEN_SIZE, &pixelFmt.greenBits); |
| egl.getConfigAttrib(m_eglDisplay, m_eglConfig, EGL_BLUE_SIZE, &pixelFmt.blueBits); |
| egl.getConfigAttrib(m_eglDisplay, m_eglConfig, EGL_ALPHA_SIZE, &pixelFmt.alphaBits); |
| |
| egl.getConfigAttrib(m_eglDisplay, m_eglConfig, EGL_DEPTH_SIZE, &depthBits); |
| egl.getConfigAttrib(m_eglDisplay, m_eglConfig, EGL_STENCIL_SIZE, &stencilBits); |
| egl.getConfigAttrib(m_eglDisplay, m_eglConfig, EGL_SAMPLES, &numSamples); |
| |
| EGLU_CHECK_MSG(egl, "Failed to query config attributes"); |
| |
| m_glRenderTarget = tcu::RenderTarget(width, height, pixelFmt, depthBits, stencilBits, numSamples); |
| } |
| |
| egl.swapInterval(m_eglDisplay, 0); |
| } |
| |
| void RenderContext::destroy (void) |
| { |
| if (m_eglDisplay != EGL_NO_DISPLAY) |
| { |
| const Library& egl = m_display->getLibrary(); |
| |
| EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); |
| |
| if (m_eglSurface != EGL_NO_SURFACE) |
| EGLU_CHECK_CALL(egl, destroySurface(m_eglDisplay, m_eglSurface)); |
| |
| if (m_eglContext != EGL_NO_CONTEXT) |
| EGLU_CHECK_CALL(egl, destroyContext(m_eglDisplay, m_eglContext)); |
| |
| if (m_eglSharedContext == EGL_NO_CONTEXT) |
| EGLU_CHECK_CALL(egl, terminate(m_eglDisplay)); |
| |
| m_eglDisplay = EGL_NO_DISPLAY; |
| m_eglSurface = EGL_NO_SURFACE; |
| m_eglContext = EGL_NO_CONTEXT; |
| } |
| |
| delete m_window; |
| delete m_pixmap; |
| delete m_dynamicGLLibrary; |
| |
| m_window = DE_NULL; |
| m_pixmap = DE_NULL; |
| m_dynamicGLLibrary = DE_NULL; |
| } |
| |
| void RenderContext::postIterate (void) |
| { |
| const Library& egl = m_display->getLibrary(); |
| |
| if (m_window) |
| { |
| EGLBoolean swapOk = egl.swapBuffers(m_eglDisplay, m_eglSurface); |
| EGLint error = egl.getError(); |
| const bool badWindow = error == EGL_BAD_SURFACE || error == EGL_BAD_NATIVE_WINDOW; |
| |
| if (!swapOk && !badWindow) |
| throw tcu::ResourceError(string("eglSwapBuffers() failed: ") + getErrorStr(error).toString()); |
| |
| try |
| { |
| m_window->processEvents(); |
| } |
| catch (const WindowDestroyedError&) |
| { |
| tcu::print("Warning: Window destroyed, recreating...\n"); |
| |
| EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); |
| EGLU_CHECK_CALL(egl, destroySurface(m_eglDisplay, m_eglSurface)); |
| m_eglSurface = EGL_NO_SURFACE; |
| |
| delete m_window; |
| m_window = DE_NULL; |
| |
| try |
| { |
| WindowSurfacePair windowSurface = createWindow(m_display.get(), m_nativeWindowFactory, m_eglDisplay, m_eglConfig, m_renderConfig); |
| m_window = windowSurface.first; |
| m_eglSurface = windowSurface.second; |
| |
| EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext)); |
| |
| swapOk = EGL_TRUE; |
| error = EGL_SUCCESS; |
| } |
| catch (const std::exception& e) |
| { |
| if (m_eglSurface) |
| { |
| egl.makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); |
| egl.destroySurface(m_eglDisplay, m_eglSurface); |
| m_eglSurface = EGL_NO_SURFACE; |
| } |
| |
| delete m_window; |
| m_window = DE_NULL; |
| |
| throw tcu::ResourceError(string("Failed to re-create window: ") + e.what()); |
| } |
| } |
| |
| if (!swapOk) |
| { |
| DE_ASSERT(badWindow); |
| throw tcu::ResourceError(string("eglSwapBuffers() failed: ") + getErrorStr(error).toString()); |
| } |
| |
| // Refresh dimensions |
| { |
| int newWidth = 0; |
| int newHeight = 0; |
| |
| egl.querySurface(m_eglDisplay, m_eglSurface, EGL_WIDTH, &newWidth); |
| egl.querySurface(m_eglDisplay, m_eglSurface, EGL_HEIGHT, &newHeight); |
| EGLU_CHECK_MSG(egl, "Failed to query window size"); |
| |
| if (newWidth != m_glRenderTarget.getWidth() || |
| newHeight != m_glRenderTarget.getHeight()) |
| { |
| tcu::print("Warning: Window size changed (%dx%d -> %dx%d), test results might be invalid!\n", |
| m_glRenderTarget.getWidth(), m_glRenderTarget.getHeight(), newWidth, newHeight); |
| |
| m_glRenderTarget = tcu::RenderTarget(newWidth, newHeight, |
| m_glRenderTarget.getPixelFormat(), |
| m_glRenderTarget.getDepthBits(), |
| m_glRenderTarget.getStencilBits(), |
| m_glRenderTarget.getNumSamples()); |
| } |
| } |
| } |
| else |
| m_glFunctions.flush(); |
| } |
| |
| } // anonymous |
| |
| GLContextFactory::GLContextFactory (const NativeDisplayFactoryRegistry& displayFactoryRegistry) |
| : glu::ContextFactory ("egl", "EGL OpenGL Context") |
| , m_displayFactoryRegistry (displayFactoryRegistry) |
| { |
| } |
| |
| glu::RenderContext* GLContextFactory::createContext (const glu::RenderConfig& config, const tcu::CommandLine& cmdLine, const glu::RenderContext *sharedContext) const |
| { |
| const NativeDisplayFactory& displayFactory = selectNativeDisplayFactory(m_displayFactoryRegistry, cmdLine); |
| |
| const NativeWindowFactory* windowFactory; |
| const NativePixmapFactory* pixmapFactory; |
| |
| try |
| { |
| windowFactory = &selectNativeWindowFactory(displayFactory, cmdLine); |
| } |
| catch (const tcu::NotSupportedError&) |
| { |
| windowFactory = DE_NULL; |
| } |
| |
| try |
| { |
| pixmapFactory = &selectNativePixmapFactory(displayFactory, cmdLine); |
| } |
| catch (const tcu::NotSupportedError&) |
| { |
| pixmapFactory = DE_NULL; |
| } |
| |
| return new RenderContext(&displayFactory, windowFactory, pixmapFactory, config, sharedContext); |
| } |
| |
| } // eglu |