1/*------------------------------------------------------------------------- 2 * drawElements Quality Program Tester Core 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 WGL GL context factory. 22 *//*--------------------------------------------------------------------*/ 23 24#include "tcuWGLContextFactory.hpp" 25 26#include "gluRenderConfig.hpp" 27#include "tcuRenderTarget.hpp" 28#include "tcuWin32Window.hpp" 29#include "glwFunctions.hpp" 30#include "glwInitFunctions.hpp" 31#include "deString.h" 32 33using std::vector; 34 35namespace tcu 36{ 37namespace wgl 38{ 39namespace 40{ 41 42enum 43{ 44 DEFAULT_WINDOW_WIDTH = 400, 45 DEFAULT_WINDOW_HEIGHT = 300 46}; 47 48class WGLFunctionLoader : public glw::FunctionLoader 49{ 50public: 51 WGLFunctionLoader (const wgl::Context& context) 52 : m_context(context) 53 { 54 } 55 56 glw::GenericFuncType get (const char* name) const 57 { 58 return (glw::GenericFuncType)m_context.getGLFunction(name); 59 } 60 61private: 62 const wgl::Context& m_context; 63}; 64 65class WGLContext : public glu::RenderContext 66{ 67public: 68 WGLContext (HINSTANCE instance, const wgl::Core& wglCore, const WGLContext* sharedContext, const glu::RenderConfig& config); 69 ~WGLContext (void); 70 71 glu::ContextType getType (void) const { return m_contextType; } 72 const RenderTarget& getRenderTarget (void) const { return m_renderTarget; } 73 void postIterate (void); 74 const glw::Functions& getFunctions (void) const { return m_functions; } 75 76 glw::GenericFuncType getProcAddress (const char* name) const; 77 78 void makeCurrent (void); 79 80private: 81 WGLContext (const WGLContext& other); 82 WGLContext& operator= (const WGLContext& other); 83 84 glu::ContextType m_contextType; 85 86 win32::Window m_window; 87 wgl::Context* m_context; 88 89 tcu::RenderTarget m_renderTarget; 90 glw::Functions m_functions; 91}; 92 93WGLContext::WGLContext (HINSTANCE instance, const wgl::Core& wglCore, const WGLContext* sharedContext, const glu::RenderConfig& config) 94 : m_contextType (config.type) 95 , m_window (instance, 96 config.width != glu::RenderConfig::DONT_CARE ? config.width : DEFAULT_WINDOW_WIDTH, 97 config.height != glu::RenderConfig::DONT_CARE ? config.height : DEFAULT_WINDOW_HEIGHT) 98 , m_context (DE_NULL) 99{ 100 if (config.surfaceType != glu::RenderConfig::SURFACETYPE_WINDOW && 101 config.surfaceType != glu::RenderConfig::SURFACETYPE_DONT_CARE) 102 throw NotSupportedError("Unsupported surface type"); 103 104 HDC deviceCtx = m_window.getDeviceContext(); 105 int pixelFormat = 0; 106 107 if (config.id != glu::RenderConfig::DONT_CARE) 108 pixelFormat = config.id; 109 else 110 pixelFormat = wgl::choosePixelFormat(wglCore, deviceCtx, config); 111 112 if (pixelFormat < 0) 113 throw NotSupportedError("Compatible WGL pixel format not found"); 114 115 const wgl::Context* sharedCtx = DE_NULL; 116 if (DE_NULL != sharedContext) 117 sharedCtx = sharedContext->m_context; 118 119 m_context = new wgl::Context(&wglCore, deviceCtx, sharedCtx, config.type, pixelFormat, config.resetNotificationStrategy); 120 121 try 122 { 123 // Describe selected config & get render target props. 124 const wgl::PixelFormatInfo info = wglCore.getPixelFormatInfo(deviceCtx, pixelFormat); 125 const IVec2 size = m_window.getSize(); 126 127 m_renderTarget = tcu::RenderTarget(size.x(), size.y(), 128 tcu::PixelFormat(info.redBits, info.greenBits, info.blueBits, info.alphaBits), 129 info.depthBits, info.stencilBits, 130 info.sampleBuffers ? info.samples : 0); 131 132 // Load functions 133 { 134 WGLFunctionLoader funcLoader(*m_context); 135 glu::initFunctions(&m_functions, &funcLoader, config.type.getAPI()); 136 } 137 138 if (config.windowVisibility != glu::RenderConfig::VISIBILITY_VISIBLE && 139 config.windowVisibility != glu::RenderConfig::VISIBILITY_HIDDEN) 140 throw NotSupportedError("Unsupported window visibility mode"); 141 142 m_window.setVisible(config.windowVisibility != glu::RenderConfig::VISIBILITY_HIDDEN); 143 } 144 catch (...) 145 { 146 delete m_context; 147 throw; 148 } 149} 150 151WGLContext::~WGLContext (void) 152{ 153 delete m_context; 154} 155 156glw::GenericFuncType WGLContext::getProcAddress (const char* name) const 157{ 158 return m_context->getGLFunction(name); 159} 160 161void WGLContext::makeCurrent (void) 162{ 163 m_context->makeCurrent(); 164} 165 166void WGLContext::postIterate (void) 167{ 168 m_context->swapBuffers(); 169 m_window.processEvents(); 170} 171 172} // anonymous 173 174ContextFactory::ContextFactory (HINSTANCE instance) 175 : glu::ContextFactory ("wgl", "Windows WGL OpenGL context") 176 , m_instance (instance) 177 , m_wglCore (instance) 178{ 179} 180 181glu::RenderContext* ContextFactory::createContext (const glu::RenderConfig& config, const tcu::CommandLine&, 182 const glu::RenderContext* sharedContext) const 183{ 184 const WGLContext* sharedWGLContext = static_cast<const WGLContext*>(sharedContext); 185 return new WGLContext(m_instance, m_wglCore, sharedWGLContext, config); 186} 187 188} // wgl 189} // tcu 190