• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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