Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/util/windows/WGLWindow.cpp
1693 views
1
//
2
// Copyright 2018 The ANGLE Project Authors. All rights reserved.
3
// Use of this source code is governed by a BSD-style license that can be
4
// found in the LICENSE file.
5
//
6
// WGLWindow:
7
// Implements initializing a WGL rendering context.
8
//
9
10
#include "util/windows/WGLWindow.h"
11
12
#include "common/string_utils.h"
13
#include "common/system_utils.h"
14
#include "util/OSWindow.h"
15
16
#include <iostream>
17
18
namespace
19
{
20
PIXELFORMATDESCRIPTOR GetDefaultPixelFormatDescriptor()
21
{
22
PIXELFORMATDESCRIPTOR pixelFormatDescriptor = {};
23
pixelFormatDescriptor.nSize = sizeof(pixelFormatDescriptor);
24
pixelFormatDescriptor.nVersion = 1;
25
pixelFormatDescriptor.dwFlags =
26
PFD_DRAW_TO_WINDOW | PFD_GENERIC_ACCELERATED | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
27
pixelFormatDescriptor.iPixelType = PFD_TYPE_RGBA;
28
pixelFormatDescriptor.cColorBits = 24;
29
pixelFormatDescriptor.cAlphaBits = 8;
30
pixelFormatDescriptor.cDepthBits = 24;
31
pixelFormatDescriptor.cStencilBits = 8;
32
pixelFormatDescriptor.iLayerType = PFD_MAIN_PLANE;
33
34
return pixelFormatDescriptor;
35
}
36
37
PFNWGLGETPROCADDRESSPROC gCurrentWGLGetProcAddress = nullptr;
38
HMODULE gCurrentModule = nullptr;
39
40
angle::GenericProc WINAPI GetProcAddressWithFallback(const char *name)
41
{
42
angle::GenericProc proc = reinterpret_cast<angle::GenericProc>(gCurrentWGLGetProcAddress(name));
43
if (proc)
44
{
45
return proc;
46
}
47
48
return reinterpret_cast<angle::GenericProc>(GetProcAddress(gCurrentModule, name));
49
}
50
51
bool HasExtension(const std::vector<std::string> &extensions, const char *ext)
52
{
53
return std::find(extensions.begin(), extensions.end(), ext) != extensions.end();
54
}
55
56
void DumpLastWindowsError()
57
{
58
std::cerr << "Last Windows error code: 0x" << std::hex << GetLastError() << std::endl;
59
}
60
} // namespace
61
62
WGLWindow::WGLWindow(int glesMajorVersion, int glesMinorVersion)
63
: GLWindowBase(glesMajorVersion, glesMinorVersion),
64
mDeviceContext(nullptr),
65
mWGLContext(nullptr),
66
mWindow(nullptr)
67
{}
68
69
WGLWindow::~WGLWindow() {}
70
71
// Internally initializes GL resources.
72
bool WGLWindow::initializeGL(OSWindow *osWindow,
73
angle::Library *glWindowingLibrary,
74
angle::GLESDriverType driverType,
75
const EGLPlatformParameters &platformParams,
76
const ConfigParameters &configParams)
77
{
78
if (driverType != angle::GLESDriverType::SystemWGL)
79
{
80
std::cerr << "WGLWindow requires angle::GLESDriverType::SystemWGL.\n";
81
return false;
82
}
83
84
glWindowingLibrary->getAs("wglGetProcAddress", &gCurrentWGLGetProcAddress);
85
86
if (!gCurrentWGLGetProcAddress)
87
{
88
std::cerr << "Error loading wglGetProcAddress." << std::endl;
89
return false;
90
}
91
92
gCurrentModule = reinterpret_cast<HMODULE>(glWindowingLibrary->getNative());
93
angle::LoadWGL(GetProcAddressWithFallback);
94
95
mWindow = osWindow->getNativeWindow();
96
mDeviceContext = GetDC(mWindow);
97
const PIXELFORMATDESCRIPTOR pixelFormatDescriptor = GetDefaultPixelFormatDescriptor();
98
99
int pixelFormat = ChoosePixelFormat(mDeviceContext, &pixelFormatDescriptor);
100
if (pixelFormat == 0)
101
{
102
std::cerr << "Could not find a compatible pixel format." << std::endl;
103
DumpLastWindowsError();
104
return false;
105
}
106
107
// According to the Windows docs, it is an error to set a pixel format twice.
108
int currentPixelFormat = GetPixelFormat(mDeviceContext);
109
if (currentPixelFormat != pixelFormat)
110
{
111
if (SetPixelFormat(mDeviceContext, pixelFormat, &pixelFormatDescriptor) != TRUE)
112
{
113
std::cerr << "Failed to set the pixel format." << std::endl;
114
DumpLastWindowsError();
115
return false;
116
}
117
}
118
119
mWGLContext = createContext(configParams, nullptr);
120
if (mWGLContext == nullptr)
121
{
122
return false;
123
}
124
125
if (!makeCurrent())
126
{
127
return false;
128
}
129
130
mPlatform = platformParams;
131
mConfigParams = configParams;
132
133
angle::LoadGLES(GetProcAddressWithFallback);
134
return true;
135
}
136
137
HGLRC WGLWindow::createContext(const ConfigParameters &configParams, HGLRC shareContext)
138
{
139
HGLRC context = _wglCreateContext(mDeviceContext);
140
if (!context)
141
{
142
std::cerr << "Failed to create a WGL context." << std::endl;
143
return context;
144
}
145
146
if (!makeCurrent(context))
147
{
148
std::cerr << "Failed to make WGL context current." << std::endl;
149
return context;
150
}
151
152
// Reload entry points to capture extensions.
153
angle::LoadWGL(GetProcAddressWithFallback);
154
155
if (!_wglGetExtensionsStringARB)
156
{
157
std::cerr << "Driver does not expose wglGetExtensionsStringARB." << std::endl;
158
return context;
159
}
160
161
const char *extensionsString = _wglGetExtensionsStringARB(mDeviceContext);
162
163
std::vector<std::string> extensions;
164
angle::SplitStringAlongWhitespace(extensionsString, &extensions);
165
166
if (!HasExtension(extensions, "WGL_EXT_create_context_es2_profile"))
167
{
168
std::cerr << "Driver does not expose WGL_EXT_create_context_es2_profile." << std::endl;
169
return context;
170
}
171
172
if (mConfigParams.webGLCompatibility.valid() || mConfigParams.robustResourceInit.valid())
173
{
174
std::cerr << "WGLWindow does not support the requested feature set." << std::endl;
175
return context;
176
}
177
178
// Tear down the context and create another with ES2 compatibility.
179
_wglDeleteContext(context);
180
181
// This could be extended to cover ES1 compatiblity.
182
int kCreateAttribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB,
183
mClientMajorVersion,
184
WGL_CONTEXT_MINOR_VERSION_ARB,
185
mClientMinorVersion,
186
WGL_CONTEXT_PROFILE_MASK_ARB,
187
WGL_CONTEXT_ES2_PROFILE_BIT_EXT,
188
0,
189
0};
190
191
context = _wglCreateContextAttribsARB(mDeviceContext, shareContext, kCreateAttribs);
192
if (!context)
193
{
194
std::cerr << "Failed to create an ES2 compatible WGL context." << std::endl;
195
return context;
196
}
197
198
return context;
199
}
200
201
void WGLWindow::destroyGL()
202
{
203
if (mWGLContext)
204
{
205
_wglDeleteContext(mWGLContext);
206
mWGLContext = nullptr;
207
}
208
209
if (mDeviceContext)
210
{
211
ReleaseDC(mWindow, mDeviceContext);
212
mDeviceContext = nullptr;
213
}
214
}
215
216
bool WGLWindow::isGLInitialized() const
217
{
218
return mWGLContext != nullptr;
219
}
220
221
GLWindowContext WGLWindow::getCurrentContextGeneric()
222
{
223
return reinterpret_cast<GLWindowContext>(mWGLContext);
224
}
225
226
GLWindowContext WGLWindow::createContextGeneric(GLWindowContext share)
227
{
228
HGLRC shareContext = reinterpret_cast<HGLRC>(share);
229
HGLRC newContext = createContext(mConfigParams, shareContext);
230
231
// createContext() calls makeCurrent(newContext), so we need to restore the current context.
232
if (!makeCurrent())
233
{
234
return nullptr;
235
}
236
237
return reinterpret_cast<GLWindowContext>(newContext);
238
}
239
240
bool WGLWindow::makeCurrent()
241
{
242
return makeCurrent(mWGLContext);
243
}
244
245
bool WGLWindow::makeCurrentGeneric(GLWindowContext context)
246
{
247
HGLRC wglContext = reinterpret_cast<HGLRC>(context);
248
return makeCurrent(wglContext);
249
}
250
251
bool WGLWindow::makeCurrent(HGLRC context)
252
{
253
if (_wglMakeCurrent(mDeviceContext, context) == FALSE)
254
{
255
std::cerr << "Error during wglMakeCurrent.\n";
256
return false;
257
}
258
259
return true;
260
}
261
262
bool WGLWindow::setSwapInterval(EGLint swapInterval)
263
{
264
if (!_wglSwapIntervalEXT || _wglSwapIntervalEXT(swapInterval) == FALSE)
265
{
266
std::cerr << "Error during wglSwapIntervalEXT.\n";
267
return false;
268
}
269
return true;
270
}
271
272
void WGLWindow::swap()
273
{
274
if (SwapBuffers(mDeviceContext) == FALSE)
275
{
276
std::cerr << "Error during SwapBuffers.\n";
277
}
278
}
279
280
bool WGLWindow::hasError() const
281
{
282
return GetLastError() != S_OK;
283
}
284
285
angle::GenericProc WGLWindow::getProcAddress(const char *name)
286
{
287
return GetProcAddressWithFallback(name);
288
}
289
290
// static
291
WGLWindow *WGLWindow::New(int glesMajorVersion, int glesMinorVersion)
292
{
293
return new WGLWindow(glesMajorVersion, glesMinorVersion);
294
}
295
296
// static
297
void WGLWindow::Delete(WGLWindow **window)
298
{
299
delete *window;
300
*window = nullptr;
301
}
302
303