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{ 26 DisplayInfo():dc(NULL),hwnd(NULL),isPixelFormatSet(false){}; 27 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 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 }; 51 WinDisplay(){}; 52 DisplayInfo& getInfo(int configurationIndex){ return getTLS()->m_map[configurationIndex];} 53 HDC getDC(int configId){return getTLS()->m_map[configId].dc;} 54 void setInfo(int configurationIndex,const DisplayInfo& info); 55 bool isPixelFormatSet(int cfgId){ return getTLS()->m_map[cfgId].isPixelFormatSet;} 56 void pixelFormatWasSet(int cfgId){getTLS()->m_map[cfgId].isPixelFormatSet = true;} 57 bool infoExists(int configurationIndex); 58 void releaseAll(); 59 }; 60 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 72 bool WinDisplay::infoExists(int configurationIndex){ 73 return getTLS()->m_map.find(configurationIndex) != getTLS()->m_map.end(); 74 } 75 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); 103 HWND getHwnd(){ return m_hwnd;}; 104 HDC getDC(){ return m_hdc;}; 105 HBITMAP getBmap(){ return m_bmap;}; 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 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 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 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 139 SrfcInfo::~SrfcInfo(){ 140 if(m_type == WINDOW){ 141 ReleaseDC(m_hwnd,m_hdc); 142 } 143 } 144 145 namespace EglOS{ 146 147 148 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 172 LRESULT CALLBACK dummyWndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam) 173 { 174 return DefWindowProc(hwnd, uMsg, wParam, lParam); 175 } 176 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 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 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 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 } 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 308 bool releaseDisplay(EGLNativeInternalDisplayType dpy) { 309 dpy->releaseAll(); 310 return true; 311 } 312 313 void deleteDisplay(EGLNativeInternalDisplayType idpy){ 314 if(idpy){ 315 delete idpy; 316 } 317 } 318 319 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 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 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 427 bool validNativeDisplay(EGLNativeInternalDisplayType dpy) { 428 return dpy != NULL; 429 } 430 431 bool validNativeWin(EGLNativeInternalDisplayType dpy,EGLNativeWindowType win) { 432 return IsWindow(win); 433 } 434 435 bool validNativeWin(EGLNativeInternalDisplayType dpy,EGLNativeSurfaceType win) { 436 if (!win) return false; 437 return validNativeWin(dpy,win->getHwnd()); 438 } 439 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 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 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 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 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 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 538 bool destroyContext(EGLNativeInternalDisplayType dpy,EGLNativeContextType ctx) { 539 if(!wglDeleteContext(ctx)) { 540 GetLastError(); 541 return false; 542 } 543 return true; 544 } 545 546 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 565 void swapBuffers(EGLNativeInternalDisplayType display,EGLNativeSurfaceType srfc){ 566 if(srfc && !SwapBuffers(srfc->getDC())) { 567 GetLastError(); 568 } 569 } 570 571 572 void waitNative(){} 573 574 void swapInterval(EGLNativeInternalDisplayType dpy,EGLNativeSurfaceType win,int interval) { 575 576 if (s_wglExtProcs->wglSwapIntervalEXT){ 577 s_wglExtProcs->wglSwapIntervalEXT(interval); 578 } 579 } 580 581 EGLNativeSurfaceType createWindowSurface(EGLNativeWindowType wnd){ 582 return new SrfcInfo(wnd); 583 } 584 585 EGLNativeSurfaceType createPixmapSurface(EGLNativePixmapType pix){ 586 return new SrfcInfo(pix); 587 } 588 589 void destroySurface(EGLNativeSurfaceType srfc){ 590 delete srfc; 591 } 592 593 594 }; 595