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