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) : m_context(context)
52 {
53 }
54
get(const char * name) const55 glw::GenericFuncType get(const char *name) const
56 {
57 return (glw::GenericFuncType)m_context.getGLFunction(name);
58 }
59
60 private:
61 const wgl::Context &m_context;
62 };
63
64 class WGLContext : public glu::RenderContext
65 {
66 public:
67 WGLContext(HINSTANCE instance, const wgl::Core &wglCore, const WGLContext *sharedContext,
68 const glu::RenderConfig &config);
69 ~WGLContext(void);
70
getType(void) const71 glu::ContextType getType(void) const
72 {
73 return m_contextType;
74 }
getRenderTarget(void) const75 const RenderTarget &getRenderTarget(void) const
76 {
77 return m_renderTarget;
78 }
79 void postIterate(void);
getFunctions(void) const80 const glw::Functions &getFunctions(void) const
81 {
82 return m_functions;
83 }
84
85 glw::GenericFuncType getProcAddress(const char *name) const;
86
87 void makeCurrent(void);
88
89 private:
90 WGLContext(const WGLContext &other);
91 WGLContext &operator=(const WGLContext &other);
92
93 glu::ContextType m_contextType;
94
95 win32::Window m_window;
96 wgl::Context *m_context;
97
98 tcu::RenderTarget m_renderTarget;
99 glw::Functions m_functions;
100 };
101
WGLContext(HINSTANCE instance,const wgl::Core & wglCore,const WGLContext * sharedContext,const glu::RenderConfig & config)102 WGLContext::WGLContext(HINSTANCE instance, const wgl::Core &wglCore, const WGLContext *sharedContext,
103 const glu::RenderConfig &config)
104 : m_contextType(config.type)
105 , m_window(instance, config.width != glu::RenderConfig::DONT_CARE ? config.width : DEFAULT_WINDOW_WIDTH,
106 config.height != glu::RenderConfig::DONT_CARE ? config.height : DEFAULT_WINDOW_HEIGHT)
107 , m_context(DE_NULL)
108 {
109 if (config.surfaceType != glu::RenderConfig::SURFACETYPE_WINDOW &&
110 config.surfaceType != glu::RenderConfig::SURFACETYPE_DONT_CARE)
111 throw NotSupportedError("Unsupported surface type");
112
113 HDC deviceCtx = m_window.getDeviceContext();
114 int pixelFormat = 0;
115
116 if (config.id != glu::RenderConfig::DONT_CARE)
117 pixelFormat = config.id;
118 else
119 pixelFormat = wgl::choosePixelFormat(wglCore, deviceCtx, config);
120
121 if (pixelFormat < 0)
122 throw NotSupportedError("Compatible WGL pixel format not found");
123
124 const wgl::Context *sharedCtx = DE_NULL;
125 if (DE_NULL != sharedContext)
126 sharedCtx = sharedContext->m_context;
127
128 m_context =
129 new wgl::Context(&wglCore, deviceCtx, sharedCtx, config.type, pixelFormat, config.resetNotificationStrategy);
130
131 try
132 {
133 // Describe selected config & get render target props.
134 const wgl::PixelFormatInfo info = wglCore.getPixelFormatInfo(deviceCtx, pixelFormat);
135 const IVec2 size = m_window.getSize();
136
137 m_renderTarget = tcu::RenderTarget(
138 size.x(), size.y(), tcu::PixelFormat(info.redBits, info.greenBits, info.blueBits, info.alphaBits),
139 info.depthBits, info.stencilBits, info.sampleBuffers ? info.samples : 0);
140
141 // Load functions
142 {
143 WGLFunctionLoader funcLoader(*m_context);
144 glu::initFunctions(&m_functions, &funcLoader, config.type.getAPI());
145 }
146
147 if (config.windowVisibility != glu::RenderConfig::VISIBILITY_VISIBLE &&
148 config.windowVisibility != glu::RenderConfig::VISIBILITY_HIDDEN)
149 throw NotSupportedError("Unsupported window visibility mode");
150
151 m_window.setVisible(config.windowVisibility != glu::RenderConfig::VISIBILITY_HIDDEN);
152 }
153 catch (...)
154 {
155 delete m_context;
156 throw;
157 }
158 }
159
~WGLContext(void)160 WGLContext::~WGLContext(void)
161 {
162 delete m_context;
163 }
164
getProcAddress(const char * name) const165 glw::GenericFuncType WGLContext::getProcAddress(const char *name) const
166 {
167 return m_context->getGLFunction(name);
168 }
169
makeCurrent(void)170 void WGLContext::makeCurrent(void)
171 {
172 m_context->makeCurrent();
173 }
174
postIterate(void)175 void WGLContext::postIterate(void)
176 {
177 m_context->swapBuffers();
178 m_window.processEvents();
179 }
180
181 } // namespace
182
ContextFactory(HINSTANCE instance)183 ContextFactory::ContextFactory(HINSTANCE instance)
184 : glu::ContextFactory("wgl", "Windows WGL OpenGL context")
185 , m_instance(instance)
186 , m_wglCore(instance)
187 {
188 }
189
createContext(const glu::RenderConfig & config,const tcu::CommandLine &,const glu::RenderContext * sharedContext) const190 glu::RenderContext *ContextFactory::createContext(const glu::RenderConfig &config, const tcu::CommandLine &,
191 const glu::RenderContext *sharedContext) const
192 {
193 const WGLContext *sharedWGLContext = static_cast<const WGLContext *>(sharedContext);
194 return new WGLContext(m_instance, m_wglCore, sharedWGLContext, config);
195 }
196
197 } // namespace wgl
198 } // namespace tcu
199