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