indirect.c revision 475c125c
1/* 2 * File: indirect.c 3 * Purpose: A GLX implementation that uses Windows OpenGL library 4 * 5 * Authors: Alexander Gottwald 6 * Jon TURNEY 7 * 8 * Copyright (c) Jon TURNEY 2009 9 * Copyright (c) Alexander Gottwald 2004 10 * 11 * Portions of this file are copied from GL/apple/indirect.c, 12 * which contains the following copyright: 13 * 14 * Copyright (c) 2007, 2008, 2009 Apple Inc. 15 * Copyright (c) 2004 Torrey T. Lyons. All Rights Reserved. 16 * Copyright (c) 2002 Greg Parker. All Rights Reserved. 17 * 18 * Portions of this file are copied from Mesa's xf86glx.c, 19 * which contains the following copyright: 20 * 21 * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 22 * All Rights Reserved. 23 * 24 * 25 * Permission is hereby granted, free of charge, to any person obtaining a 26 * copy of this software and associated documentation files (the "Software"), 27 * to deal in the Software without restriction, including without limitation 28 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 29 * and/or sell copies of the Software, and to permit persons to whom the 30 * Software is furnished to do so, subject to the following conditions: 31 * 32 * The above copyright notice and this permission notice shall be included in 33 * all copies or substantial portions of the Software. 34 * 35 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 36 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 37 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 38 * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 39 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 40 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 41 * DEALINGS IN THE SOFTWARE. 42 */ 43 44/* 45 TODO: 46 - hook up remaining unimplemented extensions 47 - research what guarantees glXWaitX, glXWaitGL are supposed to offer, and implement then 48 using GdiFlush and/or glFinish 49 - pbuffer clobbering: we don't get async notification, but can we arrange to emit the 50 event when we notice it's been clobbered? at the very least, check if it's been clobbered 51 before using it? 52 - are the __GLXConfig * we get handed back ones we are made (so we can extend the structure 53 with privates?) Or are they created inside the GLX core as well? 54*/ 55 56/* 57 MSDN clarifications: 58 59 It says SetPixelFormat()'s PIXELFORMATDESCRIPTOR pointer argument has no effect 60 except on metafiles, this seems to mean that as it's ok to supply NULL if the DC 61 is not for a metafile 62 63 wglMakeCurrent ignores the hdc if hglrc is NULL, so wglMakeCurrent(NULL, NULL) 64 is used to make no context current 65 66*/ 67 68#ifdef HAVE_XWIN_CONFIG_H 69#include <xwin-config.h> 70#endif 71 72#include "glwindows.h" 73#include <glx/glxserver.h> 74#include <glx/glxutil.h> 75#include <glx/extension_string.h> 76#include <GL/glxtokens.h> 77 78#include <winpriv.h> 79#include <wgl_ext_api.h> 80 81#define NUM_ELEMENTS(x) (sizeof(x)/ sizeof(x[1])) 82 83/* ---------------------------------------------------------------------- */ 84/* 85 * structure definitions 86 */ 87 88typedef struct __GLXWinContext __GLXWinContext; 89typedef struct __GLXWinDrawable __GLXWinDrawable; 90typedef struct __GLXWinScreen glxWinScreen; 91typedef struct __GLXWinConfig GLXWinConfig; 92 93struct __GLXWinContext { 94 __GLXcontext base; 95 HGLRC ctx; /* Windows GL Context */ 96 __GLXWinContext *shareContext; /* Context with which we will share display lists and textures */ 97 HWND hwnd; /* For detecting when HWND has changed */ 98}; 99 100struct __GLXWinDrawable 101{ 102 __GLXdrawable base; 103 __GLXWinContext *drawContext; 104 __GLXWinContext *readContext; 105 106 /* If this drawable is GLX_DRAWABLE_PBUFFER */ 107 HPBUFFERARB hPbuffer; 108 109 /* If this drawable is GLX_DRAWABLE_PIXMAP */ 110 HDC dibDC; 111 HBITMAP hDIB; 112 HBITMAP hOldDIB; /* original DIB for DC */ 113 void *pOldBits; /* original pBits for this drawable's pixmap */ 114}; 115 116struct __GLXWinScreen 117{ 118 __GLXscreen base; 119 120 /* Supported GLX extensions */ 121 unsigned char glx_enable_bits[__GLX_EXT_BYTES]; 122 123 Bool has_WGL_ARB_multisample; 124 Bool has_WGL_ARB_pixel_format; 125 Bool has_WGL_ARB_pbuffer; 126 Bool has_WGL_ARB_render_texture; 127 128 /* wrapped screen functions */ 129 RealizeWindowProcPtr RealizeWindow; 130 UnrealizeWindowProcPtr UnrealizeWindow; 131 CopyWindowProcPtr CopyWindow; 132}; 133 134struct __GLXWinConfig 135{ 136 __GLXconfig base; 137 int pixelFormatIndex; 138}; 139 140/* ---------------------------------------------------------------------- */ 141/* 142 * Various debug helpers 143 */ 144 145#define GLWIN_DEBUG_HWND(hwnd) \ 146 if (glxWinDebugSettings.dumpHWND) { \ 147 char buffer[1024]; \ 148 if (GetWindowText(hwnd, buffer, sizeof(buffer))==0) *buffer=0; \ 149 GLWIN_DEBUG_MSG("Got HWND %p for window '%s'", hwnd, buffer); \ 150 } 151 152glxWinDebugSettingsRec glxWinDebugSettings = { 0, 0, 0, 0, 0, 0}; 153 154static void glxWinInitDebugSettings(void) 155{ 156 char *envptr; 157 158 envptr = getenv("GLWIN_ENABLE_DEBUG"); 159 if (envptr != NULL) 160 glxWinDebugSettings.enableDebug = (atoi(envptr) == 1); 161 162 envptr = getenv("GLWIN_ENABLE_TRACE"); 163 if (envptr != NULL) 164 glxWinDebugSettings.enableTrace = (atoi(envptr) == 1); 165 166 envptr = getenv("GLWIN_DUMP_PFD"); 167 if (envptr != NULL) 168 glxWinDebugSettings.dumpPFD = (atoi(envptr) == 1); 169 170 envptr = getenv("GLWIN_DUMP_HWND"); 171 if (envptr != NULL) 172 glxWinDebugSettings.dumpHWND = (atoi(envptr) == 1); 173 174 envptr = getenv("GLWIN_DUMP_DC"); 175 if (envptr != NULL) 176 glxWinDebugSettings.dumpDC = (atoi(envptr) == 1); 177 178 envptr = getenv("GLWIN_ENABLE_GLCALL_TRACE"); 179 if (envptr != NULL) 180 glxWinDebugSettings.enableGLcallTrace = (atoi(envptr) == 1); 181 182 envptr = getenv("GLWIN_ENABLE_WGLCALL_TRACE"); 183 if (envptr != NULL) 184 glxWinDebugSettings.enableWGLcallTrace = (atoi(envptr) == 1); 185 186 envptr = getenv("GLWIN_DEBUG_ALL"); 187 if (envptr != NULL) 188 { 189 glxWinDebugSettings.enableDebug = 1; 190 glxWinDebugSettings.enableTrace = 1; 191 glxWinDebugSettings.dumpPFD = 1; 192 glxWinDebugSettings.dumpHWND = 1; 193 glxWinDebugSettings.dumpDC = 1; 194 glxWinDebugSettings.enableGLcallTrace = 1; 195 glxWinDebugSettings.enableWGLcallTrace = 1; 196 } 197} 198 199static 200const char *glxWinErrorMessage(void) 201{ 202 static char errorbuffer[1024]; 203 204 if (!FormatMessage( 205 FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 206 NULL, 207 GetLastError(), 208 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 209 (LPTSTR) &errorbuffer, 210 sizeof(errorbuffer), 211 NULL )) 212 { 213 snprintf(errorbuffer, sizeof(errorbuffer), "Unknown error in FormatMessage: %08x!", (unsigned)GetLastError()); 214 } 215 216 if (errorbuffer[strlen(errorbuffer)-1] == '\n') 217 errorbuffer[strlen(errorbuffer)-1] = 0; 218 219 return errorbuffer; 220} 221 222static void pfdOut(const PIXELFORMATDESCRIPTOR *pfd); 223 224#define DUMP_PFD_FLAG(flag) \ 225 if (pfd->dwFlags & flag) { \ 226 ErrorF("%s%s", pipesym, #flag); \ 227 pipesym = " | "; \ 228 } 229 230static void pfdOut(const PIXELFORMATDESCRIPTOR *pfd) 231{ 232 const char *pipesym = ""; /* will be set after first flag dump */ 233 ErrorF("PIXELFORMATDESCRIPTOR:\n"); 234 ErrorF("nSize = %u\n", pfd->nSize); 235 ErrorF("nVersion = %u\n", pfd->nVersion); 236 ErrorF("dwFlags = %lu = {", pfd->dwFlags); 237 DUMP_PFD_FLAG(PFD_DOUBLEBUFFER); 238 DUMP_PFD_FLAG(PFD_STEREO); 239 DUMP_PFD_FLAG(PFD_DRAW_TO_WINDOW); 240 DUMP_PFD_FLAG(PFD_DRAW_TO_BITMAP); 241 DUMP_PFD_FLAG(PFD_SUPPORT_GDI); 242 DUMP_PFD_FLAG(PFD_SUPPORT_OPENGL); 243 DUMP_PFD_FLAG(PFD_GENERIC_FORMAT); 244 DUMP_PFD_FLAG(PFD_NEED_PALETTE); 245 DUMP_PFD_FLAG(PFD_NEED_SYSTEM_PALETTE); 246 DUMP_PFD_FLAG(PFD_SWAP_EXCHANGE); 247 DUMP_PFD_FLAG(PFD_SWAP_COPY); 248 DUMP_PFD_FLAG(PFD_SWAP_LAYER_BUFFERS); 249 DUMP_PFD_FLAG(PFD_GENERIC_ACCELERATED); 250 DUMP_PFD_FLAG(PFD_DEPTH_DONTCARE); 251 DUMP_PFD_FLAG(PFD_DOUBLEBUFFER_DONTCARE); 252 DUMP_PFD_FLAG(PFD_STEREO_DONTCARE); 253 ErrorF("}\n"); 254 255 ErrorF("iPixelType = %hu = %s\n", pfd->iPixelType, 256 (pfd->iPixelType == PFD_TYPE_RGBA ? "PFD_TYPE_RGBA" : "PFD_TYPE_COLORINDEX")); 257 ErrorF("cColorBits = %hhu\n", pfd->cColorBits); 258 ErrorF("cRedBits = %hhu\n", pfd->cRedBits); 259 ErrorF("cRedShift = %hhu\n", pfd->cRedShift); 260 ErrorF("cGreenBits = %hhu\n", pfd->cGreenBits); 261 ErrorF("cGreenShift = %hhu\n", pfd->cGreenShift); 262 ErrorF("cBlueBits = %hhu\n", pfd->cBlueBits); 263 ErrorF("cBlueShift = %hhu\n", pfd->cBlueShift); 264 ErrorF("cAlphaBits = %hhu\n", pfd->cAlphaBits); 265 ErrorF("cAlphaShift = %hhu\n", pfd->cAlphaShift); 266 ErrorF("cAccumBits = %hhu\n", pfd->cAccumBits); 267 ErrorF("cAccumRedBits = %hhu\n", pfd->cAccumRedBits); 268 ErrorF("cAccumGreenBits = %hhu\n", pfd->cAccumGreenBits); 269 ErrorF("cAccumBlueBits = %hhu\n", pfd->cAccumBlueBits); 270 ErrorF("cAccumAlphaBits = %hhu\n", pfd->cAccumAlphaBits); 271 ErrorF("cDepthBits = %hhu\n", pfd->cDepthBits); 272 ErrorF("cStencilBits = %hhu\n", pfd->cStencilBits); 273 ErrorF("cAuxBuffers = %hhu\n", pfd->cAuxBuffers); 274 ErrorF("iLayerType = %hhu\n", pfd->iLayerType); 275 ErrorF("bReserved = %hhu\n", pfd->bReserved); 276 ErrorF("dwLayerMask = %lu\n", pfd->dwLayerMask); 277 ErrorF("dwVisibleMask = %lu\n", pfd->dwVisibleMask); 278 ErrorF("dwDamageMask = %lu\n", pfd->dwDamageMask); 279 ErrorF("\n"); 280} 281 282static const char * 283visual_class_name(int cls) 284{ 285 switch (cls) { 286 case GLX_STATIC_COLOR: 287 return "StaticColor"; 288 case GLX_PSEUDO_COLOR: 289 return "PseudoColor"; 290 case GLX_STATIC_GRAY: 291 return "StaticGray"; 292 case GLX_GRAY_SCALE: 293 return "GrayScale"; 294 case GLX_TRUE_COLOR: 295 return "TrueColor"; 296 case GLX_DIRECT_COLOR: 297 return "DirectColor"; 298 default: 299 return "-none-"; 300 } 301} 302 303static const char * 304swap_method_name(int mthd) 305{ 306 switch (mthd) 307 { 308 case GLX_SWAP_EXCHANGE_OML: 309 return "xchg"; 310 case GLX_SWAP_COPY_OML: 311 return "copy"; 312 case GLX_SWAP_UNDEFINED_OML: 313 return " "; 314 default: 315 return "????"; 316 } 317} 318 319static void 320fbConfigsDump(unsigned int n, __GLXconfig *c) 321{ 322 ErrorF("%d fbConfigs\n", n); 323 ErrorF("pxf vis fb render Ste aux accum MS drawable Group/\n"); 324 ErrorF("idx ID ID VisualType Depth Lvl RGB CI DB Swap reo R G B A Z S buf AR AG AB AA bufs num W P Pb Float Trans Caveat\n"); 325 ErrorF("-----------------------------------------------------------------------------------------------------------------------------\n"); 326 327 while (c != NULL) 328 { 329 unsigned int i = ((GLXWinConfig *)c)->pixelFormatIndex; 330 331 ErrorF("%3d %2x %2x " 332 "%-11s" 333 " %3d %3d %s %s %s %s %s " 334 "%2d %2d %2d %2d " 335 "%2d %2d " 336 "%2d " 337 "%2d %2d %2d %2d" 338 " %2d %2d" 339 " %s %s %s " 340 " %s " 341 " %s " 342 " %d %s" 343 "\n", 344 i, c->visualID, c->fbconfigID, 345 visual_class_name(c->visualType), 346 c->rgbBits ? c->rgbBits : c->indexBits, 347 c->level, 348 (c->renderType & GLX_RGBA_BIT) ? "y" : ".", 349 (c->renderType & GLX_COLOR_INDEX_BIT) ? "y" : ".", 350 c->doubleBufferMode ? "y" : ".", 351 swap_method_name(c->swapMethod), 352 c->stereoMode ? "y" : ".", 353 c->redBits, c->greenBits, c->blueBits, c->alphaBits, 354 c->depthBits, c->stencilBits, 355 c->numAuxBuffers, 356 c->accumRedBits, c->accumGreenBits, c->accumBlueBits, c->accumAlphaBits, 357 c->sampleBuffers, c->samples, 358 (c->drawableType & GLX_WINDOW_BIT) ? "y" : ".", 359 (c->drawableType & GLX_PIXMAP_BIT) ? "y" : ".", 360 (c->drawableType & GLX_PBUFFER_BIT) ? "y" : ".", 361 ".", 362 (c->transparentPixel != GLX_NONE_EXT) ? "y" : ".", 363 c->visualSelectGroup, (c->visualRating == GLX_SLOW_VISUAL_EXT) ? "*" : " "); 364 365 c = c->next; 366 } 367} 368 369/* ---------------------------------------------------------------------- */ 370/* 371 * Forward declarations 372 */ 373 374static __GLXscreen *glxWinScreenProbe(ScreenPtr pScreen); 375static __GLXcontext *glxWinCreateContext(__GLXscreen *screen, 376 __GLXconfig *modes, 377 __GLXcontext *baseShareContext); 378static __GLXdrawable *glxWinCreateDrawable(ClientPtr client, 379 __GLXscreen *screen, 380 DrawablePtr pDraw, 381 XID drawId, 382 int type, 383 XID glxDrawId, 384 __GLXconfig *conf); 385 386static Bool glxWinRealizeWindow(WindowPtr pWin); 387static Bool glxWinUnrealizeWindow(WindowPtr pWin); 388static void glxWinCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc); 389 390static HDC glxWinMakeDC(__GLXWinContext *gc, __GLXWinDrawable *draw, HDC *hdc, HWND *hwnd); 391static void glxWinReleaseDC(HWND hwnd, HDC hdc, __GLXWinDrawable *draw); 392 393static void glxWinCreateConfigs(HDC dc, glxWinScreen *screen); 394static void glxWinCreateConfigsExt(HDC hdc, glxWinScreen *screen); 395static int fbConfigToPixelFormat(__GLXconfig *mode, PIXELFORMATDESCRIPTOR *pfdret, int drawableTypeOverride); 396static int fbConfigToPixelFormatIndex(HDC hdc, __GLXconfig *mode, int drawableTypeOverride, glxWinScreen *winScreen); 397 398/* ---------------------------------------------------------------------- */ 399/* 400 * The GLX provider 401 */ 402 403__GLXprovider __glXWGLProvider = { 404 glxWinScreenProbe, 405 "Win32 native WGL", 406 NULL 407}; 408 409void 410glxWinPushNativeProvider(void) 411{ 412 GlxPushProvider(&__glXWGLProvider); 413} 414 415/* ---------------------------------------------------------------------- */ 416/* 417 * Screen functions 418 */ 419 420static void 421glxWinScreenDestroy(__GLXscreen *screen) 422{ 423 GLWIN_DEBUG_MSG("glxWinScreenDestroy(%p)", screen); 424 __glXScreenDestroy(screen); 425 free(screen); 426} 427 428static int 429glxWinScreenSwapInterval(__GLXdrawable *drawable, int interval) 430{ 431 BOOL ret = wglSwapIntervalEXTWrapper(interval); 432 if (!ret) 433 { 434 ErrorF("wglSwapIntervalEXT interval %d failed:%s\n", interval, glxWinErrorMessage()); 435 } 436 return ret; 437} 438 439/* 440 Report the extensions split and formatted to avoid overflowing a line 441 */ 442static void 443glxLogExtensions(const char *prefix, const char *extensions) 444{ 445 int length = 0; 446 char *strl; 447 char *str = strdup(extensions); 448 449 if (str == NULL) 450 { 451 ErrorF("glxLogExtensions: xalloc error\n"); 452 return; 453 } 454 455 strl = strtok(str, " "); 456 ErrorF("%s%s", prefix, strl); 457 length = strlen(prefix) + strlen(strl); 458 459 while (1) 460 { 461 strl = strtok(NULL, " "); 462 if (strl == NULL) break; 463 464 if (length + strlen(strl) + 1 > 120) 465 { 466 ErrorF("\n"); 467 ErrorF("%s",prefix); 468 length = strlen(prefix); 469 } 470 else 471 { 472 ErrorF(" "); 473 length++; 474 } 475 476 ErrorF("%s", strl); 477 length = length + strlen(strl); 478 } 479 480 ErrorF("\n"); 481 482 free(str); 483} 484 485/* This is called by GlxExtensionInit() asking the GLX provider if it can handle the screen... */ 486static __GLXscreen * 487glxWinScreenProbe(ScreenPtr pScreen) 488{ 489 glxWinScreen *screen; 490 const char *gl_extensions; 491 const char *wgl_extensions; 492 HWND hwnd; 493 HDC hdc; 494 HGLRC hglrc; 495 496 GLWIN_DEBUG_MSG("glxWinScreenProbe"); 497 498 glxWinInitDebugSettings(); 499 500 if (pScreen == NULL) 501 return NULL; 502 503 if (!winCheckScreenAiglxIsSupported(pScreen)) 504 { 505 LogMessage(X_ERROR,"AIGLX: No native OpenGL in modes with a root window\n"); 506 return NULL; 507 } 508 509 screen = calloc(1, sizeof(glxWinScreen)); 510 511 if (NULL == screen) 512 return NULL; 513 514 /* Wrap RealizeWindow, UnrealizeWindow and CopyWindow on this screen */ 515 screen->RealizeWindow = pScreen->RealizeWindow; 516 pScreen->RealizeWindow = glxWinRealizeWindow; 517 screen->UnrealizeWindow = pScreen->UnrealizeWindow; 518 pScreen->UnrealizeWindow = glxWinUnrealizeWindow; 519 screen->CopyWindow = pScreen->CopyWindow; 520 pScreen->CopyWindow = glxWinCopyWindow; 521 522 /* Dump out some useful information about the native renderer */ 523 524 // create window class 525#define WIN_GL_TEST_WINDOW_CLASS "XWinGLTest" 526 { 527 static wATOM glTestWndClass = 0; 528 if (glTestWndClass == 0) 529 { 530 WNDCLASSEX wc; 531 wc.cbSize = sizeof(WNDCLASSEX); 532 wc.style = CS_HREDRAW | CS_VREDRAW; 533 wc.lpfnWndProc = DefWindowProc; 534 wc.cbClsExtra = 0; 535 wc.cbWndExtra = 0; 536 wc.hInstance = GetModuleHandle(NULL); 537 wc.hIcon = 0; 538 wc.hCursor = 0; 539 wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 540 wc.lpszMenuName = NULL; 541 wc.lpszClassName = WIN_GL_TEST_WINDOW_CLASS; 542 wc.hIconSm = 0; 543 RegisterClassEx (&wc); 544 } 545 } 546 547 // create an invisible window for a scratch DC 548 hwnd = CreateWindowExA(0, 549 WIN_GL_TEST_WINDOW_CLASS, 550 "XWin GL Renderer Capabilities Test Window", 551 0, 0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL); 552 if (hwnd == NULL) 553 LogMessage(X_ERROR,"AIGLX: Couldn't create a window for render capabilities testing\n"); 554 555 hdc = GetDC(hwnd); 556 557 // we must set a pixel format before we can create a context, just use the first one... 558 SetPixelFormat(hdc, 1, NULL); 559 hglrc = wglCreateContext(hdc); 560 wglMakeCurrent(hdc, hglrc); 561 562 // initialize wgl extension proc pointers (don't call them before here...) 563 // (but we need to have a current context for them to be resolvable) 564 wglResolveExtensionProcs(); 565 566 ErrorF("GL_VERSION: %s\n", glGetStringWrapperNonstatic(GL_VERSION)); 567 ErrorF("GL_VENDOR: %s\n", glGetStringWrapperNonstatic(GL_VENDOR)); 568 ErrorF("GL_RENDERER: %s\n", glGetStringWrapperNonstatic(GL_RENDERER)); 569 gl_extensions = (const char *)glGetStringWrapperNonstatic(GL_EXTENSIONS); 570 glxLogExtensions("GL_EXTENSIONS: ", gl_extensions); 571 wgl_extensions = wglGetExtensionsStringARBWrapper(hdc); 572 if (!wgl_extensions) wgl_extensions = ""; 573 glxLogExtensions("WGL_EXTENSIONS: ", wgl_extensions); 574 575 // Can you see the problem here? The extensions string is DC specific 576 // Different DCs for windows on a multimonitor system driven by multiple cards 577 // might have completely different capabilities. Of course, good luck getting 578 // those screens to be accelerated in XP and earlier... 579 580 { 581 // testing facility to not use any WGL extensions 582 char *envptr = getenv("GLWIN_NO_WGL_EXTENSIONS"); 583 if ((envptr != NULL) && (atoi(envptr) != 0)) 584 { 585 ErrorF("GLWIN_NO_WGL_EXTENSIONS is set, ignoring WGL_EXTENSIONS\n"); 586 wgl_extensions = ""; 587 } 588 } 589 590 { 591 Bool glx_sgi_make_current_read = FALSE; 592 593 // 594 // Based on the WGL extensions available, enable various GLX extensions 595 // XXX: make this table-driven ? 596 // 597 memset(screen->glx_enable_bits, 0, __GLX_EXT_BYTES); 598 599 __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_visual_info"); 600 __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_visual_rating"); 601 __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_import_context"); 602 __glXEnableExtension(screen->glx_enable_bits, "GLX_OML_swap_method"); 603 __glXEnableExtension(screen->glx_enable_bits, "GLX_SGIX_fbconfig"); 604 605 if (strstr(wgl_extensions, "WGL_ARB_make_current_read")) 606 { 607 __glXEnableExtension(screen->glx_enable_bits, "GLX_SGI_make_current_read"); 608 LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_make_current_read\n"); 609 glx_sgi_make_current_read = TRUE; 610 } 611 612 if (strstr(gl_extensions, "GL_WIN_swap_hint")) 613 { 614 __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_copy_sub_buffer"); 615 LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n"); 616 } 617 618 if (strstr(wgl_extensions, "WGL_EXT_swap_control")) 619 { 620 __glXEnableExtension(screen->glx_enable_bits, "GLX_SGI_swap_control"); 621 __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_swap_control"); 622 LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_swap_control and GLX_MESA_swap_control\n"); 623 } 624 625/* // Hmm? screen->texOffset */ 626/* if (strstr(wgl_extensions, "WGL_ARB_render_texture")) */ 627/* { */ 628/* __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_texture_from_pixmap"); */ 629/* LogMessage(X_INFO, "AIGLX: GLX_EXT_texture_from_pixmap backed by buffer objects\n"); */ 630/* screen->has_WGL_ARB_render_texture = TRUE; */ 631/* } */ 632 633 if (strstr(wgl_extensions, "WGL_ARB_pbuffer")) 634 { 635 __glXEnableExtension(screen->glx_enable_bits, "GLX_SGIX_pbuffer"); 636 LogMessage(X_INFO, "AIGLX: enabled GLX_SGIX_pbuffer\n"); 637 screen->has_WGL_ARB_pbuffer = TRUE; 638 } 639 640 if (strstr(wgl_extensions, "WGL_ARB_multisample")) 641 { 642 __glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_multisample"); 643 __glXEnableExtension(screen->glx_enable_bits, "GLX_SGIS_multisample"); 644 LogMessage(X_INFO, "AIGLX: enabled GLX_ARB_multisample and GLX_SGIS_multisample\n"); 645 screen->has_WGL_ARB_multisample = TRUE; 646 } 647 648 screen->base.destroy = glxWinScreenDestroy; 649 screen->base.createContext = glxWinCreateContext; 650 screen->base.createDrawable = glxWinCreateDrawable; 651 screen->base.swapInterval = glxWinScreenSwapInterval; 652 screen->base.pScreen = pScreen; 653 654 if (strstr(wgl_extensions, "WGL_ARB_pixel_format")) 655 { 656 glxWinCreateConfigsExt(hdc, screen); 657 screen->has_WGL_ARB_pixel_format = TRUE; 658 } 659 else 660 { 661 glxWinCreateConfigs(hdc, screen); 662 screen->has_WGL_ARB_pixel_format = FALSE; 663 } 664 // Initializes screen->base.fbconfigs and screen->base.numFBConfigs 665 666 /* These will be set by __glXScreenInit */ 667 screen->base.visuals = NULL; 668 screen->base.numVisuals = 0; 669 670 __glXScreenInit(&screen->base, pScreen); 671 672 // dump out fbConfigs now fbConfigIds and visualIDs have been assigned 673 fbConfigsDump(screen->base.numFBConfigs, screen->base.fbconfigs); 674 675 // Override the GL extensions string set by __glXScreenInit() 676 screen->base.GLextensions = strdup(gl_extensions); 677 678 // Generate the GLX extensions string (overrides that set by __glXScreenInit()) 679 { 680 unsigned int buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL); 681 if (buffer_size > 0) 682 { 683 free(screen->base.GLXextensions); 684 685 screen->base.GLXextensions = xnfalloc(buffer_size); 686 __glXGetExtensionString(screen->glx_enable_bits, screen->base.GLXextensions); 687 } 688 } 689 690 // 691 // Override the GLX version (__glXScreenInit() sets it to "1.2") 692 // if we have all the needed extensions to operate as a higher version 693 // 694 // SGIX_fbconfig && SGIX_pbuffer && SGI_make_current_read -> 1.3 695 // ARB_multisample -> 1.4 696 // 697 if (screen->has_WGL_ARB_pbuffer && glx_sgi_make_current_read) 698 { 699 if (screen->has_WGL_ARB_multisample) 700 { 701 screen->base.GLXmajor = 1; 702 screen->base.GLXminor = 4; 703 } 704 else 705 { 706 screen->base.GLXmajor = 1; 707 screen->base.GLXminor = 3; 708 } 709 } 710 } 711 LogMessage(X_INFO, "AIGLX: Set GLX version to %d.%d\n", screen->base.GLXmajor, screen->base.GLXminor); 712 713 wglMakeCurrent(NULL, NULL); 714 wglDeleteContext(hglrc); 715 ReleaseDC(hwnd, hdc); 716 DestroyWindow(hwnd); 717 718 return &screen->base; 719} 720 721/* ---------------------------------------------------------------------- */ 722/* 723 * Window functions 724 */ 725 726static Bool 727glxWinRealizeWindow(WindowPtr pWin) 728{ 729 Bool result; 730 ScreenPtr pScreen = pWin->drawable.pScreen; 731 glxWinScreen *screenPriv = (glxWinScreen *) glxGetScreen(pScreen); 732 733 GLWIN_DEBUG_MSG("glxWinRealizeWindow"); 734 735 /* Allow the window to be created (RootlessRealizeWindow is inside our wrap) */ 736 pScreen->RealizeWindow = screenPriv->RealizeWindow; 737 result = pScreen->RealizeWindow(pWin); 738 pScreen->RealizeWindow = glxWinRealizeWindow; 739 740 return result; 741} 742 743 744static void 745glxWinCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc) 746{ 747 __GLXWinDrawable *pGlxDraw; 748 ScreenPtr pScreen = pWindow->drawable.pScreen; 749 glxWinScreen *screenPriv = (glxWinScreen *) glxGetScreen(pScreen); 750 751 GLWIN_TRACE_MSG("glxWinCopyWindow pWindow %p", pWindow); 752 753 dixLookupResourceByType((pointer) &pGlxDraw, pWindow->drawable.id, __glXDrawableRes, 754 NullClient, DixUnknownAccess); 755 756 757 /* 758 Discard any CopyWindow requests if a GL drawing context is pointing at the window 759 760 For regions which are being drawn by GL, the shadow framebuffer doesn't have the 761 correct bits, so we wish to avoid shadow framebuffer damage occuring, which will 762 cause those incorrect bits to be transferred to the display.... 763 */ 764 if (pGlxDraw && pGlxDraw->drawContext) 765 { 766 GLWIN_DEBUG_MSG("glxWinCopyWindow: discarding"); 767 return; 768 } 769 770 GLWIN_DEBUG_MSG("glxWinCopyWindow - passing to hw layer"); 771 772 pScreen->CopyWindow = screenPriv->CopyWindow; 773 pScreen->CopyWindow(pWindow, ptOldOrg, prgnSrc); 774 pScreen->CopyWindow = glxWinCopyWindow; 775} 776 777static Bool 778glxWinUnrealizeWindow(WindowPtr pWin) 779{ 780 Bool result; 781 ScreenPtr pScreen = pWin->drawable.pScreen; 782 glxWinScreen *screenPriv = (glxWinScreen *)glxGetScreen(pScreen); 783 784 GLWIN_DEBUG_MSG("glxWinUnrealizeWindow"); 785 786 pScreen->UnrealizeWindow = screenPriv->UnrealizeWindow; 787 result = pScreen->UnrealizeWindow(pWin); 788 pScreen->UnrealizeWindow = glxWinUnrealizeWindow; 789 790 return result; 791} 792 793/* ---------------------------------------------------------------------- */ 794/* 795 * Drawable functions 796 */ 797 798static GLboolean 799glxWinDrawableSwapBuffers(ClientPtr client, __GLXdrawable *base) 800{ 801 HDC dc; 802 HWND hwnd; 803 BOOL ret; 804 __GLXWinDrawable *draw = (__GLXWinDrawable *)base; 805 806 /* Swap buffers on the last active context for drawing on the drawable */ 807 if (draw->drawContext == NULL) 808 { 809 GLWIN_TRACE_MSG("glxWinSwapBuffers - no context for drawable"); 810 return GL_FALSE; 811 } 812 813 GLWIN_TRACE_MSG("glxWinSwapBuffers on drawable %p, last context %p (native ctx %p)", base, draw->drawContext, draw->drawContext->ctx); 814 815 /* 816 draw->drawContext->base.drawPriv will not be set if the context is not current anymore, 817 but if it is, it should point to this drawable.... 818 */ 819 assert((draw->drawContext->base.drawPriv == NULL) || (draw->drawContext->base.drawPriv == base)); 820 821 dc = glxWinMakeDC(draw->drawContext, draw, &dc, &hwnd); 822 if (dc == NULL) 823 return GL_FALSE; 824 825 ret = wglSwapLayerBuffers(dc, WGL_SWAP_MAIN_PLANE); 826 827 glxWinReleaseDC(hwnd, dc, draw); 828 829 if (!ret) 830 { 831 ErrorF("wglSwapBuffers failed: %s\n", glxWinErrorMessage()); 832 return GL_FALSE; 833 } 834 835 return GL_TRUE; 836} 837 838static void 839glxWinDrawableCopySubBuffer(__GLXdrawable *drawable, 840 int x, int y, int w, int h) 841{ 842 glAddSwapHintRectWINWrapperNonstatic(x, y, w, h); 843 glxWinDrawableSwapBuffers(NULL, drawable); 844} 845 846static void 847glxWinDrawableDestroy(__GLXdrawable *base) 848{ 849 __GLXWinDrawable *glxPriv = (__GLXWinDrawable *)base; 850 851 if (glxPriv->drawContext && (__glXLastContext == &((glxPriv->drawContext)->base))) 852 { 853 // if this context is current and has unflushed commands, say we have flushed them 854 // (don't actually flush them, the window is going away anyhow, and an implict flush occurs 855 // on the next context change) 856 // (GLX core considers it an error when we try to select a new current context if the old one 857 // has unflushed commands, but the window has disappeared..) 858 __GLX_NOTE_FLUSHED_CMDS(__glXLastContext); 859 __glXLastContext = NULL; 860 } 861 862 if (glxPriv->hPbuffer) 863 if (!wglDestroyPbufferARBWrapper(glxPriv->hPbuffer)) 864 { 865 ErrorF("wglDestroyPbufferARB failed: %s\n", glxWinErrorMessage()); 866 } 867 868 if (glxPriv->dibDC) 869 { 870 // restore the default DIB 871 SelectObject(glxPriv->dibDC, glxPriv->hOldDIB); 872 873 if (!DeleteDC(glxPriv->dibDC)) 874 { 875 ErrorF("DeleteDC failed: %s\n", glxWinErrorMessage()); 876 } 877 } 878 879 if (glxPriv->hDIB) 880 { 881 if (!DeleteObject(glxPriv->hDIB)) 882 { 883 ErrorF("DeleteObject failed: %s\n", glxWinErrorMessage()); 884 } 885 886 ((PixmapPtr)glxPriv->base.pDraw)->devPrivate.ptr = glxPriv->pOldBits; 887 } 888 889 GLWIN_DEBUG_MSG("glxWinDestroyDrawable"); 890 free(glxPriv); 891} 892 893static __GLXdrawable * 894glxWinCreateDrawable(ClientPtr client, 895 __GLXscreen *screen, 896 DrawablePtr pDraw, 897 XID drawId, 898 int type, 899 XID glxDrawId, 900 __GLXconfig *conf) 901{ 902 __GLXWinDrawable *glxPriv; 903 904 glxPriv = malloc(sizeof *glxPriv); 905 906 if (glxPriv == NULL) 907 return NULL; 908 909 memset(glxPriv, 0, sizeof *glxPriv); 910 911 if(!__glXDrawableInit(&glxPriv->base, screen, pDraw, type, glxDrawId, conf)) { 912 free(glxPriv); 913 return NULL; 914 } 915 916 glxPriv->base.destroy = glxWinDrawableDestroy; 917 glxPriv->base.swapBuffers = glxWinDrawableSwapBuffers; 918 glxPriv->base.copySubBuffer = glxWinDrawableCopySubBuffer; 919 // glxPriv->base.waitX what are these for? 920 // glxPriv->base.waitGL 921 922 GLWIN_DEBUG_MSG("glxWinCreateDrawable %p", glxPriv); 923 924 return &glxPriv->base; 925} 926 927/* ---------------------------------------------------------------------- */ 928/* 929 * Texture functions 930 */ 931 932static 933int glxWinBindTexImage(__GLXcontext *baseContext, 934 int buffer, 935 __GLXdrawable *pixmap) 936{ 937 ErrorF("glxWinBindTexImage: not implemented\n"); 938 return FALSE; 939} 940 941static 942int glxWinReleaseTexImage(__GLXcontext *baseContext, 943 int buffer, 944 __GLXdrawable *pixmap) 945{ 946 ErrorF(" glxWinReleaseTexImage: not implemented\n"); 947 return FALSE; 948} 949 950/* ---------------------------------------------------------------------- */ 951/* 952 * Lazy update context implementation 953 * 954 * WGL contexts are created for a specific HDC, so we cannot create the WGL 955 * context in glxWinCreateContext(), we must defer creation until the context 956 * is actually used on a specifc drawable which is connected to a native window, 957 * pbuffer or DIB 958 * 959 * The WGL context may be used on other, compatible HDCs, so we don't need to 960 * recreate it for every new native window 961 * 962 * XXX: I wonder why we can't create the WGL context on the screen HDC ? 963 * Basically we assume all HDCs are compatible at the moment: if they are not 964 * we are in a muddle, there was some code in the old implementation to attempt 965 * to transparently migrate a context to a new DC by copying state and sharing 966 * lists with the old one... 967 */ 968 969static void 970glxWinSetPixelFormat(__GLXWinContext *gc, HDC hdc, int bppOverride, int drawableTypeOverride) 971{ 972 __GLXscreen *screen = gc->base.pGlxScreen; 973 glxWinScreen *winScreen = (glxWinScreen *)screen; 974 975 __GLXconfig *config = gc->base.config; 976 GLXWinConfig *winConfig = (GLXWinConfig *)config; 977 978 GLWIN_DEBUG_MSG("glxWinSetPixelFormat: pixelFormatIndex %d", winConfig->pixelFormatIndex); 979 980 /* 981 Normally, we can just use the the pixelFormatIndex corresponding 982 to the fbconfig which has been specified by the client 983 */ 984 985 if (!((bppOverride && (bppOverride != (config->redBits + config->greenBits + config->blueBits) )) 986 || ((config->drawableType & drawableTypeOverride) == 0))) 987 { 988 if (!SetPixelFormat(hdc, winConfig->pixelFormatIndex, NULL)) 989 { 990 ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage()); 991 return; 992 } 993 994 return; 995 } 996 997 /* 998 However, in certain special cases this pixel format will be incompatible with the 999 use we are going to put it to, so we need to re-evaluate the pixel format to use: 1000 1001 1) When PFD_DRAW_TO_BITMAP is set, ChoosePixelFormat() always returns a format with 1002 the cColorBits we asked for, so we need to ensure it matches the bpp of the bitmap 1003 1004 2) Applications may assume that visuals selected with glXChooseVisual() work with 1005 pixmap drawables (there is no attribute to explicitly query for pixmap drawable 1006 support as there is for glXChooseFBConfig()) 1007 (it's arguable this is an error in the application, but we try to make it work) 1008 1009 pixmap rendering is always slow for us, so we don't want to choose those visuals 1010 by default, but if the actual drawable type we're trying to select the context 1011 on (drawableTypeOverride) isn't supported by the selected fbConfig, reconsider 1012 and see if we can find a suitable one... 1013 */ 1014 ErrorF("glxWinSetPixelFormat: having second thoughts: cColorbits %d, bppOveride %d; config->drawableType %d, drawableTypeOverride %d\n", 1015 (config->redBits + config->greenBits + config->blueBits), bppOverride, config->drawableType, drawableTypeOverride); 1016 1017 if (!winScreen->has_WGL_ARB_pixel_format) 1018 { 1019 PIXELFORMATDESCRIPTOR pfd; 1020 int pixelFormat; 1021 1022 /* convert fbConfig to PFD */ 1023 if (fbConfigToPixelFormat(gc->base.config, &pfd, drawableTypeOverride)) 1024 { 1025 ErrorF("glxWinSetPixelFormat: fbConfigToPixelFormat failed\n"); 1026 return; 1027 } 1028 1029 if (glxWinDebugSettings.dumpPFD) 1030 pfdOut(&pfd); 1031 1032 if (bppOverride) 1033 { 1034 GLWIN_DEBUG_MSG("glxWinSetPixelFormat: Forcing bpp from %d to %d\n", pfd.cColorBits, bppOverride); 1035 pfd.cColorBits = bppOverride; 1036 } 1037 1038 pixelFormat = ChoosePixelFormat(hdc, &pfd); 1039 if (pixelFormat == 0) 1040 { 1041 ErrorF("ChoosePixelFormat error: %s\n", glxWinErrorMessage()); 1042 return; 1043 } 1044 1045 GLWIN_DEBUG_MSG("ChoosePixelFormat: chose pixelFormatIndex %d", pixelFormat); 1046 ErrorF("ChoosePixelFormat: chose pixelFormatIndex %d (rather than %d as originally planned)\n", pixelFormat, winConfig->pixelFormatIndex); 1047 1048 if (!SetPixelFormat(hdc, pixelFormat, &pfd)) 1049 { 1050 ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage()); 1051 return; 1052 } 1053 } 1054 else 1055 { 1056 int pixelFormat = fbConfigToPixelFormatIndex(hdc, gc->base.config, drawableTypeOverride, winScreen); 1057 if (pixelFormat == 0) 1058 { 1059 ErrorF("wglChoosePixelFormat error: %s\n", glxWinErrorMessage()); 1060 return; 1061 } 1062 1063 GLWIN_DEBUG_MSG("wglChoosePixelFormat: chose pixelFormatIndex %d", pixelFormat); 1064 ErrorF("wglChoosePixelFormat: chose pixelFormatIndex %d (rather than %d as originally planned)\n", pixelFormat, winConfig->pixelFormatIndex); 1065 1066 if (!SetPixelFormat(hdc, pixelFormat, NULL)) 1067 { 1068 ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage()); 1069 return; 1070 } 1071 } 1072} 1073 1074static HDC 1075glxWinMakeDC(__GLXWinContext *gc, __GLXWinDrawable *draw, HDC *hdc, HWND *hwnd) 1076{ 1077 *hdc = NULL; 1078 *hwnd = NULL; 1079 1080 if (draw == NULL) 1081 { 1082 GLWIN_TRACE_MSG("No drawable for context %p (native ctx %p)", gc, gc->ctx); 1083 return NULL; 1084 } 1085 1086 switch (draw->base.type) 1087 { 1088 case GLX_DRAWABLE_WINDOW: 1089 { 1090 WindowPtr pWin; 1091 1092 pWin = (WindowPtr) draw->base.pDraw; 1093 if (pWin == NULL) 1094 { 1095 GLWIN_TRACE_MSG("for drawable %p, no WindowPtr", pWin); 1096 return NULL; 1097 } 1098 1099 *hwnd = winGetWindowInfo(pWin); 1100 1101 if (*hwnd == NULL) 1102 { 1103 ErrorF("No HWND error: %s\n", glxWinErrorMessage()); 1104 return NULL; 1105 } 1106 1107 *hdc = GetDC(*hwnd); 1108 1109 if (*hdc == NULL) 1110 ErrorF("GetDC error: %s\n", glxWinErrorMessage()); 1111 1112 /* Check if the hwnd has changed... */ 1113 if (*hwnd != gc->hwnd) 1114 { 1115 if (glxWinDebugSettings.enableTrace) 1116 GLWIN_DEBUG_HWND(*hwnd); 1117 1118 GLWIN_TRACE_MSG("for context %p (native ctx %p), hWnd changed from %p to %p", gc, gc->ctx, gc->hwnd, *hwnd); 1119 gc->hwnd = *hwnd; 1120 1121 /* We must select a pixelformat, but SetPixelFormat can only be called once for a window... */ 1122 glxWinSetPixelFormat(gc, *hdc, 0, GLX_WINDOW_BIT); 1123 } 1124 } 1125 break; 1126 1127 case GLX_DRAWABLE_PBUFFER: 1128 { 1129 *hdc = wglGetPbufferDCARBWrapper(draw->hPbuffer); 1130 1131 if (*hdc == NULL) 1132 ErrorF("GetDC (pbuffer) error: %s\n", glxWinErrorMessage()); 1133 } 1134 break; 1135 1136 case GLX_DRAWABLE_PIXMAP: 1137 { 1138 *hdc = draw->dibDC; 1139 } 1140 break; 1141 1142 default: 1143 { 1144 ErrorF("glxWinMakeDC: tried to makeDC for unhandled drawable type %d\n", draw->base.type); 1145 } 1146 } 1147 1148 if (glxWinDebugSettings.dumpDC) 1149 GLWIN_DEBUG_MSG("Got HDC %p", *hdc); 1150 1151 return *hdc; 1152} 1153 1154static void 1155glxWinReleaseDC(HWND hwnd, HDC hdc,__GLXWinDrawable *draw) 1156{ 1157 switch (draw->base.type) 1158 { 1159 case GLX_DRAWABLE_WINDOW: 1160 { 1161 ReleaseDC(hwnd, hdc); 1162 } 1163 break; 1164 1165 case GLX_DRAWABLE_PBUFFER: 1166 { 1167 if (!wglReleasePbufferDCARBWrapper(draw->hPbuffer, hdc)) 1168 { 1169 ErrorF("wglReleasePbufferDCARB error: %s\n", glxWinErrorMessage()); 1170 } 1171 } 1172 break; 1173 1174 case GLX_DRAWABLE_PIXMAP: 1175 { 1176 // don't release DC, the memory DC lives as long as the bitmap 1177 1178 // We must ensure that all GDI drawing into the bitmap has completed 1179 // in case we subsequently access the bits from it 1180 GdiFlush(); 1181 } 1182 break; 1183 1184 default: 1185 { 1186 ErrorF("glxWinReleaseDC: tried to releaseDC for unhandled drawable type %d\n", draw->base.type); 1187 } 1188 } 1189} 1190 1191static void 1192glxWinDeferredCreateContext(__GLXWinContext *gc, __GLXWinDrawable *draw) 1193{ 1194 HDC dc; 1195 HWND hwnd; 1196 GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: attach context %p to drawable %p", gc, draw); 1197 1198 switch (draw->base.type) 1199 { 1200 case GLX_DRAWABLE_WINDOW: 1201 { 1202 WindowPtr pWin = (WindowPtr) draw->base.pDraw; 1203 1204 if (!(gc->base.config->drawableType & GLX_WINDOW_BIT)) 1205 { 1206 ErrorF("glxWinDeferredCreateContext: tried to attach a context whose fbConfig doesn't have drawableType GLX_WINDOW_BIT to a GLX_DRAWABLE_WINDOW drawable\n"); 1207 } 1208 1209 if (pWin == NULL) 1210 { 1211 GLWIN_DEBUG_MSG("Deferring until X window is created"); 1212 return; 1213 } 1214 1215 GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: pWin %p", pWin); 1216 1217 if (winGetWindowInfo(pWin) == NULL) 1218 { 1219 GLWIN_DEBUG_MSG("Deferring until native window is created"); 1220 return; 1221 } 1222 } 1223 break; 1224 1225 case GLX_DRAWABLE_PBUFFER: 1226 { 1227 if (draw->hPbuffer == NULL) 1228 { 1229 __GLXscreen *screen; 1230 glxWinScreen *winScreen; 1231 int pixelFormat; 1232 // XXX: which DC are supposed to use??? 1233 HDC screenDC = GetDC(NULL); 1234 1235 if (!(gc->base.config->drawableType & GLX_PBUFFER_BIT)) 1236 { 1237 ErrorF("glxWinDeferredCreateContext: tried to attach a context whose fbConfig doesn't have drawableType GLX_PBUFFER_BIT to a GLX_DRAWABLE_PBUFFER drawable\n"); 1238 } 1239 1240 screen = gc->base.pGlxScreen; 1241 winScreen = (glxWinScreen *)screen; 1242 1243 pixelFormat = fbConfigToPixelFormatIndex(screenDC, gc->base.config, GLX_DRAWABLE_PBUFFER, winScreen); 1244 if (pixelFormat == 0) 1245 { 1246 ErrorF("wglChoosePixelFormat error: %s\n", glxWinErrorMessage()); 1247 return; 1248 } 1249 1250 draw->hPbuffer = wglCreatePbufferARBWrapper(screenDC, pixelFormat, draw->base.pDraw->width, draw->base.pDraw->height, NULL); 1251 ReleaseDC(NULL, screenDC); 1252 1253 if (draw->hPbuffer == NULL) 1254 { 1255 ErrorF("wglCreatePbufferARBWrapper error: %s\n", glxWinErrorMessage()); 1256 return; 1257 } 1258 1259 GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: pBuffer %p created for drawable %p", draw->hPbuffer, draw); 1260 } 1261 } 1262 break; 1263 1264 case GLX_DRAWABLE_PIXMAP: 1265 { 1266 if (draw->dibDC == NULL) 1267 { 1268 BITMAPINFOHEADER bmpHeader; 1269 void *pBits; 1270 1271 memset (&bmpHeader, 0, sizeof(BITMAPINFOHEADER)); 1272 bmpHeader.biSize = sizeof(BITMAPINFOHEADER); 1273 bmpHeader.biWidth = draw->base.pDraw->width; 1274 bmpHeader.biHeight = draw->base.pDraw->height; 1275 bmpHeader.biPlanes = 1; 1276 bmpHeader.biBitCount = draw->base.pDraw->bitsPerPixel; 1277 bmpHeader.biCompression = BI_RGB; 1278 1279 if (!(gc->base.config->drawableType & GLX_PIXMAP_BIT)) 1280 { 1281 ErrorF("glxWinDeferredCreateContext: tried to attach a context whose fbConfig doesn't have drawableType GLX_PIXMAP_BIT to a GLX_DRAWABLE_PIXMAP drawable\n"); 1282 } 1283 1284 draw->dibDC = CreateCompatibleDC(NULL); 1285 if (draw->dibDC == NULL) 1286 { 1287 ErrorF("CreateCompatibleDC error: %s\n", glxWinErrorMessage()); 1288 return; 1289 } 1290 1291 draw->hDIB = CreateDIBSection(draw->dibDC, (BITMAPINFO *)&bmpHeader, DIB_RGB_COLORS, &pBits, 0, 0); 1292 if (draw->dibDC == NULL) 1293 { 1294 ErrorF("CreateDIBSection error: %s\n", glxWinErrorMessage()); 1295 return; 1296 } 1297 1298 // XXX: CreateDIBSection insists on allocating the bitmap memory for us, so we're going to 1299 // need some jiggery pokery to point the underlying X Drawable's bitmap at the same set of bits 1300 // so that they can be read with XGetImage as well as glReadPixels, assuming the formats are 1301 // even compatible ... 1302 draw->pOldBits = ((PixmapPtr)draw->base.pDraw)->devPrivate.ptr; 1303 ((PixmapPtr)draw->base.pDraw)->devPrivate.ptr = pBits; 1304 1305 // Select the DIB into the DC 1306 draw->hOldDIB = SelectObject(draw->dibDC, draw->hDIB); 1307 if (!draw->hOldDIB) 1308 { 1309 ErrorF("SelectObject error: %s\n", glxWinErrorMessage()); 1310 } 1311 1312 // Set the pixel format of the bitmap 1313 glxWinSetPixelFormat(gc, draw->dibDC, draw->base.pDraw->bitsPerPixel, GLX_PIXMAP_BIT); 1314 1315 GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: DIB bitmap %p created for drawable %p", draw->hDIB, draw); 1316 } 1317 } 1318 break; 1319 1320 default: 1321 { 1322 ErrorF("glxWinDeferredCreateContext: tried to attach unhandled drawable type %d\n", draw->base.type); 1323 return; 1324 } 1325 } 1326 1327 dc = glxWinMakeDC(gc, draw, &dc, &hwnd); 1328 gc->ctx = wglCreateContext(dc); 1329 glxWinReleaseDC(hwnd, dc, draw); 1330 1331 if (gc->ctx == NULL) 1332 { 1333 ErrorF("wglCreateContext error: %s\n", glxWinErrorMessage()); 1334 return; 1335 } 1336 1337 GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: attached context %p to native context %p drawable %p", gc, gc->ctx, draw); 1338 1339 // if the native context was created successfully, shareLists if needed 1340 if (gc->ctx && gc->shareContext) 1341 { 1342 GLWIN_DEBUG_MSG("glxWinCreateContextReal shareLists with context %p (native ctx %p)", gc->shareContext, gc->shareContext->ctx); 1343 1344 if (!wglShareLists(gc->shareContext->ctx, gc->ctx)) 1345 { 1346 ErrorF("wglShareLists error: %s\n", glxWinErrorMessage()); 1347 } 1348 } 1349} 1350 1351/* ---------------------------------------------------------------------- */ 1352/* 1353 * Context functions 1354 */ 1355 1356 1357/* Context manipulation routines should return TRUE on success, FALSE on failure */ 1358static int 1359glxWinContextMakeCurrent(__GLXcontext *base) 1360{ 1361 __GLXWinContext *gc = (__GLXWinContext *)base; 1362 BOOL ret; 1363 HDC drawDC; 1364 HDC readDC = NULL; 1365 __GLXdrawable *drawPriv; 1366 __GLXdrawable *readPriv = NULL; 1367 HWND hDrawWnd; 1368 HWND hReadWnd; 1369 1370 GLWIN_TRACE_MSG("glxWinContextMakeCurrent context %p (native ctx %p)", gc, gc->ctx); 1371 glWinCallDelta(); 1372 1373 /* Keep a note of the last active context in the drawable */ 1374 drawPriv = gc->base.drawPriv; 1375 ((__GLXWinDrawable *)drawPriv)->drawContext = gc; 1376 1377 if (gc->ctx == NULL) 1378 { 1379 glxWinDeferredCreateContext(gc, (__GLXWinDrawable *)drawPriv); 1380 } 1381 1382 if (gc->ctx == NULL) 1383 { 1384 ErrorF("glxWinContextMakeCurrent: Native context is NULL\n"); 1385 return FALSE; 1386 } 1387 1388 drawDC = glxWinMakeDC(gc, (__GLXWinDrawable *)drawPriv, &drawDC, &hDrawWnd); 1389 if (drawDC == NULL) 1390 { 1391 ErrorF("glxWinMakeDC failed for drawDC\n"); 1392 return FALSE; 1393 } 1394 1395 if ((gc->base.readPriv != NULL) && (gc->base.readPriv != gc->base.drawPriv)) 1396 { 1397 // XXX: should only occur with WGL_ARB_make_current_read 1398 /* 1399 If there is a separate read drawable, create a separate read DC, and 1400 use the wglMakeContextCurrent extension to make the context current drawing 1401 to one DC and reading from the other 1402 */ 1403 readPriv = gc->base.readPriv; 1404 readDC = glxWinMakeDC(gc, (__GLXWinDrawable *)readPriv, &readDC, &hReadWnd); 1405 if (readDC == NULL) 1406 { 1407 ErrorF("glxWinMakeDC failed for readDC\n"); 1408 glxWinReleaseDC(hDrawWnd, drawDC, (__GLXWinDrawable *)drawPriv); 1409 return FALSE; 1410 } 1411 1412 ret = wglMakeContextCurrentARBWrapper(drawDC, readDC, gc->ctx); 1413 if (!ret) 1414 { 1415 ErrorF("wglMakeContextCurrentARBWrapper error: %s\n", glxWinErrorMessage()); 1416 } 1417 } 1418 else 1419 { 1420 /* Otherwise, just use wglMakeCurrent */ 1421 ret = wglMakeCurrent(drawDC, gc->ctx); 1422 if (!ret) 1423 { 1424 ErrorF("wglMakeCurrent error: %s\n", glxWinErrorMessage()); 1425 } 1426 } 1427 1428 // apparently make current could fail if the context is current in a different thread, 1429 // but that shouldn't be able to happen in the current server... 1430 1431 glxWinReleaseDC(hDrawWnd, drawDC, (__GLXWinDrawable *)drawPriv); 1432 if (readDC) 1433 glxWinReleaseDC(hReadWnd, readDC, (__GLXWinDrawable *)readPriv); 1434 1435 return ret; 1436} 1437 1438static int 1439glxWinContextLoseCurrent(__GLXcontext *base) 1440{ 1441 BOOL ret; 1442 __GLXWinContext *gc = (__GLXWinContext *)base; 1443 1444 GLWIN_TRACE_MSG("glxWinContextLoseCurrent context %p (native ctx %p)", gc, gc->ctx); 1445 glWinCallDelta(); 1446 1447 /* 1448 An error seems to be reported if we try to make no context current 1449 if there is already no current context, so avoid doing that... 1450 */ 1451 if (__glXLastContext != NULL) 1452 { 1453 ret = wglMakeCurrent(NULL, NULL); /* We don't need a DC when setting no current context */ 1454 if (!ret) 1455 ErrorF("glxWinContextLoseCurrent error: %s\n", glxWinErrorMessage()); 1456 } 1457 1458 return TRUE; 1459} 1460 1461static int 1462glxWinContextCopy(__GLXcontext *dst_base, __GLXcontext *src_base, unsigned long mask) 1463{ 1464 __GLXWinContext *dst = (__GLXWinContext *)dst_base; 1465 __GLXWinContext *src = (__GLXWinContext *)src_base; 1466 BOOL ret; 1467 1468 GLWIN_DEBUG_MSG("glxWinContextCopy"); 1469 1470 ret = wglCopyContext(src->ctx, dst->ctx, mask); 1471 if (!ret) 1472 { 1473 ErrorF("wglCopyContext error: %s\n", glxWinErrorMessage()); 1474 } 1475 1476 return ret; 1477} 1478 1479static int 1480glxWinContextForceCurrent(__GLXcontext *base) 1481{ 1482 /* wglMakeCurrent always flushes the previous context, so this is equivalent to glxWinContextMakeCurrent */ 1483 return glxWinContextMakeCurrent(base); 1484} 1485 1486static void 1487glxWinContextDestroy(__GLXcontext *base) 1488{ 1489 __GLXWinContext *gc = (__GLXWinContext *)base; 1490 1491 if (gc != NULL) 1492 { 1493 GLWIN_DEBUG_MSG("GLXcontext %p destroyed (native ctx %p)", base, gc->ctx); 1494 1495 if (gc->ctx) 1496 { 1497 /* It's bad style to delete the context while it's still current */ 1498 if (wglGetCurrentContext() == gc->ctx) 1499 { 1500 wglMakeCurrent(NULL, NULL); 1501 } 1502 1503 { 1504 BOOL ret = wglDeleteContext(gc->ctx); 1505 if (!ret) 1506 ErrorF("wglDeleteContext error: %s\n", glxWinErrorMessage()); 1507 } 1508 1509 gc->ctx = NULL; 1510 } 1511 1512 free(gc); 1513 } 1514} 1515 1516static __GLXcontext * 1517glxWinCreateContext(__GLXscreen *screen, 1518 __GLXconfig *modes, 1519 __GLXcontext *baseShareContext) 1520{ 1521 __GLXWinContext *context; 1522 __GLXWinContext *shareContext = (__GLXWinContext *)baseShareContext; 1523 1524 static __GLXtextureFromPixmap glxWinTextureFromPixmap = 1525 { 1526 glxWinBindTexImage, 1527 glxWinReleaseTexImage 1528 }; 1529 1530 context = (__GLXWinContext *)calloc(1, sizeof(__GLXWinContext)); 1531 1532 if (!context) 1533 return NULL; 1534 1535 memset(context, 0, sizeof *context); 1536 context->base.destroy = glxWinContextDestroy; 1537 context->base.makeCurrent = glxWinContextMakeCurrent; 1538 context->base.loseCurrent = glxWinContextLoseCurrent; 1539 context->base.copy = glxWinContextCopy; 1540 context->base.forceCurrent = glxWinContextForceCurrent; 1541 context->base.textureFromPixmap = &glxWinTextureFromPixmap; 1542 context->base.config = modes; 1543 context->base.pGlxScreen = screen; 1544 1545 // actual native GL context creation is deferred until attach() 1546 context->ctx = NULL; 1547 context->shareContext = shareContext; 1548 1549 glWinSetupDispatchTable(); 1550 1551 GLWIN_DEBUG_MSG("GLXcontext %p created", context); 1552 1553 return &(context->base); 1554} 1555 1556/* ---------------------------------------------------------------------- */ 1557/* 1558 * Utility functions 1559 */ 1560 1561static int 1562fbConfigToPixelFormat(__GLXconfig *mode, PIXELFORMATDESCRIPTOR *pfdret, int drawableTypeOverride) 1563{ 1564 PIXELFORMATDESCRIPTOR pfd = { 1565 sizeof(PIXELFORMATDESCRIPTOR), /* size of this pfd */ 1566 1, /* version number */ 1567 PFD_SUPPORT_OPENGL, /* support OpenGL */ 1568 PFD_TYPE_RGBA, /* RGBA type */ 1569 24, /* 24-bit color depth */ 1570 0, 0, 0, 0, 0, 0, /* color bits ignored */ 1571 0, /* no alpha buffer */ 1572 0, /* shift bit ignored */ 1573 0, /* no accumulation buffer */ 1574 0, 0, 0, 0, /* accum bits ignored */ 1575 32, /* 32-bit z-buffer */ 1576 0, /* no stencil buffer */ 1577 0, /* no auxiliary buffer */ 1578 PFD_MAIN_PLANE, /* main layer */ 1579 0, /* reserved */ 1580 0, 0, 0 /* layer masks ignored */ 1581 }; 1582 1583 if ((mode->drawableType | drawableTypeOverride) & GLX_WINDOW_BIT) 1584 pfd.dwFlags |= PFD_DRAW_TO_WINDOW; /* support window */ 1585 1586 if ((mode->drawableType | drawableTypeOverride) & GLX_PIXMAP_BIT) 1587 pfd.dwFlags |= (PFD_DRAW_TO_BITMAP | PFD_SUPPORT_GDI); /* supports software rendering to bitmap */ 1588 1589 if (mode->stereoMode) { 1590 pfd.dwFlags |= PFD_STEREO; 1591 } 1592 if (mode->doubleBufferMode) { 1593 pfd.dwFlags |= PFD_DOUBLEBUFFER; 1594 } 1595 1596 pfd.iPixelType = PFD_TYPE_RGBA; 1597 pfd.cColorBits = mode->redBits + mode->greenBits + mode->blueBits; 1598 pfd.cRedBits = mode->redBits; 1599 pfd.cRedShift = 0; /* FIXME */ 1600 pfd.cGreenBits = mode->greenBits; 1601 pfd.cGreenShift = 0; /* FIXME */ 1602 pfd.cBlueBits = mode->blueBits; 1603 pfd.cBlueShift = 0; /* FIXME */ 1604 pfd.cAlphaBits = mode->alphaBits; 1605 pfd.cAlphaShift = 0; /* FIXME */ 1606 1607 pfd.cAccumBits = mode->accumRedBits + mode->accumGreenBits + mode->accumBlueBits + mode->accumAlphaBits; 1608 pfd.cAccumRedBits = mode->accumRedBits; 1609 pfd.cAccumGreenBits = mode->accumGreenBits; 1610 pfd.cAccumBlueBits = mode->accumBlueBits; 1611 pfd.cAccumAlphaBits = mode->accumAlphaBits; 1612 1613 pfd.cDepthBits = mode->depthBits; 1614 pfd.cStencilBits = mode->stencilBits; 1615 pfd.cAuxBuffers = mode->numAuxBuffers; 1616 1617 /* mode->level ? */ 1618 /* mode->pixmapMode ? */ 1619 1620 *pfdret = pfd; 1621 1622 return 0; 1623} 1624 1625#define SET_ATTR_VALUE(attr, value) { attribList[i++] = attr; attribList[i++] = value; assert(i < NUM_ELEMENTS(attribList)); } 1626 1627static int 1628fbConfigToPixelFormatIndex(HDC hdc, __GLXconfig *mode, int drawableTypeOverride, glxWinScreen *winScreen) 1629{ 1630 UINT numFormats; 1631 unsigned int i = 0; 1632 1633 /* convert fbConfig to attr-value list */ 1634 int attribList[60]; 1635 1636 SET_ATTR_VALUE(WGL_SUPPORT_OPENGL_ARB, TRUE); 1637 SET_ATTR_VALUE(WGL_PIXEL_TYPE_ARB, (mode->visualType == GLX_TRUE_COLOR) ? WGL_TYPE_RGBA_ARB : WGL_TYPE_COLORINDEX_ARB); 1638 SET_ATTR_VALUE(WGL_COLOR_BITS_ARB, (mode->visualType == GLX_TRUE_COLOR) ? mode->rgbBits : mode->indexBits); 1639 SET_ATTR_VALUE(WGL_RED_BITS_ARB, mode->redBits); 1640 SET_ATTR_VALUE(WGL_GREEN_BITS_ARB, mode->greenBits); 1641 SET_ATTR_VALUE(WGL_BLUE_BITS_ARB, mode->blueBits); 1642 SET_ATTR_VALUE(WGL_ALPHA_BITS_ARB, mode->alphaBits); 1643 SET_ATTR_VALUE(WGL_ACCUM_RED_BITS_ARB, mode->accumRedBits); 1644 SET_ATTR_VALUE(WGL_ACCUM_GREEN_BITS_ARB, mode->accumGreenBits); 1645 SET_ATTR_VALUE(WGL_ACCUM_BLUE_BITS_ARB, mode->accumBlueBits); 1646 SET_ATTR_VALUE(WGL_ACCUM_ALPHA_BITS_ARB, mode->accumAlphaBits); 1647 SET_ATTR_VALUE(WGL_DEPTH_BITS_ARB, mode->depthBits); 1648 SET_ATTR_VALUE(WGL_STENCIL_BITS_ARB, mode->stencilBits); 1649 SET_ATTR_VALUE(WGL_AUX_BUFFERS_ARB, mode->numAuxBuffers); 1650 1651 if (mode->doubleBufferMode) 1652 SET_ATTR_VALUE(WGL_DOUBLE_BUFFER_ARB, TRUE); 1653 1654 if (mode->stereoMode) 1655 SET_ATTR_VALUE(WGL_STEREO_ARB, TRUE); 1656 1657 // Some attributes are only added to the list if the value requested is not 'don't care', as exactly matching that is daft.. 1658 if (mode->swapMethod == GLX_SWAP_EXCHANGE_OML) 1659 SET_ATTR_VALUE(WGL_SWAP_METHOD_ARB, WGL_SWAP_EXCHANGE_ARB); 1660 1661 if (mode->swapMethod == GLX_SWAP_COPY_OML) 1662 SET_ATTR_VALUE(WGL_SWAP_COPY_ARB, TRUE); 1663 1664 // XXX: this should probably be the other way around, but that messes up drawableTypeOverride 1665 if (mode->visualRating == GLX_SLOW_VISUAL_EXT) 1666 SET_ATTR_VALUE(WGL_ACCELERATION_ARB, WGL_NO_ACCELERATION_ARB); 1667 1668 // must support all the drawable types the mode supports 1669 if ((mode->drawableType | drawableTypeOverride) & GLX_WINDOW_BIT) 1670 SET_ATTR_VALUE(WGL_DRAW_TO_WINDOW_ARB,TRUE); 1671 1672 // XXX: this is a horrible hacky heuristic, in fact this whole drawableTypeOverride thing is a bad idea 1673 // try to avoid asking for formats which don't exist (by not asking for all when adjusting the config to include the drawableTypeOverride) 1674 if (drawableTypeOverride == GLX_WINDOW_BIT) 1675 { 1676 if (mode->drawableType & GLX_PIXMAP_BIT) 1677 SET_ATTR_VALUE(WGL_DRAW_TO_BITMAP_ARB, TRUE); 1678 1679 if (mode->drawableType & GLX_PBUFFER_BIT) 1680 if (winScreen->has_WGL_ARB_pbuffer) 1681 SET_ATTR_VALUE(WGL_DRAW_TO_PBUFFER_ARB, TRUE); 1682 } 1683 else 1684 { 1685 if (drawableTypeOverride & GLX_PIXMAP_BIT) 1686 SET_ATTR_VALUE(WGL_DRAW_TO_BITMAP_ARB, TRUE); 1687 1688 if (drawableTypeOverride & GLX_PBUFFER_BIT) 1689 if (winScreen->has_WGL_ARB_pbuffer) 1690 SET_ATTR_VALUE(WGL_DRAW_TO_PBUFFER_ARB, TRUE); 1691 } 1692 1693 SET_ATTR_VALUE(0, 0); // terminator 1694 1695 /* choose the first match */ 1696 { 1697 int pixelFormatIndex; 1698 1699 if (!wglChoosePixelFormatARBWrapper(hdc, attribList, NULL, 1, &pixelFormatIndex, &numFormats)) 1700 { 1701 ErrorF("wglChoosePixelFormat error: %s\n", glxWinErrorMessage()); 1702 } 1703 else 1704 { 1705 if (numFormats > 0) 1706 { 1707 GLWIN_DEBUG_MSG("wglChoosePixelFormat: chose pixelFormatIndex %d)", pixelFormatIndex); 1708 return pixelFormatIndex; 1709 } 1710 else 1711 ErrorF("wglChoosePixelFormat couldn't decide\n"); 1712 } 1713 } 1714 1715 return 0; 1716} 1717 1718/* ---------------------------------------------------------------------- */ 1719 1720#define BITS_AND_SHIFT_TO_MASK(bits,mask) (((1<<(bits))-1) << (mask)) 1721 1722// 1723// Create the GLXconfigs using DescribePixelFormat() 1724// 1725static void 1726glxWinCreateConfigs(HDC hdc, glxWinScreen *screen) 1727{ 1728 GLXWinConfig *c, *result, *prev = NULL; 1729 int numConfigs = 0; 1730 int i = 0; 1731 int n = 0; 1732 PIXELFORMATDESCRIPTOR pfd; 1733 1734 GLWIN_DEBUG_MSG("glxWinCreateConfigs"); 1735 1736 screen->base.numFBConfigs = 0; 1737 screen->base.fbconfigs = NULL; 1738 1739 // get the number of pixelformats 1740 numConfigs = DescribePixelFormat(hdc, 1, sizeof(PIXELFORMATDESCRIPTOR), NULL); 1741 GLWIN_DEBUG_MSG("DescribePixelFormat says %d possible pixel formats", numConfigs); 1742 1743 /* alloc */ 1744 result = malloc(sizeof(GLXWinConfig) * numConfigs); 1745 1746 if (NULL == result) 1747 { 1748 return; 1749 } 1750 1751 memset(result, 0, sizeof(GLXWinConfig) * numConfigs); 1752 n = 0; 1753 1754 /* fill in configs */ 1755 for (i = 0; i < numConfigs; i++) 1756 { 1757 int rc; 1758 1759 c = &(result[i]); 1760 c->base.next = NULL; 1761 c->pixelFormatIndex = i+1; 1762 1763 rc = DescribePixelFormat(hdc, i+1, sizeof(PIXELFORMATDESCRIPTOR), &pfd); 1764 1765 if (!rc) 1766 { 1767 ErrorF("DescribePixelFormat failed for index %d, error %s\n", i+1, glxWinErrorMessage()); 1768 break; 1769 } 1770 1771 if (glxWinDebugSettings.dumpPFD) 1772 pfdOut(&pfd); 1773 1774 if (!(pfd.dwFlags & (PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP)) || !(pfd.dwFlags & PFD_SUPPORT_OPENGL)) 1775 { 1776 GLWIN_DEBUG_MSG("pixelFormat %d has unsuitable flags 0x%08lx, skipping", i+1, pfd.dwFlags); 1777 continue; 1778 } 1779 1780 c->base.doubleBufferMode = (pfd.dwFlags & PFD_DOUBLEBUFFER) ? GL_TRUE : GL_FALSE; 1781 c->base.stereoMode = (pfd.dwFlags & PFD_STEREO) ? GL_TRUE : GL_FALSE; 1782 1783 c->base.redBits = pfd.cRedBits; 1784 c->base.greenBits = pfd.cGreenBits; 1785 c->base.blueBits = pfd.cBlueBits; 1786 c->base.alphaBits = pfd.cAlphaBits; 1787 1788 c->base.redMask = BITS_AND_SHIFT_TO_MASK(pfd.cRedBits, pfd.cRedShift); 1789 c->base.greenMask = BITS_AND_SHIFT_TO_MASK(pfd.cGreenBits, pfd.cGreenShift); 1790 c->base.blueMask = BITS_AND_SHIFT_TO_MASK(pfd.cBlueBits, pfd.cBlueShift); 1791 c->base.alphaMask = BITS_AND_SHIFT_TO_MASK(pfd.cAlphaBits, pfd.cAlphaShift); 1792 1793 c->base.rgbBits = pfd.cColorBits; 1794 1795 if (pfd.iPixelType == PFD_TYPE_COLORINDEX) 1796 { 1797 c->base.indexBits = pfd.cColorBits; 1798 } 1799 else 1800 { 1801 c->base.indexBits = 0; 1802 } 1803 1804 c->base.accumRedBits = pfd.cAccumRedBits; 1805 c->base.accumGreenBits = pfd.cAccumGreenBits; 1806 c->base.accumBlueBits = pfd.cAccumBlueBits; 1807 c->base.accumAlphaBits = pfd.cAccumAlphaBits; 1808 // pfd.cAccumBits; 1809 1810 c->base.depthBits = pfd.cDepthBits; 1811 c->base.stencilBits = pfd.cStencilBits; 1812 c->base.numAuxBuffers = pfd.cAuxBuffers; 1813 1814 // pfd.iLayerType; // ignored 1815 c->base.level = 0; 1816 // pfd.dwLayerMask; // ignored 1817 // pfd.dwDamageMask; // ignored 1818 1819 c->base.pixmapMode = 0; 1820 c->base.visualID = -1; // will be set by __glXScreenInit() 1821 1822 /* EXT_visual_rating / GLX 1.2 */ 1823 if (pfd.dwFlags & PFD_GENERIC_FORMAT) 1824 { 1825 c->base.visualRating = GLX_SLOW_VISUAL_EXT; 1826 } 1827 else 1828 { 1829 // PFD_GENERIC_ACCELERATED is not considered, so this may be MCD or ICD acclerated... 1830 c->base.visualRating = GLX_NONE_EXT; 1831 } 1832 1833 /* EXT_visual_info / GLX 1.2 */ 1834 if (pfd.iPixelType == PFD_TYPE_COLORINDEX) 1835 { 1836 c->base.visualType = GLX_STATIC_COLOR; 1837 1838 if (!getenv("GLWIN_ENABLE_COLORINDEX_FBCONFIGS")) 1839 { 1840 GLWIN_DEBUG_MSG("pixelFormat %d is PFD_TYPE_COLORINDEX, skipping", i+1); 1841 continue; 1842 } 1843 } 1844 else 1845 { 1846 c->base.visualType = GLX_TRUE_COLOR; 1847 } 1848 1849 // pfd.dwVisibleMask; ??? 1850 c->base.transparentPixel = GLX_NONE; 1851 c->base.transparentRed = GLX_NONE; 1852 c->base.transparentGreen = GLX_NONE; 1853 c->base.transparentBlue = GLX_NONE; 1854 c->base.transparentAlpha = GLX_NONE; 1855 c->base.transparentIndex = GLX_NONE; 1856 1857 /* ARB_multisample / SGIS_multisample */ 1858 c->base.sampleBuffers = 0; 1859 c->base.samples = 0; 1860 1861 /* SGIX_fbconfig / GLX 1.3 */ 1862 c->base.drawableType = (((pfd.dwFlags & PFD_DRAW_TO_WINDOW) ? GLX_WINDOW_BIT : 0) 1863 | ((pfd.dwFlags & PFD_DRAW_TO_BITMAP) ? GLX_PIXMAP_BIT : 0)); 1864 1865 if (pfd.iPixelType == PFD_TYPE_COLORINDEX) 1866 { 1867 c->base.renderType = GLX_RGBA_BIT | GLX_COLOR_INDEX_BIT; 1868 } 1869 else 1870 { 1871 c->base.renderType = GLX_RGBA_BIT; 1872 } 1873 1874 c->base.xRenderable = GL_TRUE; 1875 c->base.fbconfigID = -1; // will be set by __glXScreenInit() 1876 1877 /* SGIX_pbuffer / GLX 1.3 */ 1878 // XXX: How can we find these values out ??? 1879 c->base.maxPbufferWidth = -1; 1880 c->base.maxPbufferHeight = -1; 1881 c->base.maxPbufferPixels = -1; 1882 c->base.optimalPbufferWidth = 0; // there is no optimal value 1883 c->base.optimalPbufferHeight = 0; 1884 1885 /* SGIX_visual_select_group */ 1886 // arrange for visuals with the best acceleration to be preferred in selection 1887 switch (pfd.dwFlags & (PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED)) 1888 { 1889 case 0: 1890 c->base.visualSelectGroup = 2; 1891 break; 1892 1893 case PFD_GENERIC_ACCELERATED: 1894 c->base.visualSelectGroup = 1; 1895 break; 1896 1897 case PFD_GENERIC_FORMAT: 1898 c->base.visualSelectGroup = 0; 1899 break; 1900 1901 default: 1902 ; 1903 // "can't happen" 1904 } 1905 1906 /* OML_swap_method */ 1907 if (pfd.dwFlags & PFD_SWAP_EXCHANGE) 1908 c->base.swapMethod = GLX_SWAP_EXCHANGE_OML; 1909 else if (pfd.dwFlags & PFD_SWAP_COPY) 1910 c->base.swapMethod = GLX_SWAP_COPY_OML; 1911 else 1912 c->base.swapMethod = GLX_SWAP_UNDEFINED_OML; 1913 1914 /* EXT_import_context */ 1915 c->base.screen = screen->base.pScreen->myNum; 1916 1917 /* EXT_texture_from_pixmap */ 1918 c->base.bindToTextureRgb = -1; 1919 c->base.bindToTextureRgba = -1; 1920 c->base.bindToMipmapTexture = -1; 1921 c->base.bindToTextureTargets = -1; 1922 c->base.yInverted = -1; 1923 1924 n++; 1925 1926 // update previous config to point to this config 1927 if (prev) 1928 prev->base.next = &(c->base); 1929 1930 prev = c; 1931 } 1932 1933 GLWIN_DEBUG_MSG("found %d pixelFormats suitable for conversion to fbConfigs", n); 1934 1935 screen->base.numFBConfigs = n; 1936 screen->base.fbconfigs = &(result->base); 1937} 1938 1939// helper function to access an attribute value from an attribute value array by attribute 1940static 1941int getAttrValue(const int attrs[], int values[], unsigned int num, int attr, int fallback) 1942{ 1943 unsigned int i; 1944 for (i = 0; i < num; i++) 1945 { 1946 if (attrs[i] == attr) 1947 { 1948 GLWIN_TRACE_MSG("getAttrValue attr 0x%x, value %d", attr, values[i]); 1949 return values[i]; 1950 } 1951 } 1952 1953 ErrorF("getAttrValue failed to find attr 0x%x, using default value %d\n", attr, fallback); 1954 return fallback; 1955} 1956 1957// 1958// Create the GLXconfigs using wglGetPixelFormatAttribfvARB() extension 1959// 1960static void 1961glxWinCreateConfigsExt(HDC hdc, glxWinScreen *screen) 1962{ 1963 GLXWinConfig *c, *result, *prev = NULL; 1964 int i = 0; 1965 int n = 0; 1966 1967 const int attr = WGL_NUMBER_PIXEL_FORMATS_ARB; 1968 int numConfigs; 1969 1970 int attrs[50]; 1971 unsigned int num_attrs = 0; 1972 1973 GLWIN_DEBUG_MSG("glxWinCreateConfigsExt"); 1974 1975 screen->base.numFBConfigs = 0; 1976 screen->base.fbconfigs = NULL; 1977 1978 if (!wglGetPixelFormatAttribivARBWrapper(hdc, 0, 0, 1, &attr, &numConfigs)) 1979 { 1980 ErrorF("wglGetPixelFormatAttribivARB failed for WGL_NUMBER_PIXEL_FORMATS_ARB: %s\n", glxWinErrorMessage()); 1981 return; 1982 } 1983 1984 GLWIN_DEBUG_MSG("wglGetPixelFormatAttribivARB says %d possible pixel formats", numConfigs); 1985 1986 /* alloc */ 1987 result = malloc(sizeof(GLXWinConfig) * numConfigs); 1988 1989 if (NULL == result) 1990 { 1991 return; 1992 } 1993 1994 memset(result, 0, sizeof(GLXWinConfig) * numConfigs); 1995 n = 0; 1996 1997#define ADD_ATTR(a) { attrs[num_attrs++] = a; assert(num_attrs < NUM_ELEMENTS(attrs)); } 1998 1999 ADD_ATTR(WGL_DRAW_TO_WINDOW_ARB); 2000 ADD_ATTR(WGL_DRAW_TO_BITMAP_ARB); 2001 ADD_ATTR(WGL_ACCELERATION_ARB); 2002 ADD_ATTR(WGL_SWAP_LAYER_BUFFERS_ARB); 2003 ADD_ATTR(WGL_NUMBER_OVERLAYS_ARB); 2004 ADD_ATTR(WGL_NUMBER_UNDERLAYS_ARB); 2005 ADD_ATTR(WGL_TRANSPARENT_ARB); 2006 ADD_ATTR(WGL_TRANSPARENT_RED_VALUE_ARB); 2007 ADD_ATTR(WGL_TRANSPARENT_GREEN_VALUE_ARB); 2008 ADD_ATTR(WGL_TRANSPARENT_GREEN_VALUE_ARB); 2009 ADD_ATTR(WGL_TRANSPARENT_ALPHA_VALUE_ARB); 2010 ADD_ATTR(WGL_SUPPORT_OPENGL_ARB); 2011 ADD_ATTR(WGL_DOUBLE_BUFFER_ARB); 2012 ADD_ATTR(WGL_STEREO_ARB); 2013 ADD_ATTR(WGL_PIXEL_TYPE_ARB); 2014 ADD_ATTR(WGL_COLOR_BITS_ARB); 2015 ADD_ATTR(WGL_RED_BITS_ARB); 2016 ADD_ATTR(WGL_RED_SHIFT_ARB); 2017 ADD_ATTR(WGL_GREEN_BITS_ARB); 2018 ADD_ATTR(WGL_GREEN_SHIFT_ARB); 2019 ADD_ATTR(WGL_BLUE_BITS_ARB); 2020 ADD_ATTR(WGL_BLUE_SHIFT_ARB); 2021 ADD_ATTR(WGL_ALPHA_BITS_ARB); 2022 ADD_ATTR(WGL_ALPHA_SHIFT_ARB); 2023 ADD_ATTR(WGL_ACCUM_RED_BITS_ARB); 2024 ADD_ATTR(WGL_ACCUM_GREEN_BITS_ARB); 2025 ADD_ATTR(WGL_ACCUM_BLUE_BITS_ARB); 2026 ADD_ATTR(WGL_ACCUM_ALPHA_BITS_ARB); 2027 ADD_ATTR(WGL_DEPTH_BITS_ARB); 2028 ADD_ATTR(WGL_STENCIL_BITS_ARB); 2029 ADD_ATTR(WGL_AUX_BUFFERS_ARB); 2030 ADD_ATTR(WGL_SWAP_METHOD_ARB); 2031 2032 if (screen->has_WGL_ARB_multisample) 2033 { 2034 // we may not query these attrs if WGL_ARB_multisample is not offered 2035 ADD_ATTR(WGL_SAMPLE_BUFFERS_ARB); 2036 ADD_ATTR(WGL_SAMPLES_ARB); 2037 } 2038 2039 if (screen->has_WGL_ARB_render_texture) 2040 { 2041 // we may not query these attrs if WGL_ARB_render_texture is not offered 2042 ADD_ATTR(WGL_BIND_TO_TEXTURE_RGB_ARB); 2043 ADD_ATTR(WGL_BIND_TO_TEXTURE_RGBA_ARB); 2044 } 2045 2046 if (screen->has_WGL_ARB_pbuffer) 2047 { 2048 // we may not query these attrs if WGL_ARB_pbuffer is not offered 2049 ADD_ATTR(WGL_DRAW_TO_PBUFFER_ARB); 2050 ADD_ATTR(WGL_MAX_PBUFFER_PIXELS_ARB); 2051 ADD_ATTR(WGL_MAX_PBUFFER_WIDTH_ARB); 2052 ADD_ATTR(WGL_MAX_PBUFFER_HEIGHT_ARB); 2053 } 2054 2055 /* fill in configs */ 2056 for (i = 0; i < numConfigs; i++) 2057 { 2058 int values[num_attrs]; 2059 2060 c = &(result[i]); 2061 c->base.next = NULL; 2062 c->pixelFormatIndex = i+1; 2063 2064 if (!wglGetPixelFormatAttribivARBWrapper(hdc, i+1, 0, num_attrs, attrs, values)) 2065 { 2066 ErrorF("wglGetPixelFormatAttribivARB failed for index %d, error %s\n", i+1, glxWinErrorMessage()); 2067 break; 2068 } 2069 2070#define ATTR_VALUE(a, d) getAttrValue(attrs, values, num_attrs, (a), (d)) 2071 2072 if (!ATTR_VALUE(WGL_SUPPORT_OPENGL_ARB, 0)) 2073 { 2074 GLWIN_DEBUG_MSG("pixelFormat %d isn't WGL_SUPPORT_OPENGL_ARB, skipping", i+1); 2075 continue; 2076 } 2077 2078 c->base.doubleBufferMode = ATTR_VALUE(WGL_DOUBLE_BUFFER_ARB, 0) ? GL_TRUE : GL_FALSE; 2079 c->base.stereoMode = ATTR_VALUE(WGL_STEREO_ARB, 0) ? GL_TRUE : GL_FALSE; 2080 2081 c->base.redBits = ATTR_VALUE(WGL_RED_BITS_ARB, 0); 2082 c->base.greenBits = ATTR_VALUE(WGL_GREEN_BITS_ARB, 0); 2083 c->base.blueBits = ATTR_VALUE(WGL_BLUE_BITS_ARB, 0); 2084 c->base.alphaBits = ATTR_VALUE(WGL_ALPHA_BITS_ARB, 0); 2085 2086 c->base.redMask = BITS_AND_SHIFT_TO_MASK(c->base.redBits, ATTR_VALUE(WGL_RED_SHIFT_ARB, 0)); 2087 c->base.greenMask = BITS_AND_SHIFT_TO_MASK(c->base.greenBits, ATTR_VALUE(WGL_GREEN_SHIFT_ARB, 0)); 2088 c->base.blueMask = BITS_AND_SHIFT_TO_MASK(c->base.blueBits, ATTR_VALUE(WGL_BLUE_SHIFT_ARB, 0)); 2089 c->base.alphaMask = BITS_AND_SHIFT_TO_MASK(c->base.alphaBits, ATTR_VALUE(WGL_ALPHA_SHIFT_ARB, 0)); 2090 2091 switch (ATTR_VALUE(WGL_PIXEL_TYPE_ARB, 0)) 2092 { 2093 case WGL_TYPE_COLORINDEX_ARB: 2094 c->base.indexBits = ATTR_VALUE(WGL_COLOR_BITS_ARB, 0); 2095 c->base.rgbBits = 0; 2096 c->base.visualType = GLX_STATIC_COLOR; 2097 2098 if (!getenv("GLWIN_ENABLE_COLORINDEX_FBCONFIGS")) 2099 { 2100 GLWIN_DEBUG_MSG("pixelFormat %d is WGL_TYPE_COLORINDEX_ARB, skipping", i+1); 2101 continue; 2102 } 2103 2104 break; 2105 2106 case WGL_TYPE_RGBA_FLOAT_ARB: 2107 GLWIN_DEBUG_MSG("pixelFormat %d is WGL_TYPE_RGBA_FLOAT_ARB, skipping", i+1); 2108 continue; 2109 2110 case WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT: 2111 GLWIN_DEBUG_MSG("pixelFormat %d is WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT, skipping", i+1); 2112 continue; 2113 2114 case WGL_TYPE_RGBA_ARB: 2115 c->base.indexBits = 0; 2116 c->base.rgbBits = ATTR_VALUE(WGL_COLOR_BITS_ARB, 0); 2117 c->base.visualType = GLX_TRUE_COLOR; 2118 break; 2119 2120 default: 2121 ErrorF("wglGetPixelFormatAttribivARB returned unknown value 0x%x for WGL_PIXEL_TYPE_ARB\n", ATTR_VALUE(WGL_PIXEL_TYPE_ARB, 0)); 2122 continue; 2123 } 2124 2125 c->base.accumRedBits = ATTR_VALUE(WGL_ACCUM_RED_BITS_ARB, 0); 2126 c->base.accumGreenBits = ATTR_VALUE(WGL_ACCUM_GREEN_BITS_ARB, 0); 2127 c->base.accumBlueBits = ATTR_VALUE(WGL_ACCUM_BLUE_BITS_ARB, 0); 2128 c->base.accumAlphaBits = ATTR_VALUE(WGL_ACCUM_ALPHA_BITS_ARB, 0); 2129 2130 c->base.depthBits = ATTR_VALUE(WGL_DEPTH_BITS_ARB, 0); 2131 c->base.stencilBits = ATTR_VALUE(WGL_STENCIL_BITS_ARB, 0); 2132 c->base.numAuxBuffers = ATTR_VALUE(WGL_AUX_BUFFERS_ARB, 0); 2133 2134 { 2135 int layers = ATTR_VALUE(WGL_NUMBER_OVERLAYS_ARB,0) + ATTR_VALUE(WGL_NUMBER_UNDERLAYS_ARB, 0); 2136 2137 if (layers > 0) 2138 { 2139 ErrorF("pixelFormat %d: has %d overlay, %d underlays which aren't currently handled", i, ATTR_VALUE(WGL_NUMBER_OVERLAYS_ARB,0), ATTR_VALUE(WGL_NUMBER_UNDERLAYS_ARB, 0)); 2140 // XXX: need to iterate over layers? 2141 } 2142 } 2143 c->base.level = 0; 2144 2145 c->base.pixmapMode = 0; // ??? 2146 c->base.visualID = -1; // will be set by __glXScreenInit() 2147 2148 /* EXT_visual_rating / GLX 1.2 */ 2149 switch (ATTR_VALUE(WGL_ACCELERATION_ARB, 0)) 2150 { 2151 default: 2152 ErrorF("wglGetPixelFormatAttribivARB returned unknown value 0x%x for WGL_ACCELERATION_ARB\n", ATTR_VALUE(WGL_ACCELERATION_ARB, 0)); 2153 2154 case WGL_NO_ACCELERATION_ARB: 2155 c->base.visualRating = GLX_SLOW_VISUAL_EXT; 2156 break; 2157 2158 case WGL_GENERIC_ACCELERATION_ARB: 2159 case WGL_FULL_ACCELERATION_ARB: 2160 c->base.visualRating = GLX_NONE_EXT; 2161 break; 2162 } 2163 2164 /* EXT_visual_info / GLX 1.2 */ 2165 // c->base.visualType is set above 2166 if (ATTR_VALUE(WGL_TRANSPARENT_ARB, 0)) 2167 { 2168 c->base.transparentPixel = (c->base.visualType == GLX_TRUE_COLOR) ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT; 2169 c->base.transparentRed = ATTR_VALUE(WGL_TRANSPARENT_RED_VALUE_ARB, 0); 2170 c->base.transparentGreen = ATTR_VALUE(WGL_TRANSPARENT_GREEN_VALUE_ARB, 0); 2171 c->base.transparentBlue = ATTR_VALUE(WGL_TRANSPARENT_BLUE_VALUE_ARB, 0); 2172 c->base.transparentAlpha = ATTR_VALUE(WGL_TRANSPARENT_ALPHA_VALUE_ARB, 0); 2173 c->base.transparentIndex = ATTR_VALUE(WGL_TRANSPARENT_INDEX_VALUE_ARB, 0); 2174 } 2175 else 2176 { 2177 c->base.transparentPixel = GLX_NONE_EXT; 2178 c->base.transparentRed = GLX_NONE; 2179 c->base.transparentGreen = GLX_NONE; 2180 c->base.transparentBlue = GLX_NONE; 2181 c->base.transparentAlpha = GLX_NONE; 2182 c->base.transparentIndex = GLX_NONE; 2183 } 2184 2185 /* ARB_multisample / SGIS_multisample */ 2186 if (screen->has_WGL_ARB_multisample) 2187 { 2188 c->base.sampleBuffers = ATTR_VALUE(WGL_SAMPLE_BUFFERS_ARB, 0); 2189 c->base.samples = ATTR_VALUE(WGL_SAMPLES_ARB, 0); 2190 } 2191 else 2192 { 2193 c->base.sampleBuffers = 0; 2194 c->base.samples = 0; 2195 } 2196 2197 /* SGIX_fbconfig / GLX 1.3 */ 2198 c->base.drawableType = ((ATTR_VALUE(WGL_DRAW_TO_WINDOW_ARB, 0) ? GLX_WINDOW_BIT : 0) 2199 | (ATTR_VALUE(WGL_DRAW_TO_BITMAP_ARB, 0) ? GLX_PIXMAP_BIT : 0) 2200 | (ATTR_VALUE(WGL_DRAW_TO_PBUFFER_ARB, 0) ? GLX_PBUFFER_BIT : 0)); 2201 2202 /* 2203 Assume OpenGL RGBA rendering is available on all visuals 2204 (it is specified to render to red component in single-channel visuals, 2205 if supported, but there doesn't seem to be any mechanism to check if it 2206 is supported) 2207 2208 Color index rendering is only supported on single-channel visuals 2209 */ 2210 if (c->base.visualType == GLX_STATIC_COLOR) 2211 { 2212 c->base.renderType = GLX_RGBA_BIT | GLX_COLOR_INDEX_BIT; 2213 } 2214 else 2215 { 2216 c->base.renderType = GLX_RGBA_BIT; 2217 } 2218 2219 c->base.xRenderable = GL_TRUE; 2220 c->base.fbconfigID = -1; // will be set by __glXScreenInit() 2221 2222 /* SGIX_pbuffer / GLX 1.3 */ 2223 if (screen->has_WGL_ARB_pbuffer) 2224 { 2225 c->base.maxPbufferWidth = ATTR_VALUE(WGL_MAX_PBUFFER_WIDTH_ARB, -1); 2226 c->base.maxPbufferHeight = ATTR_VALUE(WGL_MAX_PBUFFER_HEIGHT_ARB, -1); 2227 c->base.maxPbufferPixels = ATTR_VALUE(WGL_MAX_PBUFFER_PIXELS_ARB, -1); 2228 } 2229 else 2230 { 2231 c->base.maxPbufferWidth = -1; 2232 c->base.maxPbufferHeight = -1; 2233 c->base.maxPbufferPixels = -1; 2234 } 2235 c->base.optimalPbufferWidth = 0; // there is no optimal value 2236 c->base.optimalPbufferHeight = 0; 2237 2238 /* SGIX_visual_select_group */ 2239 // arrange for visuals with the best acceleration to be preferred in selection 2240 switch (ATTR_VALUE(WGL_ACCELERATION_ARB, 0)) 2241 { 2242 case WGL_FULL_ACCELERATION_ARB: 2243 c->base.visualSelectGroup = 2; 2244 break; 2245 2246 case WGL_GENERIC_ACCELERATION_ARB: 2247 c->base.visualSelectGroup = 1; 2248 break; 2249 2250 default: 2251 case WGL_NO_ACCELERATION_ARB: 2252 c->base.visualSelectGroup = 0; 2253 break; 2254 } 2255 2256 /* OML_swap_method */ 2257 switch (ATTR_VALUE(WGL_SWAP_METHOD_ARB, 0)) 2258 { 2259 case WGL_SWAP_EXCHANGE_ARB: 2260 c->base.swapMethod = GLX_SWAP_EXCHANGE_OML; 2261 break; 2262 2263 case WGL_SWAP_COPY_ARB: 2264 c->base.swapMethod = GLX_SWAP_COPY_OML; 2265 break; 2266 2267 default: 2268 ErrorF("wglGetPixelFormatAttribivARB returned unknown value 0x%x for WGL_SWAP_METHOD_ARB\n", ATTR_VALUE(WGL_SWAP_METHOD_ARB, 0)); 2269 2270 case WGL_SWAP_UNDEFINED_ARB: 2271 c->base.swapMethod = GLX_SWAP_UNDEFINED_OML; 2272 } 2273 2274 /* EXT_import_context */ 2275 c->base.screen = screen->base.pScreen->myNum; 2276 2277 /* EXT_texture_from_pixmap */ 2278 /* 2279 Mesa's DRI configs always have bindToTextureRgb/Rgba TRUE (see driCreateConfigs(), so setting 2280 bindToTextureRgb/bindToTextureRgba to FALSE means that swrast can't find any fbConfigs to use, 2281 so setting these to 0, even if we know bindToTexture isn't available, isn't a good idea... 2282 */ 2283 if (screen->has_WGL_ARB_render_texture) 2284 { 2285 c->base.bindToTextureRgb = ATTR_VALUE(WGL_BIND_TO_TEXTURE_RGB_ARB, -1); 2286 c->base.bindToTextureRgba = ATTR_VALUE(WGL_BIND_TO_TEXTURE_RGBA_ARB, -1); 2287 } 2288 else 2289 { 2290 c->base.bindToTextureRgb = -1; 2291 c->base.bindToTextureRgba = -1; 2292 } 2293 c->base.bindToMipmapTexture = -1; 2294 c->base.bindToTextureTargets = GLX_TEXTURE_1D_BIT_EXT | GLX_TEXTURE_2D_BIT_EXT | GLX_TEXTURE_RECTANGLE_BIT_EXT; 2295 c->base.yInverted = -1; 2296 2297 n++; 2298 2299 // update previous config to point to this config 2300 if (prev) 2301 prev->base.next = &(c->base); 2302 2303 prev = c; 2304 } 2305 2306 screen->base.numFBConfigs = n; 2307 screen->base.fbconfigs = &(result->base); 2308} 2309