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
38 {
39
40 enum
41 {
42 DEFAULT_WINDOW_WIDTH = 400,
43 DEFAULT_WINDOW_HEIGHT = 300
44 };
45
46 class WGLFunctionLoader : public glw::FunctionLoader
47 {
48 public:
WGLFunctionLoader(const wgl::Context & context)49 WGLFunctionLoader (const wgl::Context& context)
50 : m_context(context)
51 {
52 }
53
get(const char * name) const54 glw::GenericFuncType get (const char* name) const
55 {
56 return (glw::GenericFuncType)m_context.getGLFunction(name);
57 }
58
59 private:
60 const wgl::Context& m_context;
61 };
62
63 class WGLContext : public glu::RenderContext
64 {
65 public:
66 WGLContext (HINSTANCE instance, const wgl::Core& wglCore, const glu::RenderConfig& config);
67 ~WGLContext (void);
68
getType(void) const69 glu::ContextType getType (void) const { return m_contextType; }
getRenderTarget(void) const70 const RenderTarget& getRenderTarget (void) const { return m_renderTarget; }
71 void postIterate (void);
getFunctions(void) const72 const glw::Functions& getFunctions (void) const { return m_functions; }
73
74 private:
75 WGLContext (const WGLContext& other);
76 WGLContext& operator= (const WGLContext& other);
77
78 glu::ContextType m_contextType;
79
80 Win32Window m_window;
81 wgl::Context* m_context;
82
83 tcu::RenderTarget m_renderTarget;
84 glw::Functions m_functions;
85 };
86
WGLContext(HINSTANCE instance,const wgl::Core & wglCore,const glu::RenderConfig & config)87 WGLContext::WGLContext (HINSTANCE instance, const wgl::Core& wglCore, const glu::RenderConfig& config)
88 : m_contextType (config.type)
89 , m_window (instance,
90 config.width != glu::RenderConfig::DONT_CARE ? config.width : DEFAULT_WINDOW_WIDTH,
91 config.height != glu::RenderConfig::DONT_CARE ? config.height : DEFAULT_WINDOW_HEIGHT)
92 , m_context (DE_NULL)
93 {
94 if (config.surfaceType != glu::RenderConfig::SURFACETYPE_WINDOW &&
95 config.surfaceType != glu::RenderConfig::SURFACETYPE_DONT_CARE)
96 throw NotSupportedError("Unsupported surface type");
97
98 HDC deviceCtx = m_window.getDeviceContext();
99 int pixelFormat = 0;
100
101 if (config.id != glu::RenderConfig::DONT_CARE)
102 pixelFormat = config.id;
103 else
104 pixelFormat = wgl::choosePixelFormat(wglCore, deviceCtx, config);
105
106 if (pixelFormat < 0)
107 throw NotSupportedError("Compatible WGL pixel format not found");
108
109 m_context = new wgl::Context(&wglCore, deviceCtx, config.type, pixelFormat);
110
111 try
112 {
113 // Describe selected config & get render target props.
114 const wgl::PixelFormatInfo info = wglCore.getPixelFormatInfo(deviceCtx, pixelFormat);
115 const IVec2 size = m_window.getSize();
116
117 m_renderTarget = tcu::RenderTarget(size.x(), size.y(),
118 tcu::PixelFormat(info.redBits, info.greenBits, info.blueBits, info.alphaBits),
119 info.depthBits, info.stencilBits,
120 info.sampleBuffers ? info.samples : 0);
121
122 // Load functions
123 {
124 WGLFunctionLoader funcLoader(*m_context);
125 glu::initFunctions(&m_functions, &funcLoader, config.type.getAPI());
126 }
127
128 if (config.windowVisibility != glu::RenderConfig::VISIBILITY_VISIBLE &&
129 config.windowVisibility != glu::RenderConfig::VISIBILITY_HIDDEN)
130 throw NotSupportedError("Unsupported window visibility mode");
131
132 m_window.setVisible(config.windowVisibility != glu::RenderConfig::VISIBILITY_HIDDEN);
133 }
134 catch (...)
135 {
136 delete m_context;
137 throw;
138 }
139 }
140
~WGLContext(void)141 WGLContext::~WGLContext (void)
142 {
143 delete m_context;
144 }
145
postIterate(void)146 void WGLContext::postIterate (void)
147 {
148 m_context->swapBuffers();
149 m_window.processEvents();
150 }
151
152 } // anonymous
153
WGLContextFactory(HINSTANCE instance)154 WGLContextFactory::WGLContextFactory (HINSTANCE instance)
155 : glu::ContextFactory ("wgl", "Windows WGL OpenGL context")
156 , m_instance (instance)
157 , m_wglCore (instance)
158 {
159 }
160
createContext(const glu::RenderConfig & config,const tcu::CommandLine &) const161 glu::RenderContext* WGLContextFactory::createContext (const glu::RenderConfig& config, const tcu::CommandLine&) const
162 {
163 return new WGLContext(m_instance, m_wglCore, config);
164 }
165
166 } // tcu
167