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 Win32 GLES3 wrapper platform.
22 *//*--------------------------------------------------------------------*/
23
24 #include "tcuWin32GLES3Platform.hpp"
25 #include "gluRenderConfig.hpp"
26 #include "gluRenderContext.hpp"
27 #include "tcuRenderTarget.hpp"
28 #include "gl3Context.h"
29 #include "glwInitES30Direct.hpp"
30
31 struct gl3PlatformContext_s
32 {
33 tcu::wgl::Context* context;
34
gl3PlatformContext_sgl3PlatformContext_s35 gl3PlatformContext_s (void)
36 : context(DE_NULL)
37 {
38 }
39 };
40
gl3PlatformContext_getProcAddress(gl3PlatformContext * platformCtx,const char * procName)41 gl3FunctionPtr gl3PlatformContext_getProcAddress (gl3PlatformContext* platformCtx, const char* procName)
42 {
43 DE_ASSERT(platformCtx && platformCtx->context);
44 return platformCtx->context->getGLFunction(procName);
45 }
46
47 namespace tcu
48 {
49
50 enum
51 {
52 DEFAULT_WINDOW_WIDTH = 400,
53 DEFAULT_WINDOW_HEIGHT = 300
54 };
55
56 // Win32GLES3Context
57
58 class Win32GLES3Context : public glu::RenderContext
59 {
60 public:
61 Win32GLES3Context (const wgl::Core& wgl, HINSTANCE instance, const glu::RenderConfig& config);
62 ~Win32GLES3Context (void);
63
getType(void) const64 glu::ContextType getType (void) const { return glu::CONTEXTTYPE_ES3; }
getRenderTarget(void) const65 const RenderTarget& getRenderTarget (void) const { return m_renderTarget; }
66 void postIterate (void);
getFunctions(void) const67 const glw::Functions& getFunctions (void) const { return m_functions; }
68
69 private:
70 Win32GLES3Context (const Win32GLES3Context& other);
71 Win32GLES3Context& operator= (const Win32GLES3Context& other);
72
73 RenderTarget m_renderTarget;
74 Win32Window m_window;
75
76 gl3PlatformContext m_platformCtx;
77 gl3Context* m_context;
78
79 glw::Functions m_functions;
80 };
81
82 typedef const char* (GL_APIENTRY* glGetStringHackFunc) (GLenum str);
83
Win32GLES3Context(const wgl::Core & wgl,HINSTANCE instance,const glu::RenderConfig & config)84 Win32GLES3Context::Win32GLES3Context (const wgl::Core& wgl, HINSTANCE instance, const glu::RenderConfig& config)
85 : m_renderTarget(config.width != glu::RenderConfig::DONT_CARE ? config.width : DEFAULT_WINDOW_WIDTH,
86 config.height != glu::RenderConfig::DONT_CARE ? config.height : DEFAULT_WINDOW_HEIGHT,
87 PixelFormat(8, 8, 8, 8), 24, 8, 0)
88 , m_window (instance, m_renderTarget.getWidth(), m_renderTarget.getHeight())
89 , m_context (DE_NULL)
90 {
91 const HDC deviceCtx = m_window.getDeviceContext();
92 const int pixelFormat = wgl::choosePixelFormat(wgl, deviceCtx, config);
93
94 if (pixelFormat < 0)
95 throw NotSupportedError("No compatible WGL pixel format found");
96
97 m_platformCtx.context = new wgl::Context(&wgl, m_window.getDeviceContext(), wgl::PROFILE_COMPATIBILITY, 3, 3, pixelFormat);
98
99 try
100 {
101 m_context = gl3Context_create(&m_platformCtx);
102 if (!m_context)
103 throw ResourceError("Failed to create GLES3 wrapper context");
104
105 gl3Context_setCurrentContext(m_context);
106 glw::initES30Direct(&m_functions);
107
108 m_window.setVisible(config.windowVisibility != glu::RenderConfig::VISIBILITY_HIDDEN);
109
110 {
111 const wgl::PixelFormatInfo info = wgl.getPixelFormatInfo(deviceCtx, pixelFormat);
112 const IVec2 size = m_window.getSize();
113
114 m_renderTarget = tcu::RenderTarget(size.x(), size.y(),
115 tcu::PixelFormat(info.redBits, info.greenBits, info.blueBits, info.alphaBits),
116 info.depthBits, info.stencilBits,
117 info.sampleBuffers ? info.samples : 0);
118 }
119 }
120 catch (...)
121 {
122 if (m_context)
123 gl3Context_destroy(m_context);
124 delete m_platformCtx.context;
125 throw;
126 }
127 }
128
~Win32GLES3Context(void)129 Win32GLES3Context::~Win32GLES3Context (void)
130 {
131 if (m_context)
132 gl3Context_destroy(m_context);
133
134 delete m_platformCtx.context;
135 }
136
postIterate(void)137 void Win32GLES3Context::postIterate (void)
138 {
139 m_platformCtx.context->swapBuffers();
140 }
141
142 // Win32GLES3ContextFactory
143
144 class Win32GLES3ContextFactory : public glu::ContextFactory
145 {
146 public:
147 Win32GLES3ContextFactory (HINSTANCE instance);
148 ~Win32GLES3ContextFactory (void);
149
150 virtual glu::RenderContext* createContext (const glu::RenderConfig& config, const tcu::CommandLine& cmdLine) const;
151
152 private:
153 const HINSTANCE m_instance;
154 wgl::Core m_wglCore;
155 };
156
Win32GLES3ContextFactory(HINSTANCE instance)157 Win32GLES3ContextFactory::Win32GLES3ContextFactory (HINSTANCE instance)
158 : glu::ContextFactory ("gles3_wrapper", "GLES3 Wrapper Context")
159 , m_instance (instance)
160 , m_wglCore (instance)
161 {
162 }
163
~Win32GLES3ContextFactory(void)164 Win32GLES3ContextFactory::~Win32GLES3ContextFactory (void)
165 {
166 }
167
createContext(const glu::RenderConfig & config,const tcu::CommandLine &) const168 glu::RenderContext* Win32GLES3ContextFactory::createContext (const glu::RenderConfig& config, const tcu::CommandLine&) const
169 {
170 if (config.type == glu::CONTEXTTYPE_ES3)
171 return new Win32GLES3Context(m_wglCore, m_instance, config);
172 else
173 throw NotSupportedError("Unsupported rendering context type");
174 }
175
176 // Win32GLES3Platform
177
Win32GLES3Platform(void)178 Win32GLES3Platform::Win32GLES3Platform (void)
179 {
180 const HINSTANCE instance = GetModuleHandle(NULL);
181
182 // Set priority to lower.
183 SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);
184
185 m_glContextFactoryRegistry.registerFactory(new Win32GLES3ContextFactory(instance));
186 }
187
~Win32GLES3Platform(void)188 Win32GLES3Platform::~Win32GLES3Platform (void)
189 {
190 }
191
processEvents(void)192 bool Win32GLES3Platform::processEvents (void)
193 {
194 MSG msg;
195 while (PeekMessage(&msg, NULL, 0, 0, TRUE))
196 {
197 DispatchMessage(&msg);
198 if (msg.message == WM_QUIT)
199 return false;
200 }
201 return true;
202 }
203
204 } // tcu
205
206 // Platform factory
createPlatform(void)207 tcu::Platform* createPlatform (void)
208 {
209 return new tcu::Win32GLES3Platform();
210 }
211