xref: /aosp_15_r20/external/angle/util/windows/WGLWindow.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2018 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // WGLWindow:
7*8975f5c5SAndroid Build Coastguard Worker //   Implements initializing a WGL rendering context.
8*8975f5c5SAndroid Build Coastguard Worker //
9*8975f5c5SAndroid Build Coastguard Worker 
10*8975f5c5SAndroid Build Coastguard Worker #include "util/windows/WGLWindow.h"
11*8975f5c5SAndroid Build Coastguard Worker 
12*8975f5c5SAndroid Build Coastguard Worker #include "common/string_utils.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "common/system_utils.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "util/OSWindow.h"
15*8975f5c5SAndroid Build Coastguard Worker 
16*8975f5c5SAndroid Build Coastguard Worker #include <iostream>
17*8975f5c5SAndroid Build Coastguard Worker 
18*8975f5c5SAndroid Build Coastguard Worker namespace
19*8975f5c5SAndroid Build Coastguard Worker {
20*8975f5c5SAndroid Build Coastguard Worker constexpr int kColorBits   = 24;
21*8975f5c5SAndroid Build Coastguard Worker constexpr int kAlphaBits   = 8;
22*8975f5c5SAndroid Build Coastguard Worker constexpr int kDepthBits   = 24;
23*8975f5c5SAndroid Build Coastguard Worker constexpr int kStencilBits = 8;
24*8975f5c5SAndroid Build Coastguard Worker 
GetDefaultPixelFormatDescriptor()25*8975f5c5SAndroid Build Coastguard Worker PIXELFORMATDESCRIPTOR GetDefaultPixelFormatDescriptor()
26*8975f5c5SAndroid Build Coastguard Worker {
27*8975f5c5SAndroid Build Coastguard Worker     PIXELFORMATDESCRIPTOR pixelFormatDescriptor = {};
28*8975f5c5SAndroid Build Coastguard Worker     pixelFormatDescriptor.nSize                 = sizeof(pixelFormatDescriptor);
29*8975f5c5SAndroid Build Coastguard Worker     pixelFormatDescriptor.nVersion              = 1;
30*8975f5c5SAndroid Build Coastguard Worker     pixelFormatDescriptor.dwFlags =
31*8975f5c5SAndroid Build Coastguard Worker         PFD_DRAW_TO_WINDOW | PFD_GENERIC_ACCELERATED | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
32*8975f5c5SAndroid Build Coastguard Worker     pixelFormatDescriptor.iPixelType   = PFD_TYPE_RGBA;
33*8975f5c5SAndroid Build Coastguard Worker     pixelFormatDescriptor.cColorBits   = kColorBits;
34*8975f5c5SAndroid Build Coastguard Worker     pixelFormatDescriptor.cAlphaBits   = kAlphaBits;
35*8975f5c5SAndroid Build Coastguard Worker     pixelFormatDescriptor.cDepthBits   = kDepthBits;
36*8975f5c5SAndroid Build Coastguard Worker     pixelFormatDescriptor.cStencilBits = kStencilBits;
37*8975f5c5SAndroid Build Coastguard Worker     pixelFormatDescriptor.iLayerType   = PFD_MAIN_PLANE;
38*8975f5c5SAndroid Build Coastguard Worker 
39*8975f5c5SAndroid Build Coastguard Worker     return pixelFormatDescriptor;
40*8975f5c5SAndroid Build Coastguard Worker }
41*8975f5c5SAndroid Build Coastguard Worker 
42*8975f5c5SAndroid Build Coastguard Worker PFNWGLGETPROCADDRESSPROC gCurrentWGLGetProcAddress = nullptr;
43*8975f5c5SAndroid Build Coastguard Worker HMODULE gCurrentModule                             = nullptr;
44*8975f5c5SAndroid Build Coastguard Worker 
GetProcAddressWithFallback(const char * name)45*8975f5c5SAndroid Build Coastguard Worker GenericProc WINAPI GetProcAddressWithFallback(const char *name)
46*8975f5c5SAndroid Build Coastguard Worker {
47*8975f5c5SAndroid Build Coastguard Worker     GenericProc proc = reinterpret_cast<GenericProc>(gCurrentWGLGetProcAddress(name));
48*8975f5c5SAndroid Build Coastguard Worker     if (proc)
49*8975f5c5SAndroid Build Coastguard Worker     {
50*8975f5c5SAndroid Build Coastguard Worker         return proc;
51*8975f5c5SAndroid Build Coastguard Worker     }
52*8975f5c5SAndroid Build Coastguard Worker 
53*8975f5c5SAndroid Build Coastguard Worker     return reinterpret_cast<GenericProc>(GetProcAddress(gCurrentModule, name));
54*8975f5c5SAndroid Build Coastguard Worker }
55*8975f5c5SAndroid Build Coastguard Worker 
HasExtension(const std::vector<std::string> & extensions,const char * ext)56*8975f5c5SAndroid Build Coastguard Worker bool HasExtension(const std::vector<std::string> &extensions, const char *ext)
57*8975f5c5SAndroid Build Coastguard Worker {
58*8975f5c5SAndroid Build Coastguard Worker     return std::find(extensions.begin(), extensions.end(), ext) != extensions.end();
59*8975f5c5SAndroid Build Coastguard Worker }
60*8975f5c5SAndroid Build Coastguard Worker 
DumpLastWindowsError()61*8975f5c5SAndroid Build Coastguard Worker void DumpLastWindowsError()
62*8975f5c5SAndroid Build Coastguard Worker {
63*8975f5c5SAndroid Build Coastguard Worker     std::cerr << "Last Windows error code: 0x" << std::hex << GetLastError() << std::endl;
64*8975f5c5SAndroid Build Coastguard Worker }
65*8975f5c5SAndroid Build Coastguard Worker 
66*8975f5c5SAndroid Build Coastguard Worker // Based on GetDefaultPixelFormatAttributes from wgl_utils.cpp
GetPixelFormatAttributes(const ConfigParameters & configParams)67*8975f5c5SAndroid Build Coastguard Worker std::vector<int> GetPixelFormatAttributes(const ConfigParameters &configParams)
68*8975f5c5SAndroid Build Coastguard Worker {
69*8975f5c5SAndroid Build Coastguard Worker     std::vector<int> attribs;
70*8975f5c5SAndroid Build Coastguard Worker     attribs.push_back(WGL_DRAW_TO_WINDOW_ARB);
71*8975f5c5SAndroid Build Coastguard Worker     attribs.push_back(TRUE);
72*8975f5c5SAndroid Build Coastguard Worker 
73*8975f5c5SAndroid Build Coastguard Worker     attribs.push_back(WGL_ACCELERATION_ARB);
74*8975f5c5SAndroid Build Coastguard Worker     attribs.push_back(WGL_FULL_ACCELERATION_ARB);
75*8975f5c5SAndroid Build Coastguard Worker 
76*8975f5c5SAndroid Build Coastguard Worker     attribs.push_back(WGL_SUPPORT_OPENGL_ARB);
77*8975f5c5SAndroid Build Coastguard Worker     attribs.push_back(TRUE);
78*8975f5c5SAndroid Build Coastguard Worker 
79*8975f5c5SAndroid Build Coastguard Worker     attribs.push_back(WGL_DOUBLE_BUFFER_ARB);
80*8975f5c5SAndroid Build Coastguard Worker     attribs.push_back(TRUE);
81*8975f5c5SAndroid Build Coastguard Worker 
82*8975f5c5SAndroid Build Coastguard Worker     attribs.push_back(WGL_PIXEL_TYPE_ARB);
83*8975f5c5SAndroid Build Coastguard Worker     attribs.push_back(WGL_TYPE_RGBA_ARB);
84*8975f5c5SAndroid Build Coastguard Worker 
85*8975f5c5SAndroid Build Coastguard Worker     attribs.push_back(WGL_COLOR_BITS_ARB);
86*8975f5c5SAndroid Build Coastguard Worker     attribs.push_back(kColorBits);
87*8975f5c5SAndroid Build Coastguard Worker 
88*8975f5c5SAndroid Build Coastguard Worker     attribs.push_back(WGL_ALPHA_BITS_ARB);
89*8975f5c5SAndroid Build Coastguard Worker     attribs.push_back(kAlphaBits);
90*8975f5c5SAndroid Build Coastguard Worker 
91*8975f5c5SAndroid Build Coastguard Worker     attribs.push_back(WGL_DEPTH_BITS_ARB);
92*8975f5c5SAndroid Build Coastguard Worker     attribs.push_back(kDepthBits);
93*8975f5c5SAndroid Build Coastguard Worker 
94*8975f5c5SAndroid Build Coastguard Worker     attribs.push_back(WGL_STENCIL_BITS_ARB);
95*8975f5c5SAndroid Build Coastguard Worker     attribs.push_back(kStencilBits);
96*8975f5c5SAndroid Build Coastguard Worker 
97*8975f5c5SAndroid Build Coastguard Worker     attribs.push_back(WGL_SWAP_METHOD_ARB);
98*8975f5c5SAndroid Build Coastguard Worker     attribs.push_back(WGL_SWAP_UNDEFINED_ARB);
99*8975f5c5SAndroid Build Coastguard Worker 
100*8975f5c5SAndroid Build Coastguard Worker     attribs.push_back(WGL_COLORSPACE_EXT);
101*8975f5c5SAndroid Build Coastguard Worker     if (configParams.colorSpace == EGL_COLORSPACE_sRGB)
102*8975f5c5SAndroid Build Coastguard Worker     {
103*8975f5c5SAndroid Build Coastguard Worker         attribs.push_back(WGL_COLORSPACE_SRGB_EXT);
104*8975f5c5SAndroid Build Coastguard Worker     }
105*8975f5c5SAndroid Build Coastguard Worker     else
106*8975f5c5SAndroid Build Coastguard Worker     {
107*8975f5c5SAndroid Build Coastguard Worker         attribs.push_back(WGL_COLORSPACE_LINEAR_EXT);
108*8975f5c5SAndroid Build Coastguard Worker     }
109*8975f5c5SAndroid Build Coastguard Worker 
110*8975f5c5SAndroid Build Coastguard Worker     attribs.push_back(0);
111*8975f5c5SAndroid Build Coastguard Worker 
112*8975f5c5SAndroid Build Coastguard Worker     return attribs;
113*8975f5c5SAndroid Build Coastguard Worker }
114*8975f5c5SAndroid Build Coastguard Worker 
115*8975f5c5SAndroid Build Coastguard Worker }  // namespace
116*8975f5c5SAndroid Build Coastguard Worker 
WGLWindow(int majorVersion,int minorVersion)117*8975f5c5SAndroid Build Coastguard Worker WGLWindow::WGLWindow(int majorVersion, int minorVersion)
118*8975f5c5SAndroid Build Coastguard Worker     : GLWindowBase(majorVersion, minorVersion),
119*8975f5c5SAndroid Build Coastguard Worker       mDeviceContext(nullptr),
120*8975f5c5SAndroid Build Coastguard Worker       mWGLContext(nullptr),
121*8975f5c5SAndroid Build Coastguard Worker       mWindow(nullptr)
122*8975f5c5SAndroid Build Coastguard Worker {}
123*8975f5c5SAndroid Build Coastguard Worker 
~WGLWindow()124*8975f5c5SAndroid Build Coastguard Worker WGLWindow::~WGLWindow() {}
125*8975f5c5SAndroid Build Coastguard Worker 
126*8975f5c5SAndroid Build Coastguard Worker // Internally initializes GL resources.
initializeGLWithResult(OSWindow * osWindow,angle::Library * glWindowingLibrary,angle::GLESDriverType driverType,const EGLPlatformParameters & platformParams,const ConfigParameters & configParams)127*8975f5c5SAndroid Build Coastguard Worker GLWindowResult WGLWindow::initializeGLWithResult(OSWindow *osWindow,
128*8975f5c5SAndroid Build Coastguard Worker                                                  angle::Library *glWindowingLibrary,
129*8975f5c5SAndroid Build Coastguard Worker                                                  angle::GLESDriverType driverType,
130*8975f5c5SAndroid Build Coastguard Worker                                                  const EGLPlatformParameters &platformParams,
131*8975f5c5SAndroid Build Coastguard Worker                                                  const ConfigParameters &configParams)
132*8975f5c5SAndroid Build Coastguard Worker {
133*8975f5c5SAndroid Build Coastguard Worker     if (driverType != angle::GLESDriverType::SystemWGL)
134*8975f5c5SAndroid Build Coastguard Worker     {
135*8975f5c5SAndroid Build Coastguard Worker         std::cerr << "WGLWindow requires angle::GLESDriverType::SystemWGL.\n";
136*8975f5c5SAndroid Build Coastguard Worker         return GLWindowResult::Error;
137*8975f5c5SAndroid Build Coastguard Worker     }
138*8975f5c5SAndroid Build Coastguard Worker 
139*8975f5c5SAndroid Build Coastguard Worker     glWindowingLibrary->getAs("wglGetProcAddress", &gCurrentWGLGetProcAddress);
140*8975f5c5SAndroid Build Coastguard Worker 
141*8975f5c5SAndroid Build Coastguard Worker     if (!gCurrentWGLGetProcAddress)
142*8975f5c5SAndroid Build Coastguard Worker     {
143*8975f5c5SAndroid Build Coastguard Worker         std::cerr << "Error loading wglGetProcAddress." << std::endl;
144*8975f5c5SAndroid Build Coastguard Worker         return GLWindowResult::Error;
145*8975f5c5SAndroid Build Coastguard Worker     }
146*8975f5c5SAndroid Build Coastguard Worker 
147*8975f5c5SAndroid Build Coastguard Worker     gCurrentModule = reinterpret_cast<HMODULE>(glWindowingLibrary->getNative());
148*8975f5c5SAndroid Build Coastguard Worker     LoadWGL(GetProcAddressWithFallback);
149*8975f5c5SAndroid Build Coastguard Worker 
150*8975f5c5SAndroid Build Coastguard Worker     mWindow                                           = osWindow->getNativeWindow();
151*8975f5c5SAndroid Build Coastguard Worker     mDeviceContext                                    = GetDC(mWindow);
152*8975f5c5SAndroid Build Coastguard Worker     const PIXELFORMATDESCRIPTOR pixelFormatDescriptor = GetDefaultPixelFormatDescriptor();
153*8975f5c5SAndroid Build Coastguard Worker 
154*8975f5c5SAndroid Build Coastguard Worker     int pixelFormat = 0;
155*8975f5c5SAndroid Build Coastguard Worker 
156*8975f5c5SAndroid Build Coastguard Worker     if (!_wglChoosePixelFormatARB)
157*8975f5c5SAndroid Build Coastguard Worker     {
158*8975f5c5SAndroid Build Coastguard Worker         std::cout << "Driver does not expose wglChoosePixelFormatARB." << std::endl;
159*8975f5c5SAndroid Build Coastguard Worker     }
160*8975f5c5SAndroid Build Coastguard Worker     else
161*8975f5c5SAndroid Build Coastguard Worker     {
162*8975f5c5SAndroid Build Coastguard Worker         std::vector<int> pixelFormatAttribs = GetPixelFormatAttributes(configParams);
163*8975f5c5SAndroid Build Coastguard Worker 
164*8975f5c5SAndroid Build Coastguard Worker         UINT matchingFormats = 0;
165*8975f5c5SAndroid Build Coastguard Worker         _wglChoosePixelFormatARB(mDeviceContext, &pixelFormatAttribs[0], nullptr, 1u, &pixelFormat,
166*8975f5c5SAndroid Build Coastguard Worker                                  &matchingFormats);
167*8975f5c5SAndroid Build Coastguard Worker     }
168*8975f5c5SAndroid Build Coastguard Worker 
169*8975f5c5SAndroid Build Coastguard Worker     if (pixelFormat == 0 && configParams.colorSpace != EGL_COLORSPACE_LINEAR)
170*8975f5c5SAndroid Build Coastguard Worker     {
171*8975f5c5SAndroid Build Coastguard Worker         std::cerr << "Could not find a compatible pixel format for a non-linear color space."
172*8975f5c5SAndroid Build Coastguard Worker                   << std::endl;
173*8975f5c5SAndroid Build Coastguard Worker         return GLWindowResult::NoColorspaceSupport;
174*8975f5c5SAndroid Build Coastguard Worker     }
175*8975f5c5SAndroid Build Coastguard Worker 
176*8975f5c5SAndroid Build Coastguard Worker     if (pixelFormat == 0)
177*8975f5c5SAndroid Build Coastguard Worker     {
178*8975f5c5SAndroid Build Coastguard Worker         pixelFormat = ChoosePixelFormat(mDeviceContext, &pixelFormatDescriptor);
179*8975f5c5SAndroid Build Coastguard Worker     }
180*8975f5c5SAndroid Build Coastguard Worker 
181*8975f5c5SAndroid Build Coastguard Worker     if (pixelFormat == 0)
182*8975f5c5SAndroid Build Coastguard Worker     {
183*8975f5c5SAndroid Build Coastguard Worker         std::cerr << "Could not find a compatible pixel format." << std::endl;
184*8975f5c5SAndroid Build Coastguard Worker         DumpLastWindowsError();
185*8975f5c5SAndroid Build Coastguard Worker         return GLWindowResult::Error;
186*8975f5c5SAndroid Build Coastguard Worker     }
187*8975f5c5SAndroid Build Coastguard Worker 
188*8975f5c5SAndroid Build Coastguard Worker     // According to the Windows docs, it is an error to set a pixel format twice.
189*8975f5c5SAndroid Build Coastguard Worker     int currentPixelFormat = GetPixelFormat(mDeviceContext);
190*8975f5c5SAndroid Build Coastguard Worker     if (currentPixelFormat != pixelFormat)
191*8975f5c5SAndroid Build Coastguard Worker     {
192*8975f5c5SAndroid Build Coastguard Worker         if (SetPixelFormat(mDeviceContext, pixelFormat, &pixelFormatDescriptor) != TRUE)
193*8975f5c5SAndroid Build Coastguard Worker         {
194*8975f5c5SAndroid Build Coastguard Worker             std::cerr << "Failed to set the pixel format." << std::endl;
195*8975f5c5SAndroid Build Coastguard Worker             DumpLastWindowsError();
196*8975f5c5SAndroid Build Coastguard Worker             return GLWindowResult::Error;
197*8975f5c5SAndroid Build Coastguard Worker         }
198*8975f5c5SAndroid Build Coastguard Worker     }
199*8975f5c5SAndroid Build Coastguard Worker 
200*8975f5c5SAndroid Build Coastguard Worker     mWGLContext = createContext(configParams, nullptr);
201*8975f5c5SAndroid Build Coastguard Worker     if (mWGLContext == nullptr)
202*8975f5c5SAndroid Build Coastguard Worker     {
203*8975f5c5SAndroid Build Coastguard Worker         return GLWindowResult::Error;
204*8975f5c5SAndroid Build Coastguard Worker     }
205*8975f5c5SAndroid Build Coastguard Worker 
206*8975f5c5SAndroid Build Coastguard Worker     if (!makeCurrent())
207*8975f5c5SAndroid Build Coastguard Worker     {
208*8975f5c5SAndroid Build Coastguard Worker         return GLWindowResult::Error;
209*8975f5c5SAndroid Build Coastguard Worker     }
210*8975f5c5SAndroid Build Coastguard Worker 
211*8975f5c5SAndroid Build Coastguard Worker     mPlatform     = platformParams;
212*8975f5c5SAndroid Build Coastguard Worker     mConfigParams = configParams;
213*8975f5c5SAndroid Build Coastguard Worker 
214*8975f5c5SAndroid Build Coastguard Worker     LoadUtilGLES(GetProcAddressWithFallback);
215*8975f5c5SAndroid Build Coastguard Worker     return GLWindowResult::NoError;
216*8975f5c5SAndroid Build Coastguard Worker }
217*8975f5c5SAndroid Build Coastguard Worker 
initializeGL(OSWindow * osWindow,angle::Library * glWindowingLibrary,angle::GLESDriverType driverType,const EGLPlatformParameters & platformParams,const ConfigParameters & configParams)218*8975f5c5SAndroid Build Coastguard Worker bool WGLWindow::initializeGL(OSWindow *osWindow,
219*8975f5c5SAndroid Build Coastguard Worker                              angle::Library *glWindowingLibrary,
220*8975f5c5SAndroid Build Coastguard Worker                              angle::GLESDriverType driverType,
221*8975f5c5SAndroid Build Coastguard Worker                              const EGLPlatformParameters &platformParams,
222*8975f5c5SAndroid Build Coastguard Worker                              const ConfigParameters &configParams)
223*8975f5c5SAndroid Build Coastguard Worker {
224*8975f5c5SAndroid Build Coastguard Worker     return initializeGLWithResult(osWindow, glWindowingLibrary, driverType, platformParams,
225*8975f5c5SAndroid Build Coastguard Worker                                   configParams) == GLWindowResult::NoError;
226*8975f5c5SAndroid Build Coastguard Worker }
227*8975f5c5SAndroid Build Coastguard Worker 
createContext(const ConfigParameters & configParams,HGLRC shareContext)228*8975f5c5SAndroid Build Coastguard Worker HGLRC WGLWindow::createContext(const ConfigParameters &configParams, HGLRC shareContext)
229*8975f5c5SAndroid Build Coastguard Worker {
230*8975f5c5SAndroid Build Coastguard Worker     HGLRC context = _wglCreateContext(mDeviceContext);
231*8975f5c5SAndroid Build Coastguard Worker     if (!context)
232*8975f5c5SAndroid Build Coastguard Worker     {
233*8975f5c5SAndroid Build Coastguard Worker         std::cerr << "Failed to create a WGL context." << std::endl;
234*8975f5c5SAndroid Build Coastguard Worker         return context;
235*8975f5c5SAndroid Build Coastguard Worker     }
236*8975f5c5SAndroid Build Coastguard Worker 
237*8975f5c5SAndroid Build Coastguard Worker     if (!makeCurrent(context))
238*8975f5c5SAndroid Build Coastguard Worker     {
239*8975f5c5SAndroid Build Coastguard Worker         std::cerr << "Failed to make WGL context current." << std::endl;
240*8975f5c5SAndroid Build Coastguard Worker         return context;
241*8975f5c5SAndroid Build Coastguard Worker     }
242*8975f5c5SAndroid Build Coastguard Worker 
243*8975f5c5SAndroid Build Coastguard Worker     // Reload entry points to capture extensions.
244*8975f5c5SAndroid Build Coastguard Worker     LoadWGL(GetProcAddressWithFallback);
245*8975f5c5SAndroid Build Coastguard Worker 
246*8975f5c5SAndroid Build Coastguard Worker     if (!_wglGetExtensionsStringARB)
247*8975f5c5SAndroid Build Coastguard Worker     {
248*8975f5c5SAndroid Build Coastguard Worker         std::cerr << "Driver does not expose wglGetExtensionsStringARB." << std::endl;
249*8975f5c5SAndroid Build Coastguard Worker         return context;
250*8975f5c5SAndroid Build Coastguard Worker     }
251*8975f5c5SAndroid Build Coastguard Worker 
252*8975f5c5SAndroid Build Coastguard Worker     const char *extensionsString = _wglGetExtensionsStringARB(mDeviceContext);
253*8975f5c5SAndroid Build Coastguard Worker 
254*8975f5c5SAndroid Build Coastguard Worker     std::vector<std::string> extensions;
255*8975f5c5SAndroid Build Coastguard Worker     angle::SplitStringAlongWhitespace(extensionsString, &extensions);
256*8975f5c5SAndroid Build Coastguard Worker 
257*8975f5c5SAndroid Build Coastguard Worker     if (!HasExtension(extensions, "WGL_EXT_create_context_es2_profile"))
258*8975f5c5SAndroid Build Coastguard Worker     {
259*8975f5c5SAndroid Build Coastguard Worker         std::cerr << "Driver does not expose WGL_EXT_create_context_es2_profile." << std::endl;
260*8975f5c5SAndroid Build Coastguard Worker         return context;
261*8975f5c5SAndroid Build Coastguard Worker     }
262*8975f5c5SAndroid Build Coastguard Worker 
263*8975f5c5SAndroid Build Coastguard Worker     if (mConfigParams.webGLCompatibility.valid() || mConfigParams.robustResourceInit.valid())
264*8975f5c5SAndroid Build Coastguard Worker     {
265*8975f5c5SAndroid Build Coastguard Worker         std::cerr << "WGLWindow does not support the requested feature set." << std::endl;
266*8975f5c5SAndroid Build Coastguard Worker         return context;
267*8975f5c5SAndroid Build Coastguard Worker     }
268*8975f5c5SAndroid Build Coastguard Worker 
269*8975f5c5SAndroid Build Coastguard Worker     // Tear down the context and create another with ES2 compatibility.
270*8975f5c5SAndroid Build Coastguard Worker     _wglDeleteContext(context);
271*8975f5c5SAndroid Build Coastguard Worker 
272*8975f5c5SAndroid Build Coastguard Worker     // This could be extended to cover ES1 compatibility.
273*8975f5c5SAndroid Build Coastguard Worker     const int createAttribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB,
274*8975f5c5SAndroid Build Coastguard Worker                                  mClientMajorVersion,
275*8975f5c5SAndroid Build Coastguard Worker                                  WGL_CONTEXT_MINOR_VERSION_ARB,
276*8975f5c5SAndroid Build Coastguard Worker                                  mClientMinorVersion,
277*8975f5c5SAndroid Build Coastguard Worker                                  WGL_CONTEXT_PROFILE_MASK_ARB,
278*8975f5c5SAndroid Build Coastguard Worker                                  WGL_CONTEXT_ES2_PROFILE_BIT_EXT,
279*8975f5c5SAndroid Build Coastguard Worker                                  0,
280*8975f5c5SAndroid Build Coastguard Worker                                  0};
281*8975f5c5SAndroid Build Coastguard Worker 
282*8975f5c5SAndroid Build Coastguard Worker     context = _wglCreateContextAttribsARB(mDeviceContext, shareContext, createAttribs);
283*8975f5c5SAndroid Build Coastguard Worker     if (!context)
284*8975f5c5SAndroid Build Coastguard Worker     {
285*8975f5c5SAndroid Build Coastguard Worker         std::cerr << "Failed to create an ES2 compatible WGL context." << std::endl;
286*8975f5c5SAndroid Build Coastguard Worker         return context;
287*8975f5c5SAndroid Build Coastguard Worker     }
288*8975f5c5SAndroid Build Coastguard Worker 
289*8975f5c5SAndroid Build Coastguard Worker     return context;
290*8975f5c5SAndroid Build Coastguard Worker }
291*8975f5c5SAndroid Build Coastguard Worker 
destroyGL()292*8975f5c5SAndroid Build Coastguard Worker void WGLWindow::destroyGL()
293*8975f5c5SAndroid Build Coastguard Worker {
294*8975f5c5SAndroid Build Coastguard Worker     if (mWGLContext)
295*8975f5c5SAndroid Build Coastguard Worker     {
296*8975f5c5SAndroid Build Coastguard Worker         _wglDeleteContext(mWGLContext);
297*8975f5c5SAndroid Build Coastguard Worker         mWGLContext = nullptr;
298*8975f5c5SAndroid Build Coastguard Worker     }
299*8975f5c5SAndroid Build Coastguard Worker 
300*8975f5c5SAndroid Build Coastguard Worker     if (mDeviceContext)
301*8975f5c5SAndroid Build Coastguard Worker     {
302*8975f5c5SAndroid Build Coastguard Worker         ReleaseDC(mWindow, mDeviceContext);
303*8975f5c5SAndroid Build Coastguard Worker         mDeviceContext = nullptr;
304*8975f5c5SAndroid Build Coastguard Worker     }
305*8975f5c5SAndroid Build Coastguard Worker }
306*8975f5c5SAndroid Build Coastguard Worker 
isGLInitialized() const307*8975f5c5SAndroid Build Coastguard Worker bool WGLWindow::isGLInitialized() const
308*8975f5c5SAndroid Build Coastguard Worker {
309*8975f5c5SAndroid Build Coastguard Worker     return mWGLContext != nullptr;
310*8975f5c5SAndroid Build Coastguard Worker }
311*8975f5c5SAndroid Build Coastguard Worker 
getCurrentContextGeneric()312*8975f5c5SAndroid Build Coastguard Worker GLWindowContext WGLWindow::getCurrentContextGeneric()
313*8975f5c5SAndroid Build Coastguard Worker {
314*8975f5c5SAndroid Build Coastguard Worker     return reinterpret_cast<GLWindowContext>(mWGLContext);
315*8975f5c5SAndroid Build Coastguard Worker }
316*8975f5c5SAndroid Build Coastguard Worker 
createContextGeneric(GLWindowContext share)317*8975f5c5SAndroid Build Coastguard Worker GLWindowContext WGLWindow::createContextGeneric(GLWindowContext share)
318*8975f5c5SAndroid Build Coastguard Worker {
319*8975f5c5SAndroid Build Coastguard Worker     HGLRC shareContext = reinterpret_cast<HGLRC>(share);
320*8975f5c5SAndroid Build Coastguard Worker     HGLRC newContext   = createContext(mConfigParams, shareContext);
321*8975f5c5SAndroid Build Coastguard Worker 
322*8975f5c5SAndroid Build Coastguard Worker     // createContext() calls makeCurrent(newContext), so we need to restore the current context.
323*8975f5c5SAndroid Build Coastguard Worker     if (!makeCurrent())
324*8975f5c5SAndroid Build Coastguard Worker     {
325*8975f5c5SAndroid Build Coastguard Worker         return nullptr;
326*8975f5c5SAndroid Build Coastguard Worker     }
327*8975f5c5SAndroid Build Coastguard Worker 
328*8975f5c5SAndroid Build Coastguard Worker     return reinterpret_cast<GLWindowContext>(newContext);
329*8975f5c5SAndroid Build Coastguard Worker }
330*8975f5c5SAndroid Build Coastguard Worker 
makeCurrent()331*8975f5c5SAndroid Build Coastguard Worker bool WGLWindow::makeCurrent()
332*8975f5c5SAndroid Build Coastguard Worker {
333*8975f5c5SAndroid Build Coastguard Worker     return makeCurrent(mWGLContext);
334*8975f5c5SAndroid Build Coastguard Worker }
335*8975f5c5SAndroid Build Coastguard Worker 
makeCurrentGeneric(GLWindowContext context)336*8975f5c5SAndroid Build Coastguard Worker bool WGLWindow::makeCurrentGeneric(GLWindowContext context)
337*8975f5c5SAndroid Build Coastguard Worker {
338*8975f5c5SAndroid Build Coastguard Worker     HGLRC wglContext = reinterpret_cast<HGLRC>(context);
339*8975f5c5SAndroid Build Coastguard Worker     return makeCurrent(wglContext);
340*8975f5c5SAndroid Build Coastguard Worker }
341*8975f5c5SAndroid Build Coastguard Worker 
makeCurrent(HGLRC context)342*8975f5c5SAndroid Build Coastguard Worker bool WGLWindow::makeCurrent(HGLRC context)
343*8975f5c5SAndroid Build Coastguard Worker {
344*8975f5c5SAndroid Build Coastguard Worker     if (_wglMakeCurrent(mDeviceContext, context) == FALSE)
345*8975f5c5SAndroid Build Coastguard Worker     {
346*8975f5c5SAndroid Build Coastguard Worker         std::cerr << "Error during wglMakeCurrent.\n";
347*8975f5c5SAndroid Build Coastguard Worker         return false;
348*8975f5c5SAndroid Build Coastguard Worker     }
349*8975f5c5SAndroid Build Coastguard Worker 
350*8975f5c5SAndroid Build Coastguard Worker     return true;
351*8975f5c5SAndroid Build Coastguard Worker }
352*8975f5c5SAndroid Build Coastguard Worker 
createImage(GLWindowContext context,Enum target,ClientBuffer buffer,const Attrib * attrib_list)353*8975f5c5SAndroid Build Coastguard Worker WGLWindow::Image WGLWindow::createImage(GLWindowContext context,
354*8975f5c5SAndroid Build Coastguard Worker                                         Enum target,
355*8975f5c5SAndroid Build Coastguard Worker                                         ClientBuffer buffer,
356*8975f5c5SAndroid Build Coastguard Worker                                         const Attrib *attrib_list)
357*8975f5c5SAndroid Build Coastguard Worker {
358*8975f5c5SAndroid Build Coastguard Worker     std::cerr << "WGLWindow::createImage not implemented.\n";
359*8975f5c5SAndroid Build Coastguard Worker     return nullptr;
360*8975f5c5SAndroid Build Coastguard Worker }
361*8975f5c5SAndroid Build Coastguard Worker 
createImageKHR(GLWindowContext context,Enum target,ClientBuffer buffer,const AttribKHR * attrib_list)362*8975f5c5SAndroid Build Coastguard Worker WGLWindow::Image WGLWindow::createImageKHR(GLWindowContext context,
363*8975f5c5SAndroid Build Coastguard Worker                                            Enum target,
364*8975f5c5SAndroid Build Coastguard Worker                                            ClientBuffer buffer,
365*8975f5c5SAndroid Build Coastguard Worker                                            const AttribKHR *attrib_list)
366*8975f5c5SAndroid Build Coastguard Worker {
367*8975f5c5SAndroid Build Coastguard Worker     std::cerr << "WGLWindow::createImageKHR not implemented.\n";
368*8975f5c5SAndroid Build Coastguard Worker     return nullptr;
369*8975f5c5SAndroid Build Coastguard Worker }
370*8975f5c5SAndroid Build Coastguard Worker 
destroyImage(Image image)371*8975f5c5SAndroid Build Coastguard Worker EGLBoolean WGLWindow::destroyImage(Image image)
372*8975f5c5SAndroid Build Coastguard Worker {
373*8975f5c5SAndroid Build Coastguard Worker     std::cerr << "WGLWindow::destroyImage not implemented.\n";
374*8975f5c5SAndroid Build Coastguard Worker     return EGL_FALSE;
375*8975f5c5SAndroid Build Coastguard Worker }
376*8975f5c5SAndroid Build Coastguard Worker 
destroyImageKHR(Image image)377*8975f5c5SAndroid Build Coastguard Worker EGLBoolean WGLWindow::destroyImageKHR(Image image)
378*8975f5c5SAndroid Build Coastguard Worker {
379*8975f5c5SAndroid Build Coastguard Worker     std::cerr << "WGLWindow::destroyImageKHR not implemented.\n";
380*8975f5c5SAndroid Build Coastguard Worker     return EGL_FALSE;
381*8975f5c5SAndroid Build Coastguard Worker }
382*8975f5c5SAndroid Build Coastguard Worker 
createSync(EGLDisplay dpy,EGLenum type,const EGLAttrib * attrib_list)383*8975f5c5SAndroid Build Coastguard Worker WGLWindow::Sync WGLWindow::createSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
384*8975f5c5SAndroid Build Coastguard Worker {
385*8975f5c5SAndroid Build Coastguard Worker     return nullptr;
386*8975f5c5SAndroid Build Coastguard Worker }
387*8975f5c5SAndroid Build Coastguard Worker 
createSyncKHR(EGLDisplay dpy,EGLenum type,const EGLint * attrib_list)388*8975f5c5SAndroid Build Coastguard Worker WGLWindow::Sync WGLWindow::createSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
389*8975f5c5SAndroid Build Coastguard Worker {
390*8975f5c5SAndroid Build Coastguard Worker     return nullptr;
391*8975f5c5SAndroid Build Coastguard Worker }
392*8975f5c5SAndroid Build Coastguard Worker 
destroySync(EGLDisplay dpy,Sync sync)393*8975f5c5SAndroid Build Coastguard Worker EGLBoolean WGLWindow::destroySync(EGLDisplay dpy, Sync sync)
394*8975f5c5SAndroid Build Coastguard Worker {
395*8975f5c5SAndroid Build Coastguard Worker     return EGL_FALSE;
396*8975f5c5SAndroid Build Coastguard Worker }
397*8975f5c5SAndroid Build Coastguard Worker 
destroySyncKHR(EGLDisplay dpy,Sync sync)398*8975f5c5SAndroid Build Coastguard Worker EGLBoolean WGLWindow::destroySyncKHR(EGLDisplay dpy, Sync sync)
399*8975f5c5SAndroid Build Coastguard Worker {
400*8975f5c5SAndroid Build Coastguard Worker     return EGL_FALSE;
401*8975f5c5SAndroid Build Coastguard Worker }
402*8975f5c5SAndroid Build Coastguard Worker 
clientWaitSync(EGLDisplay dpy,Sync sync,EGLint flags,EGLTimeKHR timeout)403*8975f5c5SAndroid Build Coastguard Worker EGLint WGLWindow::clientWaitSync(EGLDisplay dpy, Sync sync, EGLint flags, EGLTimeKHR timeout)
404*8975f5c5SAndroid Build Coastguard Worker {
405*8975f5c5SAndroid Build Coastguard Worker     return EGL_FALSE;
406*8975f5c5SAndroid Build Coastguard Worker }
407*8975f5c5SAndroid Build Coastguard Worker 
clientWaitSyncKHR(EGLDisplay dpy,Sync sync,EGLint flags,EGLTimeKHR timeout)408*8975f5c5SAndroid Build Coastguard Worker EGLint WGLWindow::clientWaitSyncKHR(EGLDisplay dpy, Sync sync, EGLint flags, EGLTimeKHR timeout)
409*8975f5c5SAndroid Build Coastguard Worker {
410*8975f5c5SAndroid Build Coastguard Worker     return EGL_FALSE;
411*8975f5c5SAndroid Build Coastguard Worker }
412*8975f5c5SAndroid Build Coastguard Worker 
getEGLError()413*8975f5c5SAndroid Build Coastguard Worker EGLint WGLWindow::getEGLError()
414*8975f5c5SAndroid Build Coastguard Worker {
415*8975f5c5SAndroid Build Coastguard Worker     return EGL_SUCCESS;
416*8975f5c5SAndroid Build Coastguard Worker }
417*8975f5c5SAndroid Build Coastguard Worker 
getCurrentDisplay()418*8975f5c5SAndroid Build Coastguard Worker WGLWindow::Display WGLWindow::getCurrentDisplay()
419*8975f5c5SAndroid Build Coastguard Worker {
420*8975f5c5SAndroid Build Coastguard Worker     return nullptr;
421*8975f5c5SAndroid Build Coastguard Worker }
422*8975f5c5SAndroid Build Coastguard Worker 
createPbufferSurface(const EGLint * attrib_list)423*8975f5c5SAndroid Build Coastguard Worker WGLWindow::Surface WGLWindow::createPbufferSurface(const EGLint *attrib_list)
424*8975f5c5SAndroid Build Coastguard Worker {
425*8975f5c5SAndroid Build Coastguard Worker     std::cerr << "WGLWindow::createPbufferSurface not implemented.\n";
426*8975f5c5SAndroid Build Coastguard Worker     return EGL_FALSE;
427*8975f5c5SAndroid Build Coastguard Worker }
428*8975f5c5SAndroid Build Coastguard Worker 
destroySurface(Surface surface)429*8975f5c5SAndroid Build Coastguard Worker EGLBoolean WGLWindow::destroySurface(Surface surface)
430*8975f5c5SAndroid Build Coastguard Worker {
431*8975f5c5SAndroid Build Coastguard Worker     std::cerr << "WGLWindow::destroySurface not implemented.\n";
432*8975f5c5SAndroid Build Coastguard Worker     return EGL_FALSE;
433*8975f5c5SAndroid Build Coastguard Worker }
434*8975f5c5SAndroid Build Coastguard Worker 
bindTexImage(EGLSurface surface,EGLint buffer)435*8975f5c5SAndroid Build Coastguard Worker EGLBoolean WGLWindow::bindTexImage(EGLSurface surface, EGLint buffer)
436*8975f5c5SAndroid Build Coastguard Worker {
437*8975f5c5SAndroid Build Coastguard Worker     std::cerr << "WGLWindow::bindTexImage not implemented.\n";
438*8975f5c5SAndroid Build Coastguard Worker     return EGL_FALSE;
439*8975f5c5SAndroid Build Coastguard Worker }
440*8975f5c5SAndroid Build Coastguard Worker 
releaseTexImage(EGLSurface surface,EGLint buffer)441*8975f5c5SAndroid Build Coastguard Worker EGLBoolean WGLWindow::releaseTexImage(EGLSurface surface, EGLint buffer)
442*8975f5c5SAndroid Build Coastguard Worker {
443*8975f5c5SAndroid Build Coastguard Worker     std::cerr << "WGLWindow::releaseTexImage not implemented.\n";
444*8975f5c5SAndroid Build Coastguard Worker     return EGL_FALSE;
445*8975f5c5SAndroid Build Coastguard Worker }
446*8975f5c5SAndroid Build Coastguard Worker 
makeCurrent(EGLSurface draw,EGLSurface read,EGLContext context)447*8975f5c5SAndroid Build Coastguard Worker bool WGLWindow::makeCurrent(EGLSurface draw, EGLSurface read, EGLContext context)
448*8975f5c5SAndroid Build Coastguard Worker {
449*8975f5c5SAndroid Build Coastguard Worker     std::cerr << "WGLWindow::makeCurrent(draw, read, context) not implemented.\n";
450*8975f5c5SAndroid Build Coastguard Worker     return EGL_FALSE;
451*8975f5c5SAndroid Build Coastguard Worker }
452*8975f5c5SAndroid Build Coastguard Worker 
setSwapInterval(EGLint swapInterval)453*8975f5c5SAndroid Build Coastguard Worker bool WGLWindow::setSwapInterval(EGLint swapInterval)
454*8975f5c5SAndroid Build Coastguard Worker {
455*8975f5c5SAndroid Build Coastguard Worker     if (!_wglSwapIntervalEXT || _wglSwapIntervalEXT(swapInterval) == FALSE)
456*8975f5c5SAndroid Build Coastguard Worker     {
457*8975f5c5SAndroid Build Coastguard Worker         std::cerr << "Error during wglSwapIntervalEXT.\n";
458*8975f5c5SAndroid Build Coastguard Worker         return false;
459*8975f5c5SAndroid Build Coastguard Worker     }
460*8975f5c5SAndroid Build Coastguard Worker     return true;
461*8975f5c5SAndroid Build Coastguard Worker }
462*8975f5c5SAndroid Build Coastguard Worker 
swap()463*8975f5c5SAndroid Build Coastguard Worker void WGLWindow::swap()
464*8975f5c5SAndroid Build Coastguard Worker {
465*8975f5c5SAndroid Build Coastguard Worker     if (SwapBuffers(mDeviceContext) == FALSE)
466*8975f5c5SAndroid Build Coastguard Worker     {
467*8975f5c5SAndroid Build Coastguard Worker         std::cerr << "Error during SwapBuffers.\n";
468*8975f5c5SAndroid Build Coastguard Worker     }
469*8975f5c5SAndroid Build Coastguard Worker }
470*8975f5c5SAndroid Build Coastguard Worker 
hasError() const471*8975f5c5SAndroid Build Coastguard Worker bool WGLWindow::hasError() const
472*8975f5c5SAndroid Build Coastguard Worker {
473*8975f5c5SAndroid Build Coastguard Worker     return GetLastError() != S_OK;
474*8975f5c5SAndroid Build Coastguard Worker }
475*8975f5c5SAndroid Build Coastguard Worker 
getProcAddress(const char * name)476*8975f5c5SAndroid Build Coastguard Worker GenericProc WGLWindow::getProcAddress(const char *name)
477*8975f5c5SAndroid Build Coastguard Worker {
478*8975f5c5SAndroid Build Coastguard Worker     return GetProcAddressWithFallback(name);
479*8975f5c5SAndroid Build Coastguard Worker }
480*8975f5c5SAndroid Build Coastguard Worker 
481*8975f5c5SAndroid Build Coastguard Worker // static
New(int majorVersion,int minorVersion)482*8975f5c5SAndroid Build Coastguard Worker WGLWindow *WGLWindow::New(int majorVersion, int minorVersion)
483*8975f5c5SAndroid Build Coastguard Worker {
484*8975f5c5SAndroid Build Coastguard Worker     return new WGLWindow(majorVersion, minorVersion);
485*8975f5c5SAndroid Build Coastguard Worker }
486*8975f5c5SAndroid Build Coastguard Worker 
487*8975f5c5SAndroid Build Coastguard Worker // static
Delete(WGLWindow ** window)488*8975f5c5SAndroid Build Coastguard Worker void WGLWindow::Delete(WGLWindow **window)
489*8975f5c5SAndroid Build Coastguard Worker {
490*8975f5c5SAndroid Build Coastguard Worker     delete *window;
491*8975f5c5SAndroid Build Coastguard Worker     *window = nullptr;
492*8975f5c5SAndroid Build Coastguard Worker }
493