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