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{ 27 DisplayInfo():dc(NULL),hwnd(NULL),isPixelFormatSet(false){}; 28 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 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 }; 54 WinDisplay(){}; 55 DisplayInfo& getInfo(int configurationIndex){ return getTLS()->m_map[configurationIndex];} 56 HDC getDC(int configId){return getTLS()->m_map[configId].dc;} 57 void setInfo(int configurationIndex,const DisplayInfo& info); 58 bool isPixelFormatSet(int cfgId){ return getTLS()->m_map[cfgId].isPixelFormatSet;} 59 void pixelFormatWasSet(int cfgId){getTLS()->m_map[cfgId].isPixelFormatSet = true;} 60 bool infoExists(int configurationIndex); 61 void releaseAll(); 62 }; 63 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 75 bool WinDisplay::infoExists(int configurationIndex){ 76 return getTLS()->m_map.find(configurationIndex) != getTLS()->m_map.end(); 77 } 78 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); 106 HWND getHwnd(){ return m_hwnd;}; 107 HDC getDC(){ return m_hdc;}; 108 HBITMAP getBmap(){ return m_bmap;}; 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 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 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 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 142 SrfcInfo::~SrfcInfo(){ 143 if(m_type == WINDOW){ 144 ReleaseDC(m_hwnd,m_hdc); 145 } 146 } 147 148 namespace EglOS{ 149 150 151 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 175 LRESULT CALLBACK dummyWndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam) 176 { 177 return DefWindowProc(hwnd, uMsg, wParam, lParam); 178 } 179 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 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 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 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 } 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 310 bool releaseDisplay(EGLNativeInternalDisplayType dpy) { 311 dpy->releaseAll(); 312 return true; 313 } 314 315 void deleteDisplay(EGLNativeInternalDisplayType idpy){ 316 if(idpy){ 317 delete idpy; 318 } 319 } 320 321 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 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 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 429 bool validNativeWin(EGLNativeInternalDisplayType dpy,EGLNativeWindowType win) { 430 return IsWindow(win); 431 } 432 433 bool validNativeWin(EGLNativeInternalDisplayType dpy,EGLNativeSurfaceType win) { 434 if (!win) return false; 435 return validNativeWin(dpy,win->getHwnd()); 436 } 437 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 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 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 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 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 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 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 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 563 void swapBuffers(EGLNativeInternalDisplayType display,EGLNativeSurfaceType srfc){ 564 if(srfc && !SwapBuffers(srfc->getDC())) { 565 DWORD err = GetLastError(); 566 } 567 } 568 569 570 void waitNative(){} 571 572 void swapInterval(EGLNativeInternalDisplayType dpy,EGLNativeSurfaceType win,int interval) { 573 574 if (s_wglExtProcs->wglSwapIntervalEXT){ 575 s_wglExtProcs->wglSwapIntervalEXT(interval); 576 } 577 } 578 579 EGLNativeSurfaceType createWindowSurface(EGLNativeWindowType wnd){ 580 return new SrfcInfo(wnd); 581 } 582 583 EGLNativeSurfaceType createPixmapSurface(EGLNativePixmapType pix){ 584 return new SrfcInfo(pix); 585 } 586 587 void destroySurface(EGLNativeSurfaceType srfc){ 588 delete srfc; 589 } 590 591 592 }; 593