Add multiple contexts tests
[platform/upstream/VK-GL-CTS.git] / framework / platform / win32 / tcuWGLContextFactory.cpp
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:
51         WGLFunctionLoader (const wgl::Context& context)
52                 : m_context(context)
53         {
54         }
55
56         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
71         glu::ContextType                                getType                         (void) const    { return m_contextType;                 }
72         const RenderTarget&                             getRenderTarget         (void) const    { return m_renderTarget;                }
73         void                                                    postIterate                     (void);
74         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
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
151 WGLContext::~WGLContext (void)
152 {
153         delete m_context;
154 }
155
156 glw::GenericFuncType WGLContext::getProcAddress (const char* name) const
157 {
158         return m_context->getGLFunction(name);
159 }
160
161 void WGLContext::makeCurrent (void)
162 {
163         m_context->makeCurrent();
164 }
165
166 void WGLContext::postIterate (void)
167 {
168         m_context->swapBuffers();
169         m_window.processEvents();
170 }
171
172 } // anonymous
173
174 ContextFactory::ContextFactory (HINSTANCE instance)
175         : glu::ContextFactory   ("wgl", "Windows WGL OpenGL context")
176         , m_instance                    (instance)
177         , m_wglCore                             (instance)
178 {
179 }
180
181 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