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