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
33 using std::vector;
34
35 namespace tcu
36 {
37 namespace wgl
38 {
39 namespace
40 {
41
42 enum
43 {
44 DEFAULT_WINDOW_WIDTH = 400,
45 DEFAULT_WINDOW_HEIGHT = 300
46 };
47
48 class WGLFunctionLoader : public glw::FunctionLoader
49 {
50 public:
WGLFunctionLoader(const wgl::Context & context)51 WGLFunctionLoader (const wgl::Context& context)
52 : m_context(context)
53 {
54 }
55
get(const char * name) const56 glw::GenericFuncType get (const char* name) const
57 {
58 return (glw::GenericFuncType)m_context.getGLFunction(name);
59 }
60
61 private:
62 const wgl::Context& m_context;
63 };
64
65 class WGLContext : public glu::RenderContext
66 {
67 public:
68 WGLContext (HINSTANCE instance, const wgl::Core& wglCore, const WGLContext* sharedContext, const glu::RenderConfig& config);
69 ~WGLContext (void);
70
getType(void) const71 glu::ContextType getType (void) const { return m_contextType; }
getRenderTarget(void) const72 const RenderTarget& getRenderTarget (void) const { return m_renderTarget; }
73 void postIterate (void);
getFunctions(void) const74 const glw::Functions& getFunctions (void) const { return m_functions; }
75
76 glw::GenericFuncType getProcAddress (const char* name) const;
77
78 void makeCurrent (void);
79
80 private:
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
WGLContext(HINSTANCE instance,const wgl::Core & wglCore,const WGLContext * sharedContext,const glu::RenderConfig & config)93 WGLContext::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
~WGLContext(void)151 WGLContext::~WGLContext (void)
152 {
153 delete m_context;
154 }
155
getProcAddress(const char * name) const156 glw::GenericFuncType WGLContext::getProcAddress (const char* name) const
157 {
158 return m_context->getGLFunction(name);
159 }
160
makeCurrent(void)161 void WGLContext::makeCurrent (void)
162 {
163 m_context->makeCurrent();
164 }
165
postIterate(void)166 void WGLContext::postIterate (void)
167 {
168 m_context->swapBuffers();
169 m_window.processEvents();
170 }
171
172 } // anonymous
173
ContextFactory(HINSTANCE instance)174 ContextFactory::ContextFactory (HINSTANCE instance)
175 : glu::ContextFactory ("wgl", "Windows WGL OpenGL context")
176 , m_instance (instance)
177 , m_wglCore (instance)
178 {
179 }
180
createContext(const glu::RenderConfig & config,const tcu::CommandLine &,const glu::RenderContext * sharedContext) const181 glu::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