| /*------------------------------------------------------------------------- |
| * 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 WGL GL context factory. |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "tcuWGLContextFactory.hpp" |
| |
| #include "gluRenderConfig.hpp" |
| #include "tcuRenderTarget.hpp" |
| #include "tcuWin32Window.hpp" |
| #include "glwFunctions.hpp" |
| #include "glwInitFunctions.hpp" |
| #include "deString.h" |
| |
| using std::vector; |
| |
| namespace tcu |
| { |
| namespace wgl |
| { |
| namespace |
| { |
| |
| enum |
| { |
| DEFAULT_WINDOW_WIDTH = 400, |
| DEFAULT_WINDOW_HEIGHT = 300 |
| }; |
| |
| class WGLFunctionLoader : public glw::FunctionLoader |
| { |
| public: |
| WGLFunctionLoader(const wgl::Context &context) : m_context(context) |
| { |
| } |
| |
| glw::GenericFuncType get(const char *name) const |
| { |
| return (glw::GenericFuncType)m_context.getGLFunction(name); |
| } |
| |
| private: |
| const wgl::Context &m_context; |
| }; |
| |
| class WGLContext : public glu::RenderContext |
| { |
| public: |
| WGLContext(HINSTANCE instance, const wgl::Core &wglCore, const WGLContext *sharedContext, |
| const glu::RenderConfig &config); |
| ~WGLContext(void); |
| |
| glu::ContextType getType(void) const |
| { |
| return m_contextType; |
| } |
| const RenderTarget &getRenderTarget(void) const |
| { |
| return m_renderTarget; |
| } |
| void postIterate(void); |
| const glw::Functions &getFunctions(void) const |
| { |
| return m_functions; |
| } |
| |
| glw::GenericFuncType getProcAddress(const char *name) const; |
| |
| void makeCurrent(void); |
| |
| private: |
| WGLContext(const WGLContext &other); |
| WGLContext &operator=(const WGLContext &other); |
| |
| glu::ContextType m_contextType; |
| |
| win32::Window m_window; |
| wgl::Context *m_context; |
| |
| tcu::RenderTarget m_renderTarget; |
| glw::Functions m_functions; |
| }; |
| |
| WGLContext::WGLContext(HINSTANCE instance, const wgl::Core &wglCore, const WGLContext *sharedContext, |
| const glu::RenderConfig &config) |
| : m_contextType(config.type) |
| , m_window(instance, config.width != glu::RenderConfig::DONT_CARE ? config.width : DEFAULT_WINDOW_WIDTH, |
| config.height != glu::RenderConfig::DONT_CARE ? config.height : DEFAULT_WINDOW_HEIGHT) |
| , m_context(DE_NULL) |
| { |
| if (config.surfaceType != glu::RenderConfig::SURFACETYPE_WINDOW && |
| config.surfaceType != glu::RenderConfig::SURFACETYPE_DONT_CARE) |
| throw NotSupportedError("Unsupported surface type"); |
| |
| HDC deviceCtx = m_window.getDeviceContext(); |
| int pixelFormat = 0; |
| |
| if (config.id != glu::RenderConfig::DONT_CARE) |
| pixelFormat = config.id; |
| else |
| pixelFormat = wgl::choosePixelFormat(wglCore, deviceCtx, config); |
| |
| if (pixelFormat < 0) |
| throw NotSupportedError("Compatible WGL pixel format not found"); |
| |
| const wgl::Context *sharedCtx = DE_NULL; |
| if (DE_NULL != sharedContext) |
| sharedCtx = sharedContext->m_context; |
| |
| m_context = |
| new wgl::Context(&wglCore, deviceCtx, sharedCtx, config.type, pixelFormat, config.resetNotificationStrategy); |
| |
| try |
| { |
| // Describe selected config & get render target props. |
| const wgl::PixelFormatInfo info = wglCore.getPixelFormatInfo(deviceCtx, pixelFormat); |
| const IVec2 size = m_window.getSize(); |
| |
| m_renderTarget = tcu::RenderTarget( |
| size.x(), size.y(), tcu::PixelFormat(info.redBits, info.greenBits, info.blueBits, info.alphaBits), |
| info.depthBits, info.stencilBits, info.sampleBuffers ? info.samples : 0); |
| |
| // Load functions |
| { |
| WGLFunctionLoader funcLoader(*m_context); |
| glu::initFunctions(&m_functions, &funcLoader, config.type.getAPI()); |
| } |
| |
| if (config.windowVisibility != glu::RenderConfig::VISIBILITY_VISIBLE && |
| config.windowVisibility != glu::RenderConfig::VISIBILITY_HIDDEN) |
| throw NotSupportedError("Unsupported window visibility mode"); |
| |
| m_window.setVisible(config.windowVisibility != glu::RenderConfig::VISIBILITY_HIDDEN); |
| } |
| catch (...) |
| { |
| delete m_context; |
| throw; |
| } |
| } |
| |
| WGLContext::~WGLContext(void) |
| { |
| delete m_context; |
| } |
| |
| glw::GenericFuncType WGLContext::getProcAddress(const char *name) const |
| { |
| return m_context->getGLFunction(name); |
| } |
| |
| void WGLContext::makeCurrent(void) |
| { |
| m_context->makeCurrent(); |
| } |
| |
| void WGLContext::postIterate(void) |
| { |
| m_context->swapBuffers(); |
| m_window.processEvents(); |
| } |
| |
| } // namespace |
| |
| ContextFactory::ContextFactory(HINSTANCE instance) |
| : glu::ContextFactory("wgl", "Windows WGL OpenGL context") |
| , m_instance(instance) |
| , m_wglCore(instance) |
| { |
| } |
| |
| glu::RenderContext *ContextFactory::createContext(const glu::RenderConfig &config, const tcu::CommandLine &, |
| const glu::RenderContext *sharedContext) const |
| { |
| const WGLContext *sharedWGLContext = static_cast<const WGLContext *>(sharedContext); |
| return new WGLContext(m_instance, m_wglCore, sharedWGLContext, config); |
| } |
| |
| } // namespace wgl |
| } // namespace tcu |