1 //
2 // Copyright 2019 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 // entry_points_wgl.cpp: Implements the exported WGL functions.
7
8 #include "entry_points_wgl.h"
9
10 #include "common/debug.h"
11 #include "common/event_tracer.h"
12 #include "common/utilities.h"
13 #include "libANGLE/Context.h"
14 #include "libANGLE/Display.h"
15 #include "libANGLE/EGLSync.h"
16 #include "libANGLE/Surface.h"
17 #include "libANGLE/Texture.h"
18 #include "libANGLE/Thread.h"
19 #include "libANGLE/entry_points_utils.h"
20 #include "libANGLE/queryutils.h"
21 #include "libANGLE/validationEGL.h"
22 #include "libGL/proc_table_wgl.h"
23 #include "libGLESv2/global_state.h"
24
25 using namespace wgl;
26 using namespace egl;
27
28 namespace
29 {
30
CompareProc(const ProcEntry & a,const char * b)31 bool CompareProc(const ProcEntry &a, const char *b)
32 {
33 return strcmp(a.first, b) < 0;
34 }
35
ClipConfigs(const std::vector<const Config * > & filteredConfigs,EGLConfig * output_configs,EGLint config_size,EGLint * num_config)36 void ClipConfigs(const std::vector<const Config *> &filteredConfigs,
37 EGLConfig *output_configs,
38 EGLint config_size,
39 EGLint *num_config)
40 {
41 EGLint result_size = static_cast<EGLint>(filteredConfigs.size());
42 if (output_configs)
43 {
44 result_size = std::max(std::min(result_size, config_size), 0);
45 for (EGLint i = 0; i < result_size; i++)
46 {
47 output_configs[i] = const_cast<Config *>(filteredConfigs[i]);
48 }
49 }
50 *num_config = result_size;
51 }
52 } // anonymous namespace
53
54 #define WGL_EVENT(EP, FMT, ...) EVENT(nullptr, WGL##EP, FMT, __VA_ARGS__)
55
56 extern "C" {
57
58 // WGL 1.0
wglChoosePixelFormat(HDC hDc,const PIXELFORMATDESCRIPTOR * pPfd)59 int GL_APIENTRY wglChoosePixelFormat(HDC hDc, const PIXELFORMATDESCRIPTOR *pPfd)
60 {
61 UNIMPLEMENTED();
62 return 1;
63 }
64
wglDescribePixelFormat(HDC hdc,int ipfd,UINT cjpfd,PIXELFORMATDESCRIPTOR * ppfd)65 int GL_APIENTRY wglDescribePixelFormat(HDC hdc, int ipfd, UINT cjpfd, PIXELFORMATDESCRIPTOR *ppfd)
66 {
67 UNIMPLEMENTED();
68 if (ppfd)
69 {
70 ppfd->dwFlags = ppfd->dwFlags | PFD_DRAW_TO_WINDOW;
71 ppfd->dwFlags = ppfd->dwFlags | PFD_SUPPORT_OPENGL;
72 ppfd->dwFlags = ppfd->dwFlags | PFD_GENERIC_ACCELERATED;
73 ppfd->dwFlags = ppfd->dwFlags | PFD_DOUBLEBUFFER;
74 ppfd->iPixelType = PFD_TYPE_RGBA;
75 ppfd->cColorBits = 24;
76 ppfd->cRedBits = 8;
77 ppfd->cGreenBits = 8;
78 ppfd->cBlueBits = 8;
79 ppfd->cAlphaBits = 8;
80 ppfd->cDepthBits = 24;
81 ppfd->cStencilBits = 8;
82 ppfd->nVersion = 1;
83 }
84 return 1;
85 }
86
wglGetEnhMetaFilePixelFormat(HENHMETAFILE hemf,UINT cbBuffer,PIXELFORMATDESCRIPTOR * ppfd)87 UINT GL_APIENTRY wglGetEnhMetaFilePixelFormat(HENHMETAFILE hemf,
88 UINT cbBuffer,
89 PIXELFORMATDESCRIPTOR *ppfd)
90 {
91 UNIMPLEMENTED();
92 return 1u;
93 }
94
wglGetPixelFormat(HDC hdc)95 int GL_APIENTRY wglGetPixelFormat(HDC hdc)
96 {
97 UNIMPLEMENTED();
98 return 1;
99 }
100
wglSetPixelFormat(HDC hdc,int ipfd,const PIXELFORMATDESCRIPTOR * ppfd)101 BOOL GL_APIENTRY wglSetPixelFormat(HDC hdc, int ipfd, const PIXELFORMATDESCRIPTOR *ppfd)
102 {
103 UNIMPLEMENTED();
104 return TRUE;
105 }
106
wglSwapBuffers(HDC hdc)107 BOOL GL_APIENTRY wglSwapBuffers(HDC hdc)
108 {
109 Thread *thread = egl::GetCurrentThread();
110 egl::Display *display = egl::Display::GetExistingDisplayFromNativeDisplay(hdc);
111
112 ANGLE_EGL_TRY_RETURN(thread, display->getWGLSurface()->swap(thread->getContext()),
113 "wglSwapBuffers", display->getWGLSurface(), FALSE);
114 return TRUE;
115 }
116
wglCopyContext(HGLRC hglrcSrc,HGLRC hglrcDst,UINT mask)117 BOOL GL_APIENTRY wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask)
118 {
119 UNIMPLEMENTED();
120 return TRUE;
121 }
122
wglCreateContext(HDC hDc)123 HGLRC GL_APIENTRY wglCreateContext(HDC hDc)
124 {
125 Thread *thread = egl::GetCurrentThread();
126
127 std::vector<EGLAttrib> displayAttributes;
128 displayAttributes.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
129 GLenum platformType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
130 displayAttributes.push_back(platformType);
131 displayAttributes.push_back(EGL_NONE);
132
133 const auto &attribMapDisplay = AttributeMap::CreateFromAttribArray(displayAttributes.data());
134
135 egl::Display *display = egl::Display::GetDisplayFromNativeDisplay(hDc, attribMapDisplay);
136
137 ANGLE_EGL_TRY_RETURN(thread, display->initialize(), "wglCreateContext", display, nullptr);
138
139 thread->setAPI(EGL_OPENGL_API);
140
141 // Default config
142 const EGLint configAttributes[] = {EGL_NONE};
143
144 // Choose config
145 EGLint configCount;
146 EGLConfig config;
147 AttributeMap attribMapConfig = AttributeMap::CreateFromIntArray(configAttributes);
148 ClipConfigs(display->chooseConfig(attribMapConfig), &config, 1, &configCount);
149
150 Config *configuration = static_cast<Config *>(config);
151
152 // Initialize surface
153 std::vector<EGLint> surfaceAttributes;
154 surfaceAttributes.push_back(EGL_NONE);
155 surfaceAttributes.push_back(EGL_NONE);
156 AttributeMap surfAttributes = AttributeMap::CreateFromIntArray(&surfaceAttributes[0]);
157
158 // Create first window surface
159 egl::Surface *surface = nullptr;
160 ANGLE_EGL_TRY_RETURN(
161 thread,
162 display->createWindowSurface(configuration, WindowFromDC(hDc), surfAttributes, &surface),
163 "wglCreateContext", display, nullptr);
164
165 // Initialize context
166 EGLint contextAttibutes[] = {EGL_CONTEXT_CLIENT_VERSION, 4, EGL_CONTEXT_MINOR_VERSION, 6,
167 EGL_NONE};
168
169 gl::Context *sharedGLContext = static_cast<gl::Context *>(nullptr);
170 AttributeMap ctxAttributes = AttributeMap::CreateFromIntArray(contextAttibutes);
171
172 gl::Context *context = nullptr;
173
174 ANGLE_EGL_TRY_RETURN(thread,
175 display->createContext(configuration, sharedGLContext, EGL_OPENGL_API,
176 ctxAttributes, &context),
177 "wglCreateContext", display, nullptr);
178
179 return reinterpret_cast<HGLRC>(context);
180 }
181
wglCreateLayerContext(HDC hDc,int level)182 HGLRC GL_APIENTRY wglCreateLayerContext(HDC hDc, int level)
183 {
184 UNIMPLEMENTED();
185 return nullptr;
186 }
187
wglDeleteContext(HGLRC oldContext)188 BOOL GL_APIENTRY wglDeleteContext(HGLRC oldContext)
189 {
190 UNIMPLEMENTED();
191 return FALSE;
192 }
193
wglDescribeLayerPlane(HDC hDc,int pixelFormat,int layerPlane,UINT nBytes,LAYERPLANEDESCRIPTOR * plpd)194 BOOL GL_APIENTRY wglDescribeLayerPlane(HDC hDc,
195 int pixelFormat,
196 int layerPlane,
197 UINT nBytes,
198 LAYERPLANEDESCRIPTOR *plpd)
199 {
200 UNIMPLEMENTED();
201 return FALSE;
202 }
203
wglGetCurrentContext()204 HGLRC GL_APIENTRY wglGetCurrentContext()
205 {
206 UNIMPLEMENTED();
207 return nullptr;
208 }
209
wglGetCurrentDC()210 HDC GL_APIENTRY wglGetCurrentDC()
211 {
212 UNIMPLEMENTED();
213 return nullptr;
214 }
215
216 int GL_APIENTRY
wglGetLayerPaletteEntries(HDC hdc,int iLayerPlane,int iStart,int cEntries,COLORREF * pcr)217 wglGetLayerPaletteEntries(HDC hdc, int iLayerPlane, int iStart, int cEntries, COLORREF *pcr)
218 {
219 UNIMPLEMENTED();
220 return 0;
221 }
222
wglGetProcAddress(LPCSTR lpszProc)223 PROC GL_APIENTRY wglGetProcAddress(LPCSTR lpszProc)
224 {
225 ANGLE_SCOPED_GLOBAL_LOCK();
226 WGL_EVENT(GetProcAddress, "const char *procname = \"%s\"", lpszProc);
227 egl::Thread *thread = egl::GetCurrentThread();
228
229 const ProcEntry *entry =
230 std::lower_bound(&g_procTable[0], &g_procTable[g_numProcs], lpszProc, CompareProc);
231
232 thread->setSuccess();
233
234 if (entry == &g_procTable[g_numProcs] || strcmp(entry->first, lpszProc) != 0)
235 {
236 return nullptr;
237 }
238
239 return entry->second;
240 }
241
wglMakeCurrent(HDC hDc,HGLRC newContext)242 BOOL GL_APIENTRY wglMakeCurrent(HDC hDc, HGLRC newContext)
243 {
244 Thread *thread = egl::GetCurrentThread();
245 egl::Display *display = egl::Display::GetExistingDisplayFromNativeDisplay(hDc);
246 const gl::Context *context =
247 GetContextIfValid(display, reinterpret_cast<gl::Context *>(newContext));
248
249 ScopedSyncCurrentContextFromThread scopedSyncCurrent(thread);
250
251 // If display or context are invalid, make thread's current rendering context not current
252 if (!context)
253 {
254 gl::Context *oldContext = thread->getContext();
255 if (oldContext)
256 {
257 ANGLE_EGL_TRY_RETURN(thread, oldContext->unMakeCurrent(display), "wglMakeCurrent",
258 GetContextIfValid(display, oldContext), EGL_FALSE);
259 thread->setCurrent(nullptr);
260 }
261 return TRUE;
262 }
263
264 egl::Surface *surface = display->getWGLSurface();
265 Surface *previousDraw = thread->getCurrentDrawSurface();
266 Surface *previousRead = thread->getCurrentReadSurface();
267 gl::Context *previousContext = thread->getContext();
268
269 if (previousDraw != surface || previousRead != surface || previousContext != context)
270 {
271 ANGLE_EGL_TRY_RETURN(thread,
272 display->makeCurrent(thread, previousContext, surface, surface,
273 const_cast<gl::Context *>(context)),
274 "wglMakeCurrent", GetContextIfValid(display, context), EGL_FALSE);
275 }
276
277 return TRUE;
278 }
279
wglRealizeLayerPalette(HDC hdc,int iLayerPlane,BOOL bRealize)280 BOOL GL_APIENTRY wglRealizeLayerPalette(HDC hdc, int iLayerPlane, BOOL bRealize)
281 {
282 UNIMPLEMENTED();
283 return FALSE;
284 }
285
286 int GL_APIENTRY
wglSetLayerPaletteEntries(HDC hdc,int iLayerPlane,int iStart,int cEntries,const COLORREF * pcr)287 wglSetLayerPaletteEntries(HDC hdc, int iLayerPlane, int iStart, int cEntries, const COLORREF *pcr)
288 {
289 UNIMPLEMENTED();
290 return 0;
291 }
292
wglShareLists(HGLRC hrcSrvShare,HGLRC hrcSrvSource)293 BOOL GL_APIENTRY wglShareLists(HGLRC hrcSrvShare, HGLRC hrcSrvSource)
294 {
295 UNIMPLEMENTED();
296 return FALSE;
297 }
298
wglSwapLayerBuffers(HDC hdc,UINT fuFlags)299 BOOL GL_APIENTRY wglSwapLayerBuffers(HDC hdc, UINT fuFlags)
300 {
301 UNIMPLEMENTED();
302 return FALSE;
303 }
304
wglUseFontBitmapsA(HDC hDC,DWORD first,DWORD count,DWORD listBase)305 BOOL GL_APIENTRY wglUseFontBitmapsA(HDC hDC, DWORD first, DWORD count, DWORD listBase)
306 {
307 UNIMPLEMENTED();
308 return FALSE;
309 }
310
wglUseFontBitmapsW(HDC hDC,DWORD first,DWORD count,DWORD listBase)311 BOOL GL_APIENTRY wglUseFontBitmapsW(HDC hDC, DWORD first, DWORD count, DWORD listBase)
312 {
313 UNIMPLEMENTED();
314 return FALSE;
315 }
316
wglUseFontOutlinesA(HDC hDC,DWORD first,DWORD count,DWORD listBase,FLOAT deviation,FLOAT extrusion,int format,LPGLYPHMETRICSFLOAT lpgmf)317 BOOL GL_APIENTRY wglUseFontOutlinesA(HDC hDC,
318 DWORD first,
319 DWORD count,
320 DWORD listBase,
321 FLOAT deviation,
322 FLOAT extrusion,
323 int format,
324 LPGLYPHMETRICSFLOAT lpgmf)
325 {
326 UNIMPLEMENTED();
327 return FALSE;
328 }
329
wglUseFontOutlinesW(HDC hDC,DWORD first,DWORD count,DWORD listBase,FLOAT deviation,FLOAT extrusion,int format,LPGLYPHMETRICSFLOAT lpgmf)330 BOOL GL_APIENTRY wglUseFontOutlinesW(HDC hDC,
331 DWORD first,
332 DWORD count,
333 DWORD listBase,
334 FLOAT deviation,
335 FLOAT extrusion,
336 int format,
337 LPGLYPHMETRICSFLOAT lpgmf)
338 {
339 UNIMPLEMENTED();
340 return FALSE;
341 }
342
343 } // extern "C"
344