xref: /aosp_15_r20/external/deqp/framework/platform/win32/tcuWGLContextFactory.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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