1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include "EglOsApi.h"
17 #include <windows.h>
18 #include <wingdi.h>
19 #include <GL/wglext.h>
20 #include <stdio.h>
21
22 #define IS_TRUE(a) \
23 if(a != true) return false;
24
25
26 struct DisplayInfo{
DisplayInfoDisplayInfo27 DisplayInfo():dc(NULL),hwnd(NULL),isPixelFormatSet(false){};
DisplayInfoDisplayInfo28 DisplayInfo(HDC hdc,HWND wnd):isPixelFormatSet(false){dc = hdc; hwnd = wnd;};
29 HDC dc;
30 HWND hwnd;
31 bool isPixelFormatSet;
32 };
33
34 struct TlsData {
35 std::map<int,DisplayInfo> m_map;
36 };
37
38 static DWORD s_tlsIndex = 0;
39
getTLS()40 static TlsData *getTLS() {
41 TlsData *tls = (TlsData *)TlsGetValue(s_tlsIndex);
42 if (!tls) {
43 tls = new TlsData();
44 TlsSetValue(s_tlsIndex, tls);
45 }
46 return tls;
47 }
48
49 class WinDisplay{
50 public:
51 typedef enum {
52 DEFAULT_DISPLAY = 0
53 };
WinDisplay()54 WinDisplay(){};
getInfo(int configurationIndex)55 DisplayInfo& getInfo(int configurationIndex){ return getTLS()->m_map[configurationIndex];}
getDC(int configId)56 HDC getDC(int configId){return getTLS()->m_map[configId].dc;}
57 void setInfo(int configurationIndex,const DisplayInfo& info);
isPixelFormatSet(int cfgId)58 bool isPixelFormatSet(int cfgId){ return getTLS()->m_map[cfgId].isPixelFormatSet;}
pixelFormatWasSet(int cfgId)59 void pixelFormatWasSet(int cfgId){getTLS()->m_map[cfgId].isPixelFormatSet = true;}
60 bool infoExists(int configurationIndex);
61 void releaseAll();
62 };
63
releaseAll()64 void WinDisplay::releaseAll(){
65 TlsData * tls = getTLS();
66
67 for(std::map<int,DisplayInfo>::iterator it = tls->m_map.begin(); it != tls->m_map.end();it++){
68 if((*it).second.hwnd){
69 DestroyWindow((*it).second.hwnd);
70 }
71 DeleteDC((*it).second.dc);
72 }
73 }
74
infoExists(int configurationIndex)75 bool WinDisplay::infoExists(int configurationIndex){
76 return getTLS()->m_map.find(configurationIndex) != getTLS()->m_map.end();
77 }
78
setInfo(int configurationIndex,const DisplayInfo & info)79 void WinDisplay::setInfo(int configurationIndex,const DisplayInfo& info){
80 getTLS()->m_map[configurationIndex] = info;
81 }
82
83 struct WglExtProcs{
84 PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB;
85 PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB;
86 PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB;
87 PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB;
88 PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB;
89 PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB;
90 PFNWGLMAKECONTEXTCURRENTARBPROC wglMakeContextCurrentARB;
91 PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
92 };
93
94 static WglExtProcs* s_wglExtProcs = NULL;
95
96 class SrfcInfo{
97 public:
98 typedef enum {
99 WINDOW = 0,
100 PBUFFER = 1,
101 PIXMAP = 2
102 }SurfaceType;
103 explicit SrfcInfo(HWND wnd);
104 explicit SrfcInfo(HPBUFFERARB pb);
105 explicit SrfcInfo(HBITMAP bmap);
getHwnd()106 HWND getHwnd(){ return m_hwnd;};
getDC()107 HDC getDC(){ return m_hdc;};
getBmap()108 HBITMAP getBmap(){ return m_bmap;};
getPbuffer()109 HPBUFFERARB getPbuffer(){ return m_pb;};
110 ~SrfcInfo();
111 private:
112 HWND m_hwnd;
113 HPBUFFERARB m_pb;
114 HBITMAP m_bmap;
115 HDC m_hdc;
116 SurfaceType m_type;
117 };
118
SrfcInfo(HBITMAP bmap)119 SrfcInfo::SrfcInfo(HBITMAP bmap):m_hwnd(NULL),
120 m_pb(NULL),
121 m_hdc(NULL),
122 m_type(PIXMAP){
123 m_bmap = bmap;
124 }
125
SrfcInfo(HWND wnd)126 SrfcInfo::SrfcInfo(HWND wnd):m_pb(NULL),
127 m_bmap(NULL),
128 m_type(WINDOW){
129 m_hwnd = wnd;
130 m_hdc = GetDC(wnd);
131 }
132
SrfcInfo(HPBUFFERARB pb)133 SrfcInfo::SrfcInfo(HPBUFFERARB pb):m_hwnd(NULL),
134 m_bmap(NULL),
135 m_type(PBUFFER){
136 m_pb = pb;
137 if(s_wglExtProcs->wglGetPbufferDCARB){
138 m_hdc = s_wglExtProcs->wglGetPbufferDCARB(pb);
139 }
140 }
141
~SrfcInfo()142 SrfcInfo::~SrfcInfo(){
143 if(m_type == WINDOW){
144 ReleaseDC(m_hwnd,m_hdc);
145 }
146 }
147
148 namespace EglOS{
149
150
151
wglGetExtentionsProcAddress(HDC hdc,const char * extension_name,const char * proc_name)152 PROC wglGetExtentionsProcAddress(HDC hdc,const char *extension_name,const char* proc_name)
153 {
154 // this is pointer to function which returns pointer to string with list of all wgl extensions
155 PFNWGLGETEXTENSIONSSTRINGARBPROC _wglGetExtensionsStringARB = NULL;
156
157 // determine pointer to wglGetExtensionsStringEXT function
158 _wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress("wglGetExtensionsStringARB");
159 if(!_wglGetExtensionsStringARB){
160 fprintf(stderr,"could not get wglGetExtensionsStringARB\n");
161 return NULL;
162 }
163
164 if (!_wglGetExtensionsStringARB || strstr(_wglGetExtensionsStringARB(hdc), extension_name) == NULL)
165 {
166 fprintf(stderr,"extension %s was not found\n",extension_name);
167 // string was not found
168 return NULL;
169 }
170
171 // extension is supported
172 return wglGetProcAddress(proc_name);
173 }
174
dummyWndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)175 LRESULT CALLBACK dummyWndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
176 {
177 return DefWindowProc(hwnd, uMsg, wParam, lParam);
178 }
179
createDummyWindow()180 HWND createDummyWindow(){
181
182 WNDCLASSEX wcx;
183 wcx.cbSize = sizeof(wcx); // size of structure
184 wcx.style = CS_OWNDC |CS_HREDRAW |CS_VREDRAW; // redraw if size changes
185 wcx.lpfnWndProc = dummyWndProc; // points to window procedure
186 wcx.cbClsExtra = 0; // no extra class memory
187 wcx.cbWndExtra = sizeof(void*); // save extra window memory, to store VasWindow instance
188 wcx.hInstance = NULL; // handle to instance
189 wcx.hIcon = NULL; // predefined app. icon
190 wcx.hCursor = NULL;
191 wcx.hbrBackground = NULL; // no background brush
192 wcx.lpszMenuName = NULL; // name of menu resource
193 wcx.lpszClassName = "DummyWin"; // name of window class
194 wcx.hIconSm = (HICON) NULL; // small class icon
195
196 ATOM winClass = RegisterClassEx(&wcx);
197 HWND hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,
198 "DummyWin",
199 "Dummy",
200 WS_POPUP,
201 0,
202 0,
203 1,
204 1,
205 NULL,
206 NULL,
207 0,0);
208 return hwnd;
209 }
210
getDefaultDisplay()211 EGLNativeInternalDisplayType getDefaultDisplay() {
212 if (!s_tlsIndex) s_tlsIndex = TlsAlloc();
213 WinDisplay* dpy = new WinDisplay();
214
215 HWND hwnd = createDummyWindow();
216 HDC hdc = GetDC(hwnd);
217 dpy->setInfo(WinDisplay::DEFAULT_DISPLAY,DisplayInfo(hdc,hwnd));
218 return static_cast<EGLNativeInternalDisplayType>(dpy);
219 }
220
getInternalDisplay(EGLNativeDisplayType display)221 EGLNativeInternalDisplayType getInternalDisplay(EGLNativeDisplayType display){
222 if (!s_tlsIndex) s_tlsIndex = TlsAlloc();
223 WinDisplay* dpy = new WinDisplay();
224 dpy->setInfo(WinDisplay::DEFAULT_DISPLAY,DisplayInfo(display,NULL));
225 return dpy;
226 }
227
getDummyDC(EGLNativeInternalDisplayType display,int cfgId)228 static HDC getDummyDC(EGLNativeInternalDisplayType display,int cfgId){
229
230 HDC dpy = NULL;
231 if(!display->infoExists(cfgId)){
232 HWND hwnd = createDummyWindow();
233 dpy = GetDC(hwnd);
234 display->setInfo(cfgId,DisplayInfo(dpy,hwnd));
235 } else {
236 dpy = display->getDC(cfgId);
237 }
238 return dpy;
239 }
initPtrToWglFunctions()240 void initPtrToWglFunctions(){
241 HWND hwnd = createDummyWindow();
242 HDC dpy = GetDC(hwnd);
243 if(!hwnd || !dpy){
244 fprintf(stderr,"error while getting DC\n");
245 return;
246 }
247 EGLNativeContextType ctx = NULL;
248 PIXELFORMATDESCRIPTOR pfd = {
249 sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
250 1, // version number
251 PFD_DRAW_TO_WINDOW | // support window
252 PFD_SUPPORT_OPENGL | // support OpenGL
253 PFD_DOUBLEBUFFER, // double buffered
254 PFD_TYPE_RGBA, // RGBA type
255 24, // 24-bit color depth
256 0, 0, 0, 0, 0, 0, // color bits ignored
257 0, // no alpha buffer
258 0, // shift bit ignored
259 0, // no accumulation buffer
260 0, 0, 0, 0, // accum bits ignored
261 32, // 32-bit z-buffer
262 0, // no stencil buffer
263 0, // no auxiliary buffer
264 PFD_MAIN_PLANE, // main layer
265 0, // reserved
266 0, 0, 0 // layer masks ignored
267 };
268
269 int iPixelFormat,err;
270 iPixelFormat = ChoosePixelFormat(dpy, &pfd);
271 if(iPixelFormat < 0){
272 fprintf(stderr,"error while choosing pixel format\n");
273 return;
274 }
275 if(!SetPixelFormat(dpy,iPixelFormat,&pfd)){
276
277 int err = GetLastError();
278 fprintf(stderr,"error while setting pixel format 0x%x\n",err);
279 return;
280 }
281
282
283 ctx = wglCreateContext(dpy);
284 if(!ctx){
285 err = GetLastError();
286 fprintf(stderr,"error while creating dummy context %d\n",err);
287 }
288 if(!wglMakeCurrent(dpy,ctx)){
289 err = GetLastError();
290 fprintf(stderr,"error while making dummy context current %d\n",err);
291 }
292
293 if(!s_wglExtProcs){
294 s_wglExtProcs = new WglExtProcs();
295 s_wglExtProcs->wglGetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)wglGetExtentionsProcAddress(dpy,"WGL_ARB_pixel_format","wglGetPixelFormatAttribivARB");
296 s_wglExtProcs->wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetExtentionsProcAddress(dpy,"WGL_ARB_pixel_format","wglChoosePixelFormatARB");
297 s_wglExtProcs->wglCreatePbufferARB = (PFNWGLCREATEPBUFFERARBPROC)wglGetExtentionsProcAddress(dpy,"WGL_ARB_pbuffer","wglCreatePbufferARB");
298 s_wglExtProcs->wglReleasePbufferDCARB = (PFNWGLRELEASEPBUFFERDCARBPROC)wglGetExtentionsProcAddress(dpy,"WGL_ARB_pbuffer","wglReleasePbufferDCARB");
299 s_wglExtProcs->wglDestroyPbufferARB = (PFNWGLDESTROYPBUFFERARBPROC)wglGetExtentionsProcAddress(dpy,"WGL_ARB_pbuffer","wglDestroyPbufferARB");
300 s_wglExtProcs->wglGetPbufferDCARB = (PFNWGLGETPBUFFERDCARBPROC)wglGetExtentionsProcAddress(dpy,"WGL_ARB_pbuffer","wglGetPbufferDCARB");
301 s_wglExtProcs->wglMakeContextCurrentARB = (PFNWGLMAKECONTEXTCURRENTARBPROC)wglGetExtentionsProcAddress(dpy,"WGL_ARB_make_current_read","wglMakeContextCurrentARB");
302 s_wglExtProcs->wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetExtentionsProcAddress(dpy,"WGL_EXT_swap_control","wglSwapIntervalEXT");
303 }
304
305 wglMakeCurrent(dpy,NULL);
306 DestroyWindow(hwnd);
307 DeleteDC(dpy);
308 }
309
releaseDisplay(EGLNativeInternalDisplayType dpy)310 bool releaseDisplay(EGLNativeInternalDisplayType dpy) {
311 dpy->releaseAll();
312 return true;
313 }
314
deleteDisplay(EGLNativeInternalDisplayType idpy)315 void deleteDisplay(EGLNativeInternalDisplayType idpy){
316 if(idpy){
317 delete idpy;
318 }
319 }
320
321
initPixelFormat(HDC dc)322 static bool initPixelFormat(HDC dc){
323 PIXELFORMATDESCRIPTOR pfd;
324 unsigned int numpf;
325 int iPixelFormat;
326
327 if(s_wglExtProcs->wglChoosePixelFormatARB) {
328 int i0 = 0;
329 float f0 = 0.0f;
330 return s_wglExtProcs->wglChoosePixelFormatARB(dc,&i0, &f0, 1, &iPixelFormat, &numpf);
331 } else {
332 return ChoosePixelFormat(dc,&pfd);
333 }
334 }
335
pixelFormatToConfig(EGLNativeInternalDisplayType display,int renderableType,EGLNativePixelFormatType * frmt,int index)336 EglConfig* pixelFormatToConfig(EGLNativeInternalDisplayType display,int renderableType,EGLNativePixelFormatType* frmt,int index){
337
338 EGLint red,green,blue,alpha,depth,stencil;
339 EGLint supportedSurfaces,visualType,visualId;
340 EGLint transparentType,samples;
341 EGLint tRed,tGreen,tBlue;
342 EGLint pMaxWidth,pMaxHeight,pMaxPixels;
343 EGLint configId,level;
344 EGLint window,bitmap,pbuffer,transparent;
345 HDC dpy = getDummyDC(display,WinDisplay::DEFAULT_DISPLAY);
346
347 if(frmt->iPixelType != PFD_TYPE_RGBA) return NULL; // other formats are not supported yet
348 if(!((frmt->dwFlags & PFD_SUPPORT_OPENGL) && (frmt->dwFlags & PFD_DOUBLEBUFFER))) return NULL; //pixel format does not supports opengl or double buffer
349 if( 0 != (frmt->dwFlags & (PFD_GENERIC_FORMAT | PFD_NEED_PALETTE )) ) return NULL; //discard generic pixel formats as well as pallete pixel formats
350
351 int attribs [] = {
352 WGL_DRAW_TO_WINDOW_ARB,
353 WGL_DRAW_TO_BITMAP_ARB,
354 WGL_DRAW_TO_PBUFFER_ARB,
355 WGL_TRANSPARENT_ARB,
356 WGL_TRANSPARENT_RED_VALUE_ARB,
357 WGL_TRANSPARENT_GREEN_VALUE_ARB,
358 WGL_TRANSPARENT_BLUE_VALUE_ARB
359 };
360
361 supportedSurfaces = 0;
362 if(!s_wglExtProcs->wglGetPixelFormatAttribivARB) return NULL;
363
364 IS_TRUE(s_wglExtProcs->wglGetPixelFormatAttribivARB(dpy,index,0,1,&attribs[0],&window));
365 IS_TRUE(s_wglExtProcs->wglGetPixelFormatAttribivARB(dpy,index,0,1,&attribs[1],&bitmap));
366 IS_TRUE(s_wglExtProcs->wglGetPixelFormatAttribivARB(dpy,index,0,1,&attribs[2],&pbuffer));
367 if(window) supportedSurfaces |= EGL_WINDOW_BIT;
368 if(bitmap) supportedSurfaces |= EGL_PIXMAP_BIT;
369 if(pbuffer) supportedSurfaces |= EGL_PBUFFER_BIT;
370
371
372 if(!supportedSurfaces) return NULL;
373
374 //default values
375 visualId = 0;
376 visualType = EGL_NONE;
377 EGLenum caveat = EGL_NONE;
378 EGLBoolean renderable = EGL_FALSE;
379 pMaxWidth = PBUFFER_MAX_WIDTH;
380 pMaxHeight = PBUFFER_MAX_HEIGHT;
381 pMaxPixels = PBUFFER_MAX_PIXELS;
382 samples = 0 ;
383 level = 0 ;
384
385 IS_TRUE(s_wglExtProcs->wglGetPixelFormatAttribivARB(dpy,index,0,1,&attribs[3],&transparent));
386 if(transparent) {
387 transparentType = EGL_TRANSPARENT_RGB;
388 IS_TRUE(s_wglExtProcs->wglGetPixelFormatAttribivARB(dpy,index,0,1,&attribs[4],&tRed));
389 IS_TRUE(s_wglExtProcs->wglGetPixelFormatAttribivARB(dpy,index,0,1,&attribs[5],&tGreen));
390 IS_TRUE(s_wglExtProcs->wglGetPixelFormatAttribivARB(dpy,index,0,1,&attribs[6],&tBlue));
391 } else {
392 transparentType = EGL_NONE;
393 }
394
395 red = frmt->cRedBits;
396 green = frmt->cGreenBits;
397 blue = frmt->cBlueBits;
398 alpha = frmt->cAlphaBits;
399 depth = frmt->cDepthBits;
400 stencil = frmt->cStencilBits;
401 return new EglConfig(red,green,blue,alpha,caveat,(EGLint)index,depth,level,pMaxWidth,pMaxHeight,pMaxPixels,renderable,renderableType,
402 visualId,visualType,samples,stencil,supportedSurfaces,transparentType,tRed,tGreen,tBlue,*frmt);
403 }
404
405
queryConfigs(EGLNativeInternalDisplayType display,int renderableType,ConfigsList & listOut)406 void queryConfigs(EGLNativeInternalDisplayType display,int renderableType,ConfigsList& listOut) {
407 PIXELFORMATDESCRIPTOR pfd;
408 int iPixelFormat = 1;
409 HDC dpy = getDummyDC(display,WinDisplay::DEFAULT_DISPLAY);
410
411 //
412 // We need to call wglChoosePixelFormat at least once,
413 // seems that the driver needs to initialize itself.
414 // do it here during initialization.
415 //
416 initPixelFormat(dpy);
417
418 //quering num of formats
419 int nFormats = DescribePixelFormat(dpy, iPixelFormat,sizeof(PIXELFORMATDESCRIPTOR), &pfd);
420
421 //inserting rest of formats
422 for(iPixelFormat;iPixelFormat < nFormats; iPixelFormat++) {
423 DescribePixelFormat(dpy, iPixelFormat,sizeof(PIXELFORMATDESCRIPTOR), &pfd);
424 EglConfig* pConfig = pixelFormatToConfig(display,renderableType,&pfd,iPixelFormat);
425 if(pConfig) listOut.push_back(pConfig);
426 }
427 }
428
validNativeWin(EGLNativeInternalDisplayType dpy,EGLNativeWindowType win)429 bool validNativeWin(EGLNativeInternalDisplayType dpy,EGLNativeWindowType win) {
430 return IsWindow(win);
431 }
432
validNativeWin(EGLNativeInternalDisplayType dpy,EGLNativeSurfaceType win)433 bool validNativeWin(EGLNativeInternalDisplayType dpy,EGLNativeSurfaceType win) {
434 if (!win) return false;
435 return validNativeWin(dpy,win->getHwnd());
436 }
437
validNativePixmap(EGLNativeInternalDisplayType dpy,EGLNativeSurfaceType pix)438 bool validNativePixmap(EGLNativeInternalDisplayType dpy,EGLNativeSurfaceType pix) {
439 BITMAP bm;
440 if (!pix) return false;
441 return GetObject(pix->getBmap(), sizeof(BITMAP), (LPSTR)&bm);
442 }
443
checkWindowPixelFormatMatch(EGLNativeInternalDisplayType dpy,EGLNativeWindowType win,EglConfig * cfg,unsigned int * width,unsigned int * height)444 bool checkWindowPixelFormatMatch(EGLNativeInternalDisplayType dpy,EGLNativeWindowType win,EglConfig* cfg,unsigned int* width,unsigned int* height) {
445 RECT r;
446 if(!GetClientRect(win,&r)) return false;
447 *width = r.right - r.left;
448 *height = r.bottom - r.top;
449 HDC dc = GetDC(win);
450 EGLNativePixelFormatType nativeConfig = cfg->nativeConfig();
451 bool ret = SetPixelFormat(dc,cfg->nativeId(),&nativeConfig);
452 DeleteDC(dc);
453 return ret;
454 }
455
checkPixmapPixelFormatMatch(EGLNativeInternalDisplayType dpy,EGLNativePixmapType pix,EglConfig * cfg,unsigned int * width,unsigned int * height)456 bool checkPixmapPixelFormatMatch(EGLNativeInternalDisplayType dpy,EGLNativePixmapType pix,EglConfig* cfg,unsigned int* width,unsigned int* height){
457
458 BITMAP bm;
459 if(!GetObject(pix, sizeof(BITMAP), (LPSTR)&bm)) return false;
460
461 *width = bm.bmWidth;
462 *height = bm.bmHeight;
463
464 return true;
465 }
466
createPbufferSurface(EGLNativeInternalDisplayType display,EglConfig * cfg,EglPbufferSurface * pbSurface)467 EGLNativeSurfaceType createPbufferSurface(EGLNativeInternalDisplayType display,EglConfig* cfg,EglPbufferSurface* pbSurface) {
468
469
470 HDC dpy = getDummyDC(display,cfg->nativeId());
471 EGLint width,height,largest,texTarget,texFormat;
472 pbSurface->getDim(&width,&height,&largest);
473 pbSurface->getTexInfo(&texTarget,&texFormat);
474
475 int wglTexFormat = WGL_NO_TEXTURE_ARB;
476 int wglTexTarget = (texTarget == EGL_TEXTURE_2D)? WGL_TEXTURE_2D_ARB:
477 WGL_NO_TEXTURE_ARB;
478
479 switch(texFormat) {
480 case EGL_TEXTURE_RGB:
481 wglTexFormat = WGL_TEXTURE_RGB_ARB;
482 break;
483 case EGL_TEXTURE_RGBA:
484 wglTexFormat = WGL_TEXTURE_RGBA_ARB;
485 break;
486 }
487
488 int pbAttribs[] = {
489 WGL_TEXTURE_TARGET_ARB ,wglTexTarget,
490 WGL_TEXTURE_FORMAT_ARB ,wglTexFormat,
491 0
492 };
493 if(!s_wglExtProcs->wglCreatePbufferARB) return NULL;
494 EGLNativePbufferType pb = s_wglExtProcs->wglCreatePbufferARB(dpy,cfg->nativeId(),width,height,pbAttribs);
495 if(!pb) {
496 DWORD err = GetLastError();
497 return NULL;
498 }
499 return new SrfcInfo(pb);
500 }
501
releasePbuffer(EGLNativeInternalDisplayType display,EGLNativeSurfaceType pb)502 bool releasePbuffer(EGLNativeInternalDisplayType display,EGLNativeSurfaceType pb) {
503 if (!pb) return false;
504 if(!s_wglExtProcs->wglReleasePbufferDCARB || !s_wglExtProcs->wglDestroyPbufferARB) return false;
505 if(!s_wglExtProcs->wglReleasePbufferDCARB(pb->getPbuffer(),pb->getDC()) || !s_wglExtProcs->wglDestroyPbufferARB(pb->getPbuffer())){
506 DWORD err = GetLastError();
507 return false;
508 }
509 return true;
510 }
511
createContext(EGLNativeInternalDisplayType display,EglConfig * cfg,EGLNativeContextType sharedContext)512 EGLNativeContextType createContext(EGLNativeInternalDisplayType display,EglConfig* cfg,EGLNativeContextType sharedContext) {
513
514 EGLNativeContextType ctx = NULL;
515 HDC dpy = getDummyDC(display,cfg->nativeId());
516
517 if(!display->isPixelFormatSet(cfg->nativeId())){
518 EGLNativePixelFormatType nativeConfig = cfg->nativeConfig();
519 if(!SetPixelFormat(dpy,cfg->nativeId(),&nativeConfig)){
520 return NULL;
521 }
522 display->pixelFormatWasSet(cfg->nativeId());
523 }
524
525 ctx = wglCreateContext(dpy);
526
527 if(ctx && sharedContext) {
528 if(!wglShareLists(sharedContext,ctx)) {
529 wglDeleteContext(ctx);
530 return NULL;
531 }
532 }
533 return ctx;
534 }
535
destroyContext(EGLNativeInternalDisplayType dpy,EGLNativeContextType ctx)536 bool destroyContext(EGLNativeInternalDisplayType dpy,EGLNativeContextType ctx) {
537 if(!wglDeleteContext(ctx)) {
538 DWORD err = GetLastError();
539 return false;
540 }
541 return true;
542 }
543
544
makeCurrent(EGLNativeInternalDisplayType display,EglSurface * read,EglSurface * draw,EGLNativeContextType ctx)545 bool makeCurrent(EGLNativeInternalDisplayType display,EglSurface* read,EglSurface* draw,EGLNativeContextType ctx) {
546
547 HDC hdcRead = read ? read->native()->getDC(): NULL;
548 HDC hdcDraw = draw ? draw->native()->getDC(): NULL;
549 bool retVal = false;
550
551
552 if(hdcRead == hdcDraw){
553 bool ret = wglMakeCurrent(hdcDraw,ctx);
554 return ret;
555 } else if (!s_wglExtProcs->wglMakeContextCurrentARB ) {
556 return false;
557 }
558 retVal = s_wglExtProcs->wglMakeContextCurrentARB(hdcDraw,hdcRead,ctx);
559
560 return retVal;
561 }
562
swapBuffers(EGLNativeInternalDisplayType display,EGLNativeSurfaceType srfc)563 void swapBuffers(EGLNativeInternalDisplayType display,EGLNativeSurfaceType srfc){
564 if(srfc && !SwapBuffers(srfc->getDC())) {
565 DWORD err = GetLastError();
566 }
567 }
568
569
waitNative()570 void waitNative(){}
571
swapInterval(EGLNativeInternalDisplayType dpy,EGLNativeSurfaceType win,int interval)572 void swapInterval(EGLNativeInternalDisplayType dpy,EGLNativeSurfaceType win,int interval) {
573
574 if (s_wglExtProcs->wglSwapIntervalEXT){
575 s_wglExtProcs->wglSwapIntervalEXT(interval);
576 }
577 }
578
createWindowSurface(EGLNativeWindowType wnd)579 EGLNativeSurfaceType createWindowSurface(EGLNativeWindowType wnd){
580 return new SrfcInfo(wnd);
581 }
582
createPixmapSurface(EGLNativePixmapType pix)583 EGLNativeSurfaceType createPixmapSurface(EGLNativePixmapType pix){
584 return new SrfcInfo(pix);
585 }
586
destroySurface(EGLNativeSurfaceType srfc)587 void destroySurface(EGLNativeSurfaceType srfc){
588 delete srfc;
589 }
590
591
592 };
593