1706f2543Smrg/* 2706f2543Smrg * File: indirect.c 3706f2543Smrg * Purpose: A GLX implementation that uses Windows OpenGL library 4706f2543Smrg * 5706f2543Smrg * Authors: Alexander Gottwald 6706f2543Smrg * Jon TURNEY 7706f2543Smrg * 8706f2543Smrg * Copyright (c) Jon TURNEY 2009 9706f2543Smrg * Copyright (c) Alexander Gottwald 2004 10706f2543Smrg * 11706f2543Smrg * Portions of this file are copied from GL/apple/indirect.c, 12706f2543Smrg * which contains the following copyright: 13706f2543Smrg * 14706f2543Smrg * Copyright (c) 2007, 2008, 2009 Apple Inc. 15706f2543Smrg * Copyright (c) 2004 Torrey T. Lyons. All Rights Reserved. 16706f2543Smrg * Copyright (c) 2002 Greg Parker. All Rights Reserved. 17706f2543Smrg * 18706f2543Smrg * Portions of this file are copied from Mesa's xf86glx.c, 19706f2543Smrg * which contains the following copyright: 20706f2543Smrg * 21706f2543Smrg * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 22706f2543Smrg * All Rights Reserved. 23706f2543Smrg * 24706f2543Smrg * 25706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining a 26706f2543Smrg * copy of this software and associated documentation files (the "Software"), 27706f2543Smrg * to deal in the Software without restriction, including without limitation 28706f2543Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 29706f2543Smrg * and/or sell copies of the Software, and to permit persons to whom the 30706f2543Smrg * Software is furnished to do so, subject to the following conditions: 31706f2543Smrg * 32706f2543Smrg * The above copyright notice and this permission notice shall be included in 33706f2543Smrg * all copies or substantial portions of the Software. 34706f2543Smrg * 35706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 36706f2543Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 37706f2543Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 38706f2543Smrg * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 39706f2543Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 40706f2543Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 41706f2543Smrg * DEALINGS IN THE SOFTWARE. 42706f2543Smrg */ 43706f2543Smrg 44706f2543Smrg/* 45706f2543Smrg TODO: 46706f2543Smrg - hook up remaining unimplemented extensions 47706f2543Smrg - research what guarantees glXWaitX, glXWaitGL are supposed to offer, and implement then 48706f2543Smrg using GdiFlush and/or glFinish 49706f2543Smrg - pbuffer clobbering: we don't get async notification, but can we arrange to emit the 50706f2543Smrg event when we notice it's been clobbered? at the very least, check if it's been clobbered 51706f2543Smrg before using it? 52706f2543Smrg - are the __GLXConfig * we get handed back ones we are made (so we can extend the structure 53706f2543Smrg with privates?) Or are they created inside the GLX core as well? 54706f2543Smrg*/ 55706f2543Smrg 56706f2543Smrg/* 57706f2543Smrg MSDN clarifications: 58706f2543Smrg 59706f2543Smrg It says SetPixelFormat()'s PIXELFORMATDESCRIPTOR pointer argument has no effect 60706f2543Smrg except on metafiles, this seems to mean that as it's ok to supply NULL if the DC 61706f2543Smrg is not for a metafile 62706f2543Smrg 63706f2543Smrg wglMakeCurrent ignores the hdc if hglrc is NULL, so wglMakeCurrent(NULL, NULL) 64706f2543Smrg is used to make no context current 65706f2543Smrg 66706f2543Smrg*/ 67706f2543Smrg 68706f2543Smrg#ifdef HAVE_XWIN_CONFIG_H 69706f2543Smrg#include <xwin-config.h> 70706f2543Smrg#endif 71706f2543Smrg 72706f2543Smrg#include "glwindows.h" 73706f2543Smrg#include <glx/glxserver.h> 74706f2543Smrg#include <glx/glxutil.h> 75706f2543Smrg#include <glx/extension_string.h> 76706f2543Smrg#include <GL/glxtokens.h> 77706f2543Smrg 78706f2543Smrg#include <winpriv.h> 79706f2543Smrg#include <wgl_ext_api.h> 80706f2543Smrg 81706f2543Smrg#define NUM_ELEMENTS(x) (sizeof(x)/ sizeof(x[1])) 82706f2543Smrg 83706f2543Smrg/* ---------------------------------------------------------------------- */ 84706f2543Smrg/* 85706f2543Smrg * structure definitions 86706f2543Smrg */ 87706f2543Smrg 88706f2543Smrgtypedef struct __GLXWinContext __GLXWinContext; 89706f2543Smrgtypedef struct __GLXWinDrawable __GLXWinDrawable; 90706f2543Smrgtypedef struct __GLXWinScreen glxWinScreen; 91706f2543Smrgtypedef struct __GLXWinConfig GLXWinConfig; 92706f2543Smrg 93706f2543Smrgstruct __GLXWinContext { 94706f2543Smrg __GLXcontext base; 95706f2543Smrg HGLRC ctx; /* Windows GL Context */ 96706f2543Smrg __GLXWinContext *shareContext; /* Context with which we will share display lists and textures */ 97706f2543Smrg HWND hwnd; /* For detecting when HWND has changed */ 98706f2543Smrg}; 99706f2543Smrg 100706f2543Smrgstruct __GLXWinDrawable 101706f2543Smrg{ 102706f2543Smrg __GLXdrawable base; 103706f2543Smrg __GLXWinContext *drawContext; 104706f2543Smrg __GLXWinContext *readContext; 105706f2543Smrg 106706f2543Smrg /* If this drawable is GLX_DRAWABLE_PBUFFER */ 107706f2543Smrg HPBUFFERARB hPbuffer; 108706f2543Smrg 109706f2543Smrg /* If this drawable is GLX_DRAWABLE_PIXMAP */ 110706f2543Smrg HDC dibDC; 111706f2543Smrg HBITMAP hDIB; 112706f2543Smrg HBITMAP hOldDIB; /* original DIB for DC */ 113706f2543Smrg void *pOldBits; /* original pBits for this drawable's pixmap */ 114706f2543Smrg}; 115706f2543Smrg 116706f2543Smrgstruct __GLXWinScreen 117706f2543Smrg{ 118706f2543Smrg __GLXscreen base; 119706f2543Smrg 120706f2543Smrg /* Supported GLX extensions */ 121706f2543Smrg unsigned char glx_enable_bits[__GLX_EXT_BYTES]; 122706f2543Smrg 123706f2543Smrg Bool has_WGL_ARB_multisample; 124706f2543Smrg Bool has_WGL_ARB_pixel_format; 125706f2543Smrg Bool has_WGL_ARB_pbuffer; 126706f2543Smrg Bool has_WGL_ARB_render_texture; 127706f2543Smrg 128706f2543Smrg /* wrapped screen functions */ 129706f2543Smrg RealizeWindowProcPtr RealizeWindow; 130706f2543Smrg UnrealizeWindowProcPtr UnrealizeWindow; 131706f2543Smrg CopyWindowProcPtr CopyWindow; 132706f2543Smrg}; 133706f2543Smrg 134706f2543Smrgstruct __GLXWinConfig 135706f2543Smrg{ 136706f2543Smrg __GLXconfig base; 137706f2543Smrg int pixelFormatIndex; 138706f2543Smrg}; 139706f2543Smrg 140706f2543Smrg/* ---------------------------------------------------------------------- */ 141706f2543Smrg/* 142706f2543Smrg * Various debug helpers 143706f2543Smrg */ 144706f2543Smrg 145706f2543Smrg#define GLWIN_DEBUG_HWND(hwnd) \ 146706f2543Smrg if (glxWinDebugSettings.dumpHWND) { \ 147706f2543Smrg char buffer[1024]; \ 148706f2543Smrg if (GetWindowText(hwnd, buffer, sizeof(buffer))==0) *buffer=0; \ 149706f2543Smrg GLWIN_DEBUG_MSG("Got HWND %p for window '%s'", hwnd, buffer); \ 150706f2543Smrg } 151706f2543Smrg 152706f2543SmrgglxWinDebugSettingsRec glxWinDebugSettings = { 0, 0, 0, 0, 0, 0}; 153706f2543Smrg 154706f2543Smrgstatic void glxWinInitDebugSettings(void) 155706f2543Smrg{ 156706f2543Smrg char *envptr; 157706f2543Smrg 158706f2543Smrg envptr = getenv("GLWIN_ENABLE_DEBUG"); 159706f2543Smrg if (envptr != NULL) 160706f2543Smrg glxWinDebugSettings.enableDebug = (atoi(envptr) == 1); 161706f2543Smrg 162706f2543Smrg envptr = getenv("GLWIN_ENABLE_TRACE"); 163706f2543Smrg if (envptr != NULL) 164706f2543Smrg glxWinDebugSettings.enableTrace = (atoi(envptr) == 1); 165706f2543Smrg 166706f2543Smrg envptr = getenv("GLWIN_DUMP_PFD"); 167706f2543Smrg if (envptr != NULL) 168706f2543Smrg glxWinDebugSettings.dumpPFD = (atoi(envptr) == 1); 169706f2543Smrg 170706f2543Smrg envptr = getenv("GLWIN_DUMP_HWND"); 171706f2543Smrg if (envptr != NULL) 172706f2543Smrg glxWinDebugSettings.dumpHWND = (atoi(envptr) == 1); 173706f2543Smrg 174706f2543Smrg envptr = getenv("GLWIN_DUMP_DC"); 175706f2543Smrg if (envptr != NULL) 176706f2543Smrg glxWinDebugSettings.dumpDC = (atoi(envptr) == 1); 177706f2543Smrg 178706f2543Smrg envptr = getenv("GLWIN_ENABLE_GLCALL_TRACE"); 179706f2543Smrg if (envptr != NULL) 180706f2543Smrg glxWinDebugSettings.enableGLcallTrace = (atoi(envptr) == 1); 181706f2543Smrg 182706f2543Smrg envptr = getenv("GLWIN_ENABLE_WGLCALL_TRACE"); 183706f2543Smrg if (envptr != NULL) 184706f2543Smrg glxWinDebugSettings.enableWGLcallTrace = (atoi(envptr) == 1); 185706f2543Smrg 186706f2543Smrg envptr = getenv("GLWIN_DEBUG_ALL"); 187706f2543Smrg if (envptr != NULL) 188706f2543Smrg { 189706f2543Smrg glxWinDebugSettings.enableDebug = 1; 190706f2543Smrg glxWinDebugSettings.enableTrace = 1; 191706f2543Smrg glxWinDebugSettings.dumpPFD = 1; 192706f2543Smrg glxWinDebugSettings.dumpHWND = 1; 193706f2543Smrg glxWinDebugSettings.dumpDC = 1; 194706f2543Smrg glxWinDebugSettings.enableGLcallTrace = 1; 195706f2543Smrg glxWinDebugSettings.enableWGLcallTrace = 1; 196706f2543Smrg } 197706f2543Smrg} 198706f2543Smrg 199706f2543Smrgstatic 200706f2543Smrgconst char *glxWinErrorMessage(void) 201706f2543Smrg{ 202706f2543Smrg static char errorbuffer[1024]; 203706f2543Smrg 204706f2543Smrg if (!FormatMessage( 205706f2543Smrg FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 206706f2543Smrg NULL, 207706f2543Smrg GetLastError(), 208706f2543Smrg MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 209706f2543Smrg (LPTSTR) &errorbuffer, 210706f2543Smrg sizeof(errorbuffer), 211706f2543Smrg NULL )) 212706f2543Smrg { 213706f2543Smrg snprintf(errorbuffer, sizeof(errorbuffer), "Unknown error in FormatMessage: %08x!", (unsigned)GetLastError()); 214706f2543Smrg } 215706f2543Smrg 216706f2543Smrg if (errorbuffer[strlen(errorbuffer)-1] == '\n') 217706f2543Smrg errorbuffer[strlen(errorbuffer)-1] = 0; 218706f2543Smrg 219706f2543Smrg return errorbuffer; 220706f2543Smrg} 221706f2543Smrg 222706f2543Smrgstatic void pfdOut(const PIXELFORMATDESCRIPTOR *pfd); 223706f2543Smrg 224706f2543Smrg#define DUMP_PFD_FLAG(flag) \ 225706f2543Smrg if (pfd->dwFlags & flag) { \ 226706f2543Smrg ErrorF("%s%s", pipesym, #flag); \ 227706f2543Smrg pipesym = " | "; \ 228706f2543Smrg } 229706f2543Smrg 230706f2543Smrgstatic void pfdOut(const PIXELFORMATDESCRIPTOR *pfd) 231706f2543Smrg{ 232706f2543Smrg const char *pipesym = ""; /* will be set after first flag dump */ 233706f2543Smrg ErrorF("PIXELFORMATDESCRIPTOR:\n"); 234706f2543Smrg ErrorF("nSize = %u\n", pfd->nSize); 235706f2543Smrg ErrorF("nVersion = %u\n", pfd->nVersion); 236706f2543Smrg ErrorF("dwFlags = %lu = {", pfd->dwFlags); 237706f2543Smrg DUMP_PFD_FLAG(PFD_DOUBLEBUFFER); 238706f2543Smrg DUMP_PFD_FLAG(PFD_STEREO); 239706f2543Smrg DUMP_PFD_FLAG(PFD_DRAW_TO_WINDOW); 240706f2543Smrg DUMP_PFD_FLAG(PFD_DRAW_TO_BITMAP); 241706f2543Smrg DUMP_PFD_FLAG(PFD_SUPPORT_GDI); 242706f2543Smrg DUMP_PFD_FLAG(PFD_SUPPORT_OPENGL); 243706f2543Smrg DUMP_PFD_FLAG(PFD_GENERIC_FORMAT); 244706f2543Smrg DUMP_PFD_FLAG(PFD_NEED_PALETTE); 245706f2543Smrg DUMP_PFD_FLAG(PFD_NEED_SYSTEM_PALETTE); 246706f2543Smrg DUMP_PFD_FLAG(PFD_SWAP_EXCHANGE); 247706f2543Smrg DUMP_PFD_FLAG(PFD_SWAP_COPY); 248706f2543Smrg DUMP_PFD_FLAG(PFD_SWAP_LAYER_BUFFERS); 249706f2543Smrg DUMP_PFD_FLAG(PFD_GENERIC_ACCELERATED); 250706f2543Smrg DUMP_PFD_FLAG(PFD_DEPTH_DONTCARE); 251706f2543Smrg DUMP_PFD_FLAG(PFD_DOUBLEBUFFER_DONTCARE); 252706f2543Smrg DUMP_PFD_FLAG(PFD_STEREO_DONTCARE); 253706f2543Smrg ErrorF("}\n"); 254706f2543Smrg 255706f2543Smrg ErrorF("iPixelType = %hu = %s\n", pfd->iPixelType, 256706f2543Smrg (pfd->iPixelType == PFD_TYPE_RGBA ? "PFD_TYPE_RGBA" : "PFD_TYPE_COLORINDEX")); 257706f2543Smrg ErrorF("cColorBits = %hhu\n", pfd->cColorBits); 258706f2543Smrg ErrorF("cRedBits = %hhu\n", pfd->cRedBits); 259706f2543Smrg ErrorF("cRedShift = %hhu\n", pfd->cRedShift); 260706f2543Smrg ErrorF("cGreenBits = %hhu\n", pfd->cGreenBits); 261706f2543Smrg ErrorF("cGreenShift = %hhu\n", pfd->cGreenShift); 262706f2543Smrg ErrorF("cBlueBits = %hhu\n", pfd->cBlueBits); 263706f2543Smrg ErrorF("cBlueShift = %hhu\n", pfd->cBlueShift); 264706f2543Smrg ErrorF("cAlphaBits = %hhu\n", pfd->cAlphaBits); 265706f2543Smrg ErrorF("cAlphaShift = %hhu\n", pfd->cAlphaShift); 266706f2543Smrg ErrorF("cAccumBits = %hhu\n", pfd->cAccumBits); 267706f2543Smrg ErrorF("cAccumRedBits = %hhu\n", pfd->cAccumRedBits); 268706f2543Smrg ErrorF("cAccumGreenBits = %hhu\n", pfd->cAccumGreenBits); 269706f2543Smrg ErrorF("cAccumBlueBits = %hhu\n", pfd->cAccumBlueBits); 270706f2543Smrg ErrorF("cAccumAlphaBits = %hhu\n", pfd->cAccumAlphaBits); 271706f2543Smrg ErrorF("cDepthBits = %hhu\n", pfd->cDepthBits); 272706f2543Smrg ErrorF("cStencilBits = %hhu\n", pfd->cStencilBits); 273706f2543Smrg ErrorF("cAuxBuffers = %hhu\n", pfd->cAuxBuffers); 274706f2543Smrg ErrorF("iLayerType = %hhu\n", pfd->iLayerType); 275706f2543Smrg ErrorF("bReserved = %hhu\n", pfd->bReserved); 276706f2543Smrg ErrorF("dwLayerMask = %lu\n", pfd->dwLayerMask); 277706f2543Smrg ErrorF("dwVisibleMask = %lu\n", pfd->dwVisibleMask); 278706f2543Smrg ErrorF("dwDamageMask = %lu\n", pfd->dwDamageMask); 279706f2543Smrg ErrorF("\n"); 280706f2543Smrg} 281706f2543Smrg 282706f2543Smrgstatic const char * 283706f2543Smrgvisual_class_name(int cls) 284706f2543Smrg{ 285706f2543Smrg switch (cls) { 286706f2543Smrg case GLX_STATIC_COLOR: 287706f2543Smrg return "StaticColor"; 288706f2543Smrg case GLX_PSEUDO_COLOR: 289706f2543Smrg return "PseudoColor"; 290706f2543Smrg case GLX_STATIC_GRAY: 291706f2543Smrg return "StaticGray"; 292706f2543Smrg case GLX_GRAY_SCALE: 293706f2543Smrg return "GrayScale"; 294706f2543Smrg case GLX_TRUE_COLOR: 295706f2543Smrg return "TrueColor"; 296706f2543Smrg case GLX_DIRECT_COLOR: 297706f2543Smrg return "DirectColor"; 298706f2543Smrg default: 299706f2543Smrg return "-none-"; 300706f2543Smrg } 301706f2543Smrg} 302706f2543Smrg 303706f2543Smrgstatic const char * 304706f2543Smrgswap_method_name(int mthd) 305706f2543Smrg{ 306706f2543Smrg switch (mthd) 307706f2543Smrg { 308706f2543Smrg case GLX_SWAP_EXCHANGE_OML: 309706f2543Smrg return "xchg"; 310706f2543Smrg case GLX_SWAP_COPY_OML: 311706f2543Smrg return "copy"; 312706f2543Smrg case GLX_SWAP_UNDEFINED_OML: 313706f2543Smrg return " "; 314706f2543Smrg default: 315706f2543Smrg return "????"; 316706f2543Smrg } 317706f2543Smrg} 318706f2543Smrg 319706f2543Smrgstatic void 320706f2543SmrgfbConfigsDump(unsigned int n, __GLXconfig *c) 321706f2543Smrg{ 322706f2543Smrg ErrorF("%d fbConfigs\n", n); 323706f2543Smrg ErrorF("pxf vis fb render Ste aux accum MS drawable Group/\n"); 324706f2543Smrg 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"); 325706f2543Smrg ErrorF("-----------------------------------------------------------------------------------------------------------------------------\n"); 326706f2543Smrg 327706f2543Smrg while (c != NULL) 328706f2543Smrg { 329706f2543Smrg unsigned int i = ((GLXWinConfig *)c)->pixelFormatIndex; 330706f2543Smrg 331706f2543Smrg ErrorF("%3d %2x %2x " 332706f2543Smrg "%-11s" 333706f2543Smrg " %3d %3d %s %s %s %s %s " 334706f2543Smrg "%2d %2d %2d %2d " 335706f2543Smrg "%2d %2d " 336706f2543Smrg "%2d " 337706f2543Smrg "%2d %2d %2d %2d" 338706f2543Smrg " %2d %2d" 339706f2543Smrg " %s %s %s " 340706f2543Smrg " %s " 341706f2543Smrg " %s " 342706f2543Smrg " %d %s" 343706f2543Smrg "\n", 344706f2543Smrg i, c->visualID, c->fbconfigID, 345706f2543Smrg visual_class_name(c->visualType), 346706f2543Smrg c->rgbBits ? c->rgbBits : c->indexBits, 347706f2543Smrg c->level, 348706f2543Smrg (c->renderType & GLX_RGBA_BIT) ? "y" : ".", 349706f2543Smrg (c->renderType & GLX_COLOR_INDEX_BIT) ? "y" : ".", 350706f2543Smrg c->doubleBufferMode ? "y" : ".", 351706f2543Smrg swap_method_name(c->swapMethod), 352706f2543Smrg c->stereoMode ? "y" : ".", 353706f2543Smrg c->redBits, c->greenBits, c->blueBits, c->alphaBits, 354706f2543Smrg c->depthBits, c->stencilBits, 355706f2543Smrg c->numAuxBuffers, 356706f2543Smrg c->accumRedBits, c->accumGreenBits, c->accumBlueBits, c->accumAlphaBits, 357706f2543Smrg c->sampleBuffers, c->samples, 358706f2543Smrg (c->drawableType & GLX_WINDOW_BIT) ? "y" : ".", 359706f2543Smrg (c->drawableType & GLX_PIXMAP_BIT) ? "y" : ".", 360706f2543Smrg (c->drawableType & GLX_PBUFFER_BIT) ? "y" : ".", 361706f2543Smrg ".", 362706f2543Smrg (c->transparentPixel != GLX_NONE_EXT) ? "y" : ".", 363706f2543Smrg c->visualSelectGroup, (c->visualRating == GLX_SLOW_VISUAL_EXT) ? "*" : " "); 364706f2543Smrg 365706f2543Smrg c = c->next; 366706f2543Smrg } 367706f2543Smrg} 368706f2543Smrg 369706f2543Smrg/* ---------------------------------------------------------------------- */ 370706f2543Smrg/* 371706f2543Smrg * Forward declarations 372706f2543Smrg */ 373706f2543Smrg 374706f2543Smrgstatic __GLXscreen *glxWinScreenProbe(ScreenPtr pScreen); 375706f2543Smrgstatic __GLXcontext *glxWinCreateContext(__GLXscreen *screen, 376706f2543Smrg __GLXconfig *modes, 377706f2543Smrg __GLXcontext *baseShareContext); 378706f2543Smrgstatic __GLXdrawable *glxWinCreateDrawable(ClientPtr client, 379706f2543Smrg __GLXscreen *screen, 380706f2543Smrg DrawablePtr pDraw, 381706f2543Smrg XID drawId, 382706f2543Smrg int type, 383706f2543Smrg XID glxDrawId, 384706f2543Smrg __GLXconfig *conf); 385706f2543Smrg 386706f2543Smrgstatic Bool glxWinRealizeWindow(WindowPtr pWin); 387706f2543Smrgstatic Bool glxWinUnrealizeWindow(WindowPtr pWin); 388706f2543Smrgstatic void glxWinCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc); 389706f2543Smrg 390706f2543Smrgstatic HDC glxWinMakeDC(__GLXWinContext *gc, __GLXWinDrawable *draw, HDC *hdc, HWND *hwnd); 391706f2543Smrgstatic void glxWinReleaseDC(HWND hwnd, HDC hdc, __GLXWinDrawable *draw); 392706f2543Smrg 393706f2543Smrgstatic void glxWinCreateConfigs(HDC dc, glxWinScreen *screen); 394706f2543Smrgstatic void glxWinCreateConfigsExt(HDC hdc, glxWinScreen *screen); 395706f2543Smrgstatic int fbConfigToPixelFormat(__GLXconfig *mode, PIXELFORMATDESCRIPTOR *pfdret, int drawableTypeOverride); 396706f2543Smrgstatic int fbConfigToPixelFormatIndex(HDC hdc, __GLXconfig *mode, int drawableTypeOverride, glxWinScreen *winScreen); 397706f2543Smrg 398706f2543Smrg/* ---------------------------------------------------------------------- */ 399706f2543Smrg/* 400706f2543Smrg * The GLX provider 401706f2543Smrg */ 402706f2543Smrg 403706f2543Smrg__GLXprovider __glXWGLProvider = { 404706f2543Smrg glxWinScreenProbe, 405706f2543Smrg "Win32 native WGL", 406706f2543Smrg NULL 407706f2543Smrg}; 408706f2543Smrg 409706f2543Smrgvoid 410706f2543SmrgglxWinPushNativeProvider(void) 411706f2543Smrg{ 412706f2543Smrg GlxPushProvider(&__glXWGLProvider); 413706f2543Smrg} 414706f2543Smrg 415706f2543Smrg/* ---------------------------------------------------------------------- */ 416706f2543Smrg/* 417706f2543Smrg * Screen functions 418706f2543Smrg */ 419706f2543Smrg 420706f2543Smrgstatic void 421706f2543SmrgglxWinScreenDestroy(__GLXscreen *screen) 422706f2543Smrg{ 423706f2543Smrg GLWIN_DEBUG_MSG("glxWinScreenDestroy(%p)", screen); 424706f2543Smrg __glXScreenDestroy(screen); 425706f2543Smrg free(screen); 426706f2543Smrg} 427706f2543Smrg 428706f2543Smrgstatic int 429706f2543SmrgglxWinScreenSwapInterval(__GLXdrawable *drawable, int interval) 430706f2543Smrg{ 431706f2543Smrg BOOL ret = wglSwapIntervalEXTWrapper(interval); 432706f2543Smrg if (!ret) 433706f2543Smrg { 434706f2543Smrg ErrorF("wglSwapIntervalEXT interval %d failed:%s\n", interval, glxWinErrorMessage()); 435706f2543Smrg } 436706f2543Smrg return ret; 437706f2543Smrg} 438706f2543Smrg 439706f2543Smrg/* 440706f2543Smrg Report the extensions split and formatted to avoid overflowing a line 441706f2543Smrg */ 442706f2543Smrgstatic void 443706f2543SmrgglxLogExtensions(const char *prefix, const char *extensions) 444706f2543Smrg{ 445706f2543Smrg int length = 0; 446706f2543Smrg char *strl; 447706f2543Smrg char *str = strdup(extensions); 448706f2543Smrg 449706f2543Smrg if (str == NULL) 450706f2543Smrg { 451706f2543Smrg ErrorF("glxLogExtensions: xalloc error\n"); 452706f2543Smrg return; 453706f2543Smrg } 454706f2543Smrg 455706f2543Smrg strl = strtok(str, " "); 456706f2543Smrg ErrorF("%s%s", prefix, strl); 457706f2543Smrg length = strlen(prefix) + strlen(strl); 458706f2543Smrg 459706f2543Smrg while (1) 460706f2543Smrg { 461706f2543Smrg strl = strtok(NULL, " "); 462706f2543Smrg if (strl == NULL) break; 463706f2543Smrg 464706f2543Smrg if (length + strlen(strl) + 1 > 120) 465706f2543Smrg { 466706f2543Smrg ErrorF("\n"); 467706f2543Smrg ErrorF("%s",prefix); 468706f2543Smrg length = strlen(prefix); 469706f2543Smrg } 470706f2543Smrg else 471706f2543Smrg { 472706f2543Smrg ErrorF(" "); 473706f2543Smrg length++; 474706f2543Smrg } 475706f2543Smrg 476706f2543Smrg ErrorF("%s", strl); 477706f2543Smrg length = length + strlen(strl); 478706f2543Smrg } 479706f2543Smrg 480706f2543Smrg ErrorF("\n"); 481706f2543Smrg 482706f2543Smrg free(str); 483706f2543Smrg} 484706f2543Smrg 485706f2543Smrg/* This is called by GlxExtensionInit() asking the GLX provider if it can handle the screen... */ 486706f2543Smrgstatic __GLXscreen * 487706f2543SmrgglxWinScreenProbe(ScreenPtr pScreen) 488706f2543Smrg{ 489706f2543Smrg glxWinScreen *screen; 490706f2543Smrg const char *gl_extensions; 491706f2543Smrg const char *wgl_extensions; 492706f2543Smrg HWND hwnd; 493706f2543Smrg HDC hdc; 494706f2543Smrg HGLRC hglrc; 495706f2543Smrg 496706f2543Smrg GLWIN_DEBUG_MSG("glxWinScreenProbe"); 497706f2543Smrg 498706f2543Smrg glxWinInitDebugSettings(); 499706f2543Smrg 500706f2543Smrg if (pScreen == NULL) 501706f2543Smrg return NULL; 502706f2543Smrg 503706f2543Smrg if (!winCheckScreenAiglxIsSupported(pScreen)) 504706f2543Smrg { 505706f2543Smrg LogMessage(X_ERROR,"AIGLX: No native OpenGL in modes with a root window\n"); 506706f2543Smrg return NULL; 507706f2543Smrg } 508706f2543Smrg 509706f2543Smrg screen = calloc(1, sizeof(glxWinScreen)); 510706f2543Smrg 511706f2543Smrg if (NULL == screen) 512706f2543Smrg return NULL; 513706f2543Smrg 514706f2543Smrg /* Wrap RealizeWindow, UnrealizeWindow and CopyWindow on this screen */ 515706f2543Smrg screen->RealizeWindow = pScreen->RealizeWindow; 516706f2543Smrg pScreen->RealizeWindow = glxWinRealizeWindow; 517706f2543Smrg screen->UnrealizeWindow = pScreen->UnrealizeWindow; 518706f2543Smrg pScreen->UnrealizeWindow = glxWinUnrealizeWindow; 519706f2543Smrg screen->CopyWindow = pScreen->CopyWindow; 520706f2543Smrg pScreen->CopyWindow = glxWinCopyWindow; 521706f2543Smrg 522706f2543Smrg /* Dump out some useful information about the native renderer */ 523706f2543Smrg 524706f2543Smrg // create window class 525706f2543Smrg#define WIN_GL_TEST_WINDOW_CLASS "XWinGLTest" 526706f2543Smrg { 527706f2543Smrg static wATOM glTestWndClass = 0; 528706f2543Smrg if (glTestWndClass == 0) 529706f2543Smrg { 530706f2543Smrg WNDCLASSEX wc; 531706f2543Smrg wc.cbSize = sizeof(WNDCLASSEX); 532706f2543Smrg wc.style = CS_HREDRAW | CS_VREDRAW; 533706f2543Smrg wc.lpfnWndProc = DefWindowProc; 534706f2543Smrg wc.cbClsExtra = 0; 535706f2543Smrg wc.cbWndExtra = 0; 536706f2543Smrg wc.hInstance = GetModuleHandle(NULL); 537706f2543Smrg wc.hIcon = 0; 538706f2543Smrg wc.hCursor = 0; 539706f2543Smrg wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 540706f2543Smrg wc.lpszMenuName = NULL; 541706f2543Smrg wc.lpszClassName = WIN_GL_TEST_WINDOW_CLASS; 542706f2543Smrg wc.hIconSm = 0; 543706f2543Smrg RegisterClassEx (&wc); 544706f2543Smrg } 545706f2543Smrg } 546706f2543Smrg 547706f2543Smrg // create an invisible window for a scratch DC 548706f2543Smrg hwnd = CreateWindowExA(0, 549706f2543Smrg WIN_GL_TEST_WINDOW_CLASS, 550706f2543Smrg "XWin GL Renderer Capabilities Test Window", 551706f2543Smrg 0, 0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL); 552706f2543Smrg if (hwnd == NULL) 553706f2543Smrg LogMessage(X_ERROR,"AIGLX: Couldn't create a window for render capabilities testing\n"); 554706f2543Smrg 555706f2543Smrg hdc = GetDC(hwnd); 556706f2543Smrg 557706f2543Smrg // we must set a pixel format before we can create a context, just use the first one... 558706f2543Smrg SetPixelFormat(hdc, 1, NULL); 559706f2543Smrg hglrc = wglCreateContext(hdc); 560706f2543Smrg wglMakeCurrent(hdc, hglrc); 561706f2543Smrg 562706f2543Smrg // initialize wgl extension proc pointers (don't call them before here...) 563706f2543Smrg // (but we need to have a current context for them to be resolvable) 564706f2543Smrg wglResolveExtensionProcs(); 565706f2543Smrg 566706f2543Smrg ErrorF("GL_VERSION: %s\n", glGetStringWrapperNonstatic(GL_VERSION)); 567706f2543Smrg ErrorF("GL_VENDOR: %s\n", glGetStringWrapperNonstatic(GL_VENDOR)); 568706f2543Smrg ErrorF("GL_RENDERER: %s\n", glGetStringWrapperNonstatic(GL_RENDERER)); 569706f2543Smrg gl_extensions = (const char *)glGetStringWrapperNonstatic(GL_EXTENSIONS); 570706f2543Smrg glxLogExtensions("GL_EXTENSIONS: ", gl_extensions); 571706f2543Smrg wgl_extensions = wglGetExtensionsStringARBWrapper(hdc); 572706f2543Smrg if (!wgl_extensions) wgl_extensions = ""; 573706f2543Smrg glxLogExtensions("WGL_EXTENSIONS: ", wgl_extensions); 574706f2543Smrg 575706f2543Smrg // Can you see the problem here? The extensions string is DC specific 576706f2543Smrg // Different DCs for windows on a multimonitor system driven by multiple cards 577706f2543Smrg // might have completely different capabilities. Of course, good luck getting 578706f2543Smrg // those screens to be accelerated in XP and earlier... 579706f2543Smrg 580706f2543Smrg { 581706f2543Smrg // testing facility to not use any WGL extensions 582706f2543Smrg char *envptr = getenv("GLWIN_NO_WGL_EXTENSIONS"); 583706f2543Smrg if ((envptr != NULL) && (atoi(envptr) != 0)) 584706f2543Smrg { 585706f2543Smrg ErrorF("GLWIN_NO_WGL_EXTENSIONS is set, ignoring WGL_EXTENSIONS\n"); 586706f2543Smrg wgl_extensions = ""; 587706f2543Smrg } 588706f2543Smrg } 589706f2543Smrg 590706f2543Smrg { 591706f2543Smrg Bool glx_sgi_make_current_read = FALSE; 592706f2543Smrg 593706f2543Smrg // 594706f2543Smrg // Based on the WGL extensions available, enable various GLX extensions 595706f2543Smrg // XXX: make this table-driven ? 596706f2543Smrg // 597706f2543Smrg memset(screen->glx_enable_bits, 0, __GLX_EXT_BYTES); 598706f2543Smrg 599706f2543Smrg __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_visual_info"); 600706f2543Smrg __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_visual_rating"); 601706f2543Smrg __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_import_context"); 602706f2543Smrg __glXEnableExtension(screen->glx_enable_bits, "GLX_OML_swap_method"); 603706f2543Smrg __glXEnableExtension(screen->glx_enable_bits, "GLX_SGIX_fbconfig"); 604706f2543Smrg 605706f2543Smrg if (strstr(wgl_extensions, "WGL_ARB_make_current_read")) 606706f2543Smrg { 607706f2543Smrg __glXEnableExtension(screen->glx_enable_bits, "GLX_SGI_make_current_read"); 608706f2543Smrg LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_make_current_read\n"); 609706f2543Smrg glx_sgi_make_current_read = TRUE; 610706f2543Smrg } 611706f2543Smrg 612706f2543Smrg if (strstr(gl_extensions, "GL_WIN_swap_hint")) 613706f2543Smrg { 614706f2543Smrg __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_copy_sub_buffer"); 615706f2543Smrg LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n"); 616706f2543Smrg } 617706f2543Smrg 618706f2543Smrg if (strstr(wgl_extensions, "WGL_EXT_swap_control")) 619706f2543Smrg { 620706f2543Smrg __glXEnableExtension(screen->glx_enable_bits, "GLX_SGI_swap_control"); 621706f2543Smrg __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_swap_control"); 622706f2543Smrg LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_swap_control and GLX_MESA_swap_control\n"); 623706f2543Smrg } 624706f2543Smrg 625706f2543Smrg/* // Hmm? screen->texOffset */ 626706f2543Smrg/* if (strstr(wgl_extensions, "WGL_ARB_render_texture")) */ 627706f2543Smrg/* { */ 628706f2543Smrg/* __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_texture_from_pixmap"); */ 629706f2543Smrg/* LogMessage(X_INFO, "AIGLX: GLX_EXT_texture_from_pixmap backed by buffer objects\n"); */ 630706f2543Smrg/* screen->has_WGL_ARB_render_texture = TRUE; */ 631706f2543Smrg/* } */ 632706f2543Smrg 633706f2543Smrg if (strstr(wgl_extensions, "WGL_ARB_pbuffer")) 634706f2543Smrg { 635706f2543Smrg __glXEnableExtension(screen->glx_enable_bits, "GLX_SGIX_pbuffer"); 636706f2543Smrg LogMessage(X_INFO, "AIGLX: enabled GLX_SGIX_pbuffer\n"); 637706f2543Smrg screen->has_WGL_ARB_pbuffer = TRUE; 638706f2543Smrg } 639706f2543Smrg 640706f2543Smrg if (strstr(wgl_extensions, "WGL_ARB_multisample")) 641706f2543Smrg { 642706f2543Smrg __glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_multisample"); 643706f2543Smrg __glXEnableExtension(screen->glx_enable_bits, "GLX_SGIS_multisample"); 644706f2543Smrg LogMessage(X_INFO, "AIGLX: enabled GLX_ARB_multisample and GLX_SGIS_multisample\n"); 645706f2543Smrg screen->has_WGL_ARB_multisample = TRUE; 646706f2543Smrg } 647706f2543Smrg 648706f2543Smrg screen->base.destroy = glxWinScreenDestroy; 649706f2543Smrg screen->base.createContext = glxWinCreateContext; 650706f2543Smrg screen->base.createDrawable = glxWinCreateDrawable; 651706f2543Smrg screen->base.swapInterval = glxWinScreenSwapInterval; 652706f2543Smrg screen->base.pScreen = pScreen; 653706f2543Smrg 654706f2543Smrg if (strstr(wgl_extensions, "WGL_ARB_pixel_format")) 655706f2543Smrg { 656706f2543Smrg glxWinCreateConfigsExt(hdc, screen); 657706f2543Smrg screen->has_WGL_ARB_pixel_format = TRUE; 658706f2543Smrg } 659706f2543Smrg else 660706f2543Smrg { 661706f2543Smrg glxWinCreateConfigs(hdc, screen); 662706f2543Smrg screen->has_WGL_ARB_pixel_format = FALSE; 663706f2543Smrg } 664706f2543Smrg // Initializes screen->base.fbconfigs and screen->base.numFBConfigs 665706f2543Smrg 666706f2543Smrg /* These will be set by __glXScreenInit */ 667706f2543Smrg screen->base.visuals = NULL; 668706f2543Smrg screen->base.numVisuals = 0; 669706f2543Smrg 670706f2543Smrg __glXScreenInit(&screen->base, pScreen); 671706f2543Smrg 672706f2543Smrg // dump out fbConfigs now fbConfigIds and visualIDs have been assigned 673706f2543Smrg fbConfigsDump(screen->base.numFBConfigs, screen->base.fbconfigs); 674706f2543Smrg 675706f2543Smrg // Override the GL extensions string set by __glXScreenInit() 676706f2543Smrg screen->base.GLextensions = strdup(gl_extensions); 677706f2543Smrg 678706f2543Smrg // Generate the GLX extensions string (overrides that set by __glXScreenInit()) 679706f2543Smrg { 680706f2543Smrg unsigned int buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL); 681706f2543Smrg if (buffer_size > 0) 682706f2543Smrg { 683706f2543Smrg free(screen->base.GLXextensions); 684706f2543Smrg 685706f2543Smrg screen->base.GLXextensions = xnfalloc(buffer_size); 686706f2543Smrg __glXGetExtensionString(screen->glx_enable_bits, screen->base.GLXextensions); 687706f2543Smrg } 688706f2543Smrg } 689706f2543Smrg 690706f2543Smrg // 691706f2543Smrg // Override the GLX version (__glXScreenInit() sets it to "1.2") 692706f2543Smrg // if we have all the needed extensions to operate as a higher version 693706f2543Smrg // 694706f2543Smrg // SGIX_fbconfig && SGIX_pbuffer && SGI_make_current_read -> 1.3 695706f2543Smrg // ARB_multisample -> 1.4 696706f2543Smrg // 697706f2543Smrg if (screen->has_WGL_ARB_pbuffer && glx_sgi_make_current_read) 698706f2543Smrg { 699706f2543Smrg if (screen->has_WGL_ARB_multisample) 700706f2543Smrg { 701706f2543Smrg screen->base.GLXmajor = 1; 702706f2543Smrg screen->base.GLXminor = 4; 703706f2543Smrg } 704706f2543Smrg else 705706f2543Smrg { 706706f2543Smrg screen->base.GLXmajor = 1; 707706f2543Smrg screen->base.GLXminor = 3; 708706f2543Smrg } 709706f2543Smrg } 710706f2543Smrg } 711706f2543Smrg LogMessage(X_INFO, "AIGLX: Set GLX version to %d.%d\n", screen->base.GLXmajor, screen->base.GLXminor); 712706f2543Smrg 713706f2543Smrg wglMakeCurrent(NULL, NULL); 714706f2543Smrg wglDeleteContext(hglrc); 715706f2543Smrg ReleaseDC(hwnd, hdc); 716706f2543Smrg DestroyWindow(hwnd); 717706f2543Smrg 718706f2543Smrg return &screen->base; 719706f2543Smrg} 720706f2543Smrg 721706f2543Smrg/* ---------------------------------------------------------------------- */ 722706f2543Smrg/* 723706f2543Smrg * Window functions 724706f2543Smrg */ 725706f2543Smrg 726706f2543Smrgstatic Bool 727706f2543SmrgglxWinRealizeWindow(WindowPtr pWin) 728706f2543Smrg{ 729706f2543Smrg Bool result; 730706f2543Smrg ScreenPtr pScreen = pWin->drawable.pScreen; 731706f2543Smrg glxWinScreen *screenPriv = (glxWinScreen *) glxGetScreen(pScreen); 732706f2543Smrg 733706f2543Smrg GLWIN_DEBUG_MSG("glxWinRealizeWindow"); 734706f2543Smrg 735706f2543Smrg /* Allow the window to be created (RootlessRealizeWindow is inside our wrap) */ 736706f2543Smrg pScreen->RealizeWindow = screenPriv->RealizeWindow; 737706f2543Smrg result = pScreen->RealizeWindow(pWin); 738706f2543Smrg pScreen->RealizeWindow = glxWinRealizeWindow; 739706f2543Smrg 740706f2543Smrg return result; 741706f2543Smrg} 742706f2543Smrg 743706f2543Smrg 744706f2543Smrgstatic void 745706f2543SmrgglxWinCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc) 746706f2543Smrg{ 747706f2543Smrg __GLXWinDrawable *pGlxDraw; 748706f2543Smrg ScreenPtr pScreen = pWindow->drawable.pScreen; 749706f2543Smrg glxWinScreen *screenPriv = (glxWinScreen *) glxGetScreen(pScreen); 750706f2543Smrg 751706f2543Smrg GLWIN_TRACE_MSG("glxWinCopyWindow pWindow %p", pWindow); 752706f2543Smrg 753706f2543Smrg dixLookupResourceByType((pointer) &pGlxDraw, pWindow->drawable.id, __glXDrawableRes, 754706f2543Smrg NullClient, DixUnknownAccess); 755706f2543Smrg 756706f2543Smrg 757706f2543Smrg /* 758706f2543Smrg Discard any CopyWindow requests if a GL drawing context is pointing at the window 759706f2543Smrg 760706f2543Smrg For regions which are being drawn by GL, the shadow framebuffer doesn't have the 761706f2543Smrg correct bits, so we wish to avoid shadow framebuffer damage occuring, which will 762706f2543Smrg cause those incorrect bits to be transferred to the display.... 763706f2543Smrg */ 764706f2543Smrg if (pGlxDraw && pGlxDraw->drawContext) 765706f2543Smrg { 766706f2543Smrg GLWIN_DEBUG_MSG("glxWinCopyWindow: discarding"); 767706f2543Smrg return; 768706f2543Smrg } 769706f2543Smrg 770706f2543Smrg GLWIN_DEBUG_MSG("glxWinCopyWindow - passing to hw layer"); 771706f2543Smrg 772706f2543Smrg pScreen->CopyWindow = screenPriv->CopyWindow; 773706f2543Smrg pScreen->CopyWindow(pWindow, ptOldOrg, prgnSrc); 774706f2543Smrg pScreen->CopyWindow = glxWinCopyWindow; 775706f2543Smrg} 776706f2543Smrg 777706f2543Smrgstatic Bool 778706f2543SmrgglxWinUnrealizeWindow(WindowPtr pWin) 779706f2543Smrg{ 780706f2543Smrg Bool result; 781706f2543Smrg ScreenPtr pScreen = pWin->drawable.pScreen; 782706f2543Smrg glxWinScreen *screenPriv = (glxWinScreen *)glxGetScreen(pScreen); 783706f2543Smrg 784706f2543Smrg GLWIN_DEBUG_MSG("glxWinUnrealizeWindow"); 785706f2543Smrg 786706f2543Smrg pScreen->UnrealizeWindow = screenPriv->UnrealizeWindow; 787706f2543Smrg result = pScreen->UnrealizeWindow(pWin); 788706f2543Smrg pScreen->UnrealizeWindow = glxWinUnrealizeWindow; 789706f2543Smrg 790706f2543Smrg return result; 791706f2543Smrg} 792706f2543Smrg 793706f2543Smrg/* ---------------------------------------------------------------------- */ 794706f2543Smrg/* 795706f2543Smrg * Drawable functions 796706f2543Smrg */ 797706f2543Smrg 798706f2543Smrgstatic GLboolean 799706f2543SmrgglxWinDrawableSwapBuffers(ClientPtr client, __GLXdrawable *base) 800706f2543Smrg{ 801706f2543Smrg HDC dc; 802706f2543Smrg HWND hwnd; 803706f2543Smrg BOOL ret; 804706f2543Smrg __GLXWinDrawable *draw = (__GLXWinDrawable *)base; 805706f2543Smrg 806706f2543Smrg /* Swap buffers on the last active context for drawing on the drawable */ 807706f2543Smrg if (draw->drawContext == NULL) 808706f2543Smrg { 809706f2543Smrg GLWIN_TRACE_MSG("glxWinSwapBuffers - no context for drawable"); 810706f2543Smrg return GL_FALSE; 811706f2543Smrg } 812706f2543Smrg 813706f2543Smrg GLWIN_TRACE_MSG("glxWinSwapBuffers on drawable %p, last context %p (native ctx %p)", base, draw->drawContext, draw->drawContext->ctx); 814706f2543Smrg 815706f2543Smrg /* 816706f2543Smrg draw->drawContext->base.drawPriv will not be set if the context is not current anymore, 817706f2543Smrg but if it is, it should point to this drawable.... 818706f2543Smrg */ 819706f2543Smrg assert((draw->drawContext->base.drawPriv == NULL) || (draw->drawContext->base.drawPriv == base)); 820706f2543Smrg 821706f2543Smrg dc = glxWinMakeDC(draw->drawContext, draw, &dc, &hwnd); 822706f2543Smrg if (dc == NULL) 823706f2543Smrg return GL_FALSE; 824706f2543Smrg 825706f2543Smrg ret = wglSwapLayerBuffers(dc, WGL_SWAP_MAIN_PLANE); 826706f2543Smrg 827706f2543Smrg glxWinReleaseDC(hwnd, dc, draw); 828706f2543Smrg 829706f2543Smrg if (!ret) 830706f2543Smrg { 831706f2543Smrg ErrorF("wglSwapBuffers failed: %s\n", glxWinErrorMessage()); 832706f2543Smrg return GL_FALSE; 833706f2543Smrg } 834706f2543Smrg 835706f2543Smrg return GL_TRUE; 836706f2543Smrg} 837706f2543Smrg 838706f2543Smrgstatic void 839706f2543SmrgglxWinDrawableCopySubBuffer(__GLXdrawable *drawable, 840706f2543Smrg int x, int y, int w, int h) 841706f2543Smrg{ 842706f2543Smrg glAddSwapHintRectWINWrapperNonstatic(x, y, w, h); 843706f2543Smrg glxWinDrawableSwapBuffers(NULL, drawable); 844706f2543Smrg} 845706f2543Smrg 846706f2543Smrgstatic void 847706f2543SmrgglxWinDrawableDestroy(__GLXdrawable *base) 848706f2543Smrg{ 849706f2543Smrg __GLXWinDrawable *glxPriv = (__GLXWinDrawable *)base; 850706f2543Smrg 851706f2543Smrg if (glxPriv->drawContext && (__glXLastContext == &((glxPriv->drawContext)->base))) 852706f2543Smrg { 853706f2543Smrg // if this context is current and has unflushed commands, say we have flushed them 854706f2543Smrg // (don't actually flush them, the window is going away anyhow, and an implict flush occurs 855706f2543Smrg // on the next context change) 856706f2543Smrg // (GLX core considers it an error when we try to select a new current context if the old one 857706f2543Smrg // has unflushed commands, but the window has disappeared..) 858706f2543Smrg __GLX_NOTE_FLUSHED_CMDS(__glXLastContext); 859706f2543Smrg __glXLastContext = NULL; 860706f2543Smrg } 861706f2543Smrg 862706f2543Smrg if (glxPriv->hPbuffer) 863706f2543Smrg if (!wglDestroyPbufferARBWrapper(glxPriv->hPbuffer)) 864706f2543Smrg { 865706f2543Smrg ErrorF("wglDestroyPbufferARB failed: %s\n", glxWinErrorMessage()); 866706f2543Smrg } 867706f2543Smrg 868706f2543Smrg if (glxPriv->dibDC) 869706f2543Smrg { 870706f2543Smrg // restore the default DIB 871706f2543Smrg SelectObject(glxPriv->dibDC, glxPriv->hOldDIB); 872706f2543Smrg 873706f2543Smrg if (!DeleteDC(glxPriv->dibDC)) 874706f2543Smrg { 875706f2543Smrg ErrorF("DeleteDC failed: %s\n", glxWinErrorMessage()); 876706f2543Smrg } 877706f2543Smrg } 878706f2543Smrg 879706f2543Smrg if (glxPriv->hDIB) 880706f2543Smrg { 881706f2543Smrg if (!DeleteObject(glxPriv->hDIB)) 882706f2543Smrg { 883706f2543Smrg ErrorF("DeleteObject failed: %s\n", glxWinErrorMessage()); 884706f2543Smrg } 885706f2543Smrg 886706f2543Smrg ((PixmapPtr)glxPriv->base.pDraw)->devPrivate.ptr = glxPriv->pOldBits; 887706f2543Smrg } 888706f2543Smrg 889706f2543Smrg GLWIN_DEBUG_MSG("glxWinDestroyDrawable"); 890706f2543Smrg free(glxPriv); 891706f2543Smrg} 892706f2543Smrg 893706f2543Smrgstatic __GLXdrawable * 894706f2543SmrgglxWinCreateDrawable(ClientPtr client, 895706f2543Smrg __GLXscreen *screen, 896706f2543Smrg DrawablePtr pDraw, 897706f2543Smrg XID drawId, 898706f2543Smrg int type, 899706f2543Smrg XID glxDrawId, 900706f2543Smrg __GLXconfig *conf) 901706f2543Smrg{ 902706f2543Smrg __GLXWinDrawable *glxPriv; 903706f2543Smrg 904706f2543Smrg glxPriv = malloc(sizeof *glxPriv); 905706f2543Smrg 906706f2543Smrg if (glxPriv == NULL) 907706f2543Smrg return NULL; 908706f2543Smrg 909706f2543Smrg memset(glxPriv, 0, sizeof *glxPriv); 910706f2543Smrg 911706f2543Smrg if(!__glXDrawableInit(&glxPriv->base, screen, pDraw, type, glxDrawId, conf)) { 912706f2543Smrg free(glxPriv); 913706f2543Smrg return NULL; 914706f2543Smrg } 915706f2543Smrg 916706f2543Smrg glxPriv->base.destroy = glxWinDrawableDestroy; 917706f2543Smrg glxPriv->base.swapBuffers = glxWinDrawableSwapBuffers; 918706f2543Smrg glxPriv->base.copySubBuffer = glxWinDrawableCopySubBuffer; 919706f2543Smrg // glxPriv->base.waitX what are these for? 920706f2543Smrg // glxPriv->base.waitGL 921706f2543Smrg 922706f2543Smrg GLWIN_DEBUG_MSG("glxWinCreateDrawable %p", glxPriv); 923706f2543Smrg 924706f2543Smrg return &glxPriv->base; 925706f2543Smrg} 926706f2543Smrg 927706f2543Smrg/* ---------------------------------------------------------------------- */ 928706f2543Smrg/* 929706f2543Smrg * Texture functions 930706f2543Smrg */ 931706f2543Smrg 932706f2543Smrgstatic 933706f2543Smrgint glxWinBindTexImage(__GLXcontext *baseContext, 934706f2543Smrg int buffer, 935706f2543Smrg __GLXdrawable *pixmap) 936706f2543Smrg{ 937706f2543Smrg ErrorF("glxWinBindTexImage: not implemented\n"); 938706f2543Smrg return FALSE; 939706f2543Smrg} 940706f2543Smrg 941706f2543Smrgstatic 942706f2543Smrgint glxWinReleaseTexImage(__GLXcontext *baseContext, 943706f2543Smrg int buffer, 944706f2543Smrg __GLXdrawable *pixmap) 945706f2543Smrg{ 946706f2543Smrg ErrorF(" glxWinReleaseTexImage: not implemented\n"); 947706f2543Smrg return FALSE; 948706f2543Smrg} 949706f2543Smrg 950706f2543Smrg/* ---------------------------------------------------------------------- */ 951706f2543Smrg/* 952706f2543Smrg * Lazy update context implementation 953706f2543Smrg * 954706f2543Smrg * WGL contexts are created for a specific HDC, so we cannot create the WGL 955706f2543Smrg * context in glxWinCreateContext(), we must defer creation until the context 956706f2543Smrg * is actually used on a specifc drawable which is connected to a native window, 957706f2543Smrg * pbuffer or DIB 958706f2543Smrg * 959706f2543Smrg * The WGL context may be used on other, compatible HDCs, so we don't need to 960706f2543Smrg * recreate it for every new native window 961706f2543Smrg * 962706f2543Smrg * XXX: I wonder why we can't create the WGL context on the screen HDC ? 963706f2543Smrg * Basically we assume all HDCs are compatible at the moment: if they are not 964706f2543Smrg * we are in a muddle, there was some code in the old implementation to attempt 965706f2543Smrg * to transparently migrate a context to a new DC by copying state and sharing 966706f2543Smrg * lists with the old one... 967706f2543Smrg */ 968706f2543Smrg 969706f2543Smrgstatic void 970706f2543SmrgglxWinSetPixelFormat(__GLXWinContext *gc, HDC hdc, int bppOverride, int drawableTypeOverride) 971706f2543Smrg{ 972706f2543Smrg __GLXscreen *screen = gc->base.pGlxScreen; 973706f2543Smrg glxWinScreen *winScreen = (glxWinScreen *)screen; 974706f2543Smrg 975706f2543Smrg __GLXconfig *config = gc->base.config; 976706f2543Smrg GLXWinConfig *winConfig = (GLXWinConfig *)config; 977706f2543Smrg 978706f2543Smrg GLWIN_DEBUG_MSG("glxWinSetPixelFormat: pixelFormatIndex %d", winConfig->pixelFormatIndex); 979706f2543Smrg 980706f2543Smrg /* 981706f2543Smrg Normally, we can just use the the pixelFormatIndex corresponding 982706f2543Smrg to the fbconfig which has been specified by the client 983706f2543Smrg */ 984706f2543Smrg 985706f2543Smrg if (!((bppOverride && (bppOverride != (config->redBits + config->greenBits + config->blueBits) )) 986706f2543Smrg || ((config->drawableType & drawableTypeOverride) == 0))) 987706f2543Smrg { 988706f2543Smrg if (!SetPixelFormat(hdc, winConfig->pixelFormatIndex, NULL)) 989706f2543Smrg { 990706f2543Smrg ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage()); 991706f2543Smrg return; 992706f2543Smrg } 993706f2543Smrg 994706f2543Smrg return; 995706f2543Smrg } 996706f2543Smrg 997706f2543Smrg /* 998706f2543Smrg However, in certain special cases this pixel format will be incompatible with the 999706f2543Smrg use we are going to put it to, so we need to re-evaluate the pixel format to use: 1000706f2543Smrg 1001706f2543Smrg 1) When PFD_DRAW_TO_BITMAP is set, ChoosePixelFormat() always returns a format with 1002706f2543Smrg the cColorBits we asked for, so we need to ensure it matches the bpp of the bitmap 1003706f2543Smrg 1004706f2543Smrg 2) Applications may assume that visuals selected with glXChooseVisual() work with 1005706f2543Smrg pixmap drawables (there is no attribute to explicitly query for pixmap drawable 1006706f2543Smrg support as there is for glXChooseFBConfig()) 1007706f2543Smrg (it's arguable this is an error in the application, but we try to make it work) 1008706f2543Smrg 1009706f2543Smrg pixmap rendering is always slow for us, so we don't want to choose those visuals 1010706f2543Smrg by default, but if the actual drawable type we're trying to select the context 1011706f2543Smrg on (drawableTypeOverride) isn't supported by the selected fbConfig, reconsider 1012706f2543Smrg and see if we can find a suitable one... 1013706f2543Smrg */ 1014706f2543Smrg ErrorF("glxWinSetPixelFormat: having second thoughts: cColorbits %d, bppOveride %d; config->drawableType %d, drawableTypeOverride %d\n", 1015706f2543Smrg (config->redBits + config->greenBits + config->blueBits), bppOverride, config->drawableType, drawableTypeOverride); 1016706f2543Smrg 1017706f2543Smrg if (!winScreen->has_WGL_ARB_pixel_format) 1018706f2543Smrg { 1019706f2543Smrg PIXELFORMATDESCRIPTOR pfd; 1020706f2543Smrg int pixelFormat; 1021706f2543Smrg 1022706f2543Smrg /* convert fbConfig to PFD */ 1023706f2543Smrg if (fbConfigToPixelFormat(gc->base.config, &pfd, drawableTypeOverride)) 1024706f2543Smrg { 1025706f2543Smrg ErrorF("glxWinSetPixelFormat: fbConfigToPixelFormat failed\n"); 1026706f2543Smrg return; 1027706f2543Smrg } 1028706f2543Smrg 1029706f2543Smrg if (glxWinDebugSettings.dumpPFD) 1030706f2543Smrg pfdOut(&pfd); 1031706f2543Smrg 1032706f2543Smrg if (bppOverride) 1033706f2543Smrg { 1034706f2543Smrg GLWIN_DEBUG_MSG("glxWinSetPixelFormat: Forcing bpp from %d to %d\n", pfd.cColorBits, bppOverride); 1035706f2543Smrg pfd.cColorBits = bppOverride; 1036706f2543Smrg } 1037706f2543Smrg 1038706f2543Smrg pixelFormat = ChoosePixelFormat(hdc, &pfd); 1039706f2543Smrg if (pixelFormat == 0) 1040706f2543Smrg { 1041706f2543Smrg ErrorF("ChoosePixelFormat error: %s\n", glxWinErrorMessage()); 1042706f2543Smrg return; 1043706f2543Smrg } 1044706f2543Smrg 1045706f2543Smrg GLWIN_DEBUG_MSG("ChoosePixelFormat: chose pixelFormatIndex %d", pixelFormat); 1046706f2543Smrg ErrorF("ChoosePixelFormat: chose pixelFormatIndex %d (rather than %d as originally planned)\n", pixelFormat, winConfig->pixelFormatIndex); 1047706f2543Smrg 1048706f2543Smrg if (!SetPixelFormat(hdc, pixelFormat, &pfd)) 1049706f2543Smrg { 1050706f2543Smrg ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage()); 1051706f2543Smrg return; 1052706f2543Smrg } 1053706f2543Smrg } 1054706f2543Smrg else 1055706f2543Smrg { 1056706f2543Smrg int pixelFormat = fbConfigToPixelFormatIndex(hdc, gc->base.config, drawableTypeOverride, winScreen); 1057706f2543Smrg if (pixelFormat == 0) 1058706f2543Smrg { 1059706f2543Smrg ErrorF("wglChoosePixelFormat error: %s\n", glxWinErrorMessage()); 1060706f2543Smrg return; 1061706f2543Smrg } 1062706f2543Smrg 1063706f2543Smrg GLWIN_DEBUG_MSG("wglChoosePixelFormat: chose pixelFormatIndex %d", pixelFormat); 1064706f2543Smrg ErrorF("wglChoosePixelFormat: chose pixelFormatIndex %d (rather than %d as originally planned)\n", pixelFormat, winConfig->pixelFormatIndex); 1065706f2543Smrg 1066706f2543Smrg if (!SetPixelFormat(hdc, pixelFormat, NULL)) 1067706f2543Smrg { 1068706f2543Smrg ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage()); 1069706f2543Smrg return; 1070706f2543Smrg } 1071706f2543Smrg } 1072706f2543Smrg} 1073706f2543Smrg 1074706f2543Smrgstatic HDC 1075706f2543SmrgglxWinMakeDC(__GLXWinContext *gc, __GLXWinDrawable *draw, HDC *hdc, HWND *hwnd) 1076706f2543Smrg{ 1077706f2543Smrg *hdc = NULL; 1078706f2543Smrg *hwnd = NULL; 1079706f2543Smrg 1080706f2543Smrg if (draw == NULL) 1081706f2543Smrg { 1082706f2543Smrg GLWIN_TRACE_MSG("No drawable for context %p (native ctx %p)", gc, gc->ctx); 1083706f2543Smrg return NULL; 1084706f2543Smrg } 1085706f2543Smrg 1086706f2543Smrg switch (draw->base.type) 1087706f2543Smrg { 1088706f2543Smrg case GLX_DRAWABLE_WINDOW: 1089706f2543Smrg { 1090706f2543Smrg WindowPtr pWin; 1091706f2543Smrg 1092706f2543Smrg pWin = (WindowPtr) draw->base.pDraw; 1093706f2543Smrg if (pWin == NULL) 1094706f2543Smrg { 1095706f2543Smrg GLWIN_TRACE_MSG("for drawable %p, no WindowPtr", pWin); 1096706f2543Smrg return NULL; 1097706f2543Smrg } 1098706f2543Smrg 1099706f2543Smrg *hwnd = winGetWindowInfo(pWin); 1100706f2543Smrg 1101706f2543Smrg if (*hwnd == NULL) 1102706f2543Smrg { 1103706f2543Smrg ErrorF("No HWND error: %s\n", glxWinErrorMessage()); 1104706f2543Smrg return NULL; 1105706f2543Smrg } 1106706f2543Smrg 1107706f2543Smrg *hdc = GetDC(*hwnd); 1108706f2543Smrg 1109706f2543Smrg if (*hdc == NULL) 1110706f2543Smrg ErrorF("GetDC error: %s\n", glxWinErrorMessage()); 1111706f2543Smrg 1112706f2543Smrg /* Check if the hwnd has changed... */ 1113706f2543Smrg if (*hwnd != gc->hwnd) 1114706f2543Smrg { 1115706f2543Smrg if (glxWinDebugSettings.enableTrace) 1116706f2543Smrg GLWIN_DEBUG_HWND(*hwnd); 1117706f2543Smrg 1118706f2543Smrg GLWIN_TRACE_MSG("for context %p (native ctx %p), hWnd changed from %p to %p", gc, gc->ctx, gc->hwnd, *hwnd); 1119706f2543Smrg gc->hwnd = *hwnd; 1120706f2543Smrg 1121706f2543Smrg /* We must select a pixelformat, but SetPixelFormat can only be called once for a window... */ 1122706f2543Smrg glxWinSetPixelFormat(gc, *hdc, 0, GLX_WINDOW_BIT); 1123706f2543Smrg } 1124706f2543Smrg } 1125706f2543Smrg break; 1126706f2543Smrg 1127706f2543Smrg case GLX_DRAWABLE_PBUFFER: 1128706f2543Smrg { 1129706f2543Smrg *hdc = wglGetPbufferDCARBWrapper(draw->hPbuffer); 1130706f2543Smrg 1131706f2543Smrg if (*hdc == NULL) 1132706f2543Smrg ErrorF("GetDC (pbuffer) error: %s\n", glxWinErrorMessage()); 1133706f2543Smrg } 1134706f2543Smrg break; 1135706f2543Smrg 1136706f2543Smrg case GLX_DRAWABLE_PIXMAP: 1137706f2543Smrg { 1138706f2543Smrg *hdc = draw->dibDC; 1139706f2543Smrg } 1140706f2543Smrg break; 1141706f2543Smrg 1142706f2543Smrg default: 1143706f2543Smrg { 1144706f2543Smrg ErrorF("glxWinMakeDC: tried to makeDC for unhandled drawable type %d\n", draw->base.type); 1145706f2543Smrg } 1146706f2543Smrg } 1147706f2543Smrg 1148706f2543Smrg if (glxWinDebugSettings.dumpDC) 1149706f2543Smrg GLWIN_DEBUG_MSG("Got HDC %p", *hdc); 1150706f2543Smrg 1151706f2543Smrg return *hdc; 1152706f2543Smrg} 1153706f2543Smrg 1154706f2543Smrgstatic void 1155706f2543SmrgglxWinReleaseDC(HWND hwnd, HDC hdc,__GLXWinDrawable *draw) 1156706f2543Smrg{ 1157706f2543Smrg switch (draw->base.type) 1158706f2543Smrg { 1159706f2543Smrg case GLX_DRAWABLE_WINDOW: 1160706f2543Smrg { 1161706f2543Smrg ReleaseDC(hwnd, hdc); 1162706f2543Smrg } 1163706f2543Smrg break; 1164706f2543Smrg 1165706f2543Smrg case GLX_DRAWABLE_PBUFFER: 1166706f2543Smrg { 1167706f2543Smrg if (!wglReleasePbufferDCARBWrapper(draw->hPbuffer, hdc)) 1168706f2543Smrg { 1169706f2543Smrg ErrorF("wglReleasePbufferDCARB error: %s\n", glxWinErrorMessage()); 1170706f2543Smrg } 1171706f2543Smrg } 1172706f2543Smrg break; 1173706f2543Smrg 1174706f2543Smrg case GLX_DRAWABLE_PIXMAP: 1175706f2543Smrg { 1176706f2543Smrg // don't release DC, the memory DC lives as long as the bitmap 1177706f2543Smrg 1178706f2543Smrg // We must ensure that all GDI drawing into the bitmap has completed 1179706f2543Smrg // in case we subsequently access the bits from it 1180706f2543Smrg GdiFlush(); 1181706f2543Smrg } 1182706f2543Smrg break; 1183706f2543Smrg 1184706f2543Smrg default: 1185706f2543Smrg { 1186706f2543Smrg ErrorF("glxWinReleaseDC: tried to releaseDC for unhandled drawable type %d\n", draw->base.type); 1187706f2543Smrg } 1188706f2543Smrg } 1189706f2543Smrg} 1190706f2543Smrg 1191706f2543Smrgstatic void 1192706f2543SmrgglxWinDeferredCreateContext(__GLXWinContext *gc, __GLXWinDrawable *draw) 1193706f2543Smrg{ 1194706f2543Smrg HDC dc; 1195706f2543Smrg HWND hwnd; 1196706f2543Smrg GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: attach context %p to drawable %p", gc, draw); 1197706f2543Smrg 1198706f2543Smrg switch (draw->base.type) 1199706f2543Smrg { 1200706f2543Smrg case GLX_DRAWABLE_WINDOW: 1201706f2543Smrg { 1202706f2543Smrg WindowPtr pWin = (WindowPtr) draw->base.pDraw; 1203706f2543Smrg 1204706f2543Smrg if (!(gc->base.config->drawableType & GLX_WINDOW_BIT)) 1205706f2543Smrg { 1206706f2543Smrg ErrorF("glxWinDeferredCreateContext: tried to attach a context whose fbConfig doesn't have drawableType GLX_WINDOW_BIT to a GLX_DRAWABLE_WINDOW drawable\n"); 1207706f2543Smrg } 1208706f2543Smrg 1209706f2543Smrg if (pWin == NULL) 1210706f2543Smrg { 1211706f2543Smrg GLWIN_DEBUG_MSG("Deferring until X window is created"); 1212706f2543Smrg return; 1213706f2543Smrg } 1214706f2543Smrg 1215706f2543Smrg GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: pWin %p", pWin); 1216706f2543Smrg 1217706f2543Smrg if (winGetWindowInfo(pWin) == NULL) 1218706f2543Smrg { 1219706f2543Smrg GLWIN_DEBUG_MSG("Deferring until native window is created"); 1220706f2543Smrg return; 1221706f2543Smrg } 1222706f2543Smrg } 1223706f2543Smrg break; 1224706f2543Smrg 1225706f2543Smrg case GLX_DRAWABLE_PBUFFER: 1226706f2543Smrg { 1227706f2543Smrg if (draw->hPbuffer == NULL) 1228706f2543Smrg { 1229706f2543Smrg __GLXscreen *screen; 1230706f2543Smrg glxWinScreen *winScreen; 1231706f2543Smrg int pixelFormat; 1232706f2543Smrg // XXX: which DC are supposed to use??? 1233706f2543Smrg HDC screenDC = GetDC(NULL); 1234706f2543Smrg 1235706f2543Smrg if (!(gc->base.config->drawableType & GLX_PBUFFER_BIT)) 1236706f2543Smrg { 1237706f2543Smrg ErrorF("glxWinDeferredCreateContext: tried to attach a context whose fbConfig doesn't have drawableType GLX_PBUFFER_BIT to a GLX_DRAWABLE_PBUFFER drawable\n"); 1238706f2543Smrg } 1239706f2543Smrg 1240706f2543Smrg screen = gc->base.pGlxScreen; 1241706f2543Smrg winScreen = (glxWinScreen *)screen; 1242706f2543Smrg 1243706f2543Smrg pixelFormat = fbConfigToPixelFormatIndex(screenDC, gc->base.config, GLX_DRAWABLE_PBUFFER, winScreen); 1244706f2543Smrg if (pixelFormat == 0) 1245706f2543Smrg { 1246706f2543Smrg ErrorF("wglChoosePixelFormat error: %s\n", glxWinErrorMessage()); 1247706f2543Smrg return; 1248706f2543Smrg } 1249706f2543Smrg 1250706f2543Smrg draw->hPbuffer = wglCreatePbufferARBWrapper(screenDC, pixelFormat, draw->base.pDraw->width, draw->base.pDraw->height, NULL); 1251706f2543Smrg ReleaseDC(NULL, screenDC); 1252706f2543Smrg 1253706f2543Smrg if (draw->hPbuffer == NULL) 1254706f2543Smrg { 1255706f2543Smrg ErrorF("wglCreatePbufferARBWrapper error: %s\n", glxWinErrorMessage()); 1256706f2543Smrg return; 1257706f2543Smrg } 1258706f2543Smrg 1259706f2543Smrg GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: pBuffer %p created for drawable %p", draw->hPbuffer, draw); 1260706f2543Smrg } 1261706f2543Smrg } 1262706f2543Smrg break; 1263706f2543Smrg 1264706f2543Smrg case GLX_DRAWABLE_PIXMAP: 1265706f2543Smrg { 1266706f2543Smrg if (draw->dibDC == NULL) 1267706f2543Smrg { 1268706f2543Smrg BITMAPINFOHEADER bmpHeader; 1269706f2543Smrg void *pBits; 1270706f2543Smrg 1271706f2543Smrg memset (&bmpHeader, 0, sizeof(BITMAPINFOHEADER)); 1272706f2543Smrg bmpHeader.biSize = sizeof(BITMAPINFOHEADER); 1273706f2543Smrg bmpHeader.biWidth = draw->base.pDraw->width; 1274706f2543Smrg bmpHeader.biHeight = draw->base.pDraw->height; 1275706f2543Smrg bmpHeader.biPlanes = 1; 1276706f2543Smrg bmpHeader.biBitCount = draw->base.pDraw->bitsPerPixel; 1277706f2543Smrg bmpHeader.biCompression = BI_RGB; 1278706f2543Smrg 1279706f2543Smrg if (!(gc->base.config->drawableType & GLX_PIXMAP_BIT)) 1280706f2543Smrg { 1281706f2543Smrg ErrorF("glxWinDeferredCreateContext: tried to attach a context whose fbConfig doesn't have drawableType GLX_PIXMAP_BIT to a GLX_DRAWABLE_PIXMAP drawable\n"); 1282706f2543Smrg } 1283706f2543Smrg 1284706f2543Smrg draw->dibDC = CreateCompatibleDC(NULL); 1285706f2543Smrg if (draw->dibDC == NULL) 1286706f2543Smrg { 1287706f2543Smrg ErrorF("CreateCompatibleDC error: %s\n", glxWinErrorMessage()); 1288706f2543Smrg return; 1289706f2543Smrg } 1290706f2543Smrg 1291706f2543Smrg draw->hDIB = CreateDIBSection(draw->dibDC, (BITMAPINFO *)&bmpHeader, DIB_RGB_COLORS, &pBits, 0, 0); 1292706f2543Smrg if (draw->dibDC == NULL) 1293706f2543Smrg { 1294706f2543Smrg ErrorF("CreateDIBSection error: %s\n", glxWinErrorMessage()); 1295706f2543Smrg return; 1296706f2543Smrg } 1297706f2543Smrg 1298706f2543Smrg // XXX: CreateDIBSection insists on allocating the bitmap memory for us, so we're going to 1299706f2543Smrg // need some jiggery pokery to point the underlying X Drawable's bitmap at the same set of bits 1300706f2543Smrg // so that they can be read with XGetImage as well as glReadPixels, assuming the formats are 1301706f2543Smrg // even compatible ... 1302706f2543Smrg draw->pOldBits = ((PixmapPtr)draw->base.pDraw)->devPrivate.ptr; 1303706f2543Smrg ((PixmapPtr)draw->base.pDraw)->devPrivate.ptr = pBits; 1304706f2543Smrg 1305706f2543Smrg // Select the DIB into the DC 1306706f2543Smrg draw->hOldDIB = SelectObject(draw->dibDC, draw->hDIB); 1307706f2543Smrg if (!draw->hOldDIB) 1308706f2543Smrg { 1309706f2543Smrg ErrorF("SelectObject error: %s\n", glxWinErrorMessage()); 1310706f2543Smrg } 1311706f2543Smrg 1312706f2543Smrg // Set the pixel format of the bitmap 1313706f2543Smrg glxWinSetPixelFormat(gc, draw->dibDC, draw->base.pDraw->bitsPerPixel, GLX_PIXMAP_BIT); 1314706f2543Smrg 1315706f2543Smrg GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: DIB bitmap %p created for drawable %p", draw->hDIB, draw); 1316706f2543Smrg } 1317706f2543Smrg } 1318706f2543Smrg break; 1319706f2543Smrg 1320706f2543Smrg default: 1321706f2543Smrg { 1322706f2543Smrg ErrorF("glxWinDeferredCreateContext: tried to attach unhandled drawable type %d\n", draw->base.type); 1323706f2543Smrg return; 1324706f2543Smrg } 1325706f2543Smrg } 1326706f2543Smrg 1327706f2543Smrg dc = glxWinMakeDC(gc, draw, &dc, &hwnd); 1328706f2543Smrg gc->ctx = wglCreateContext(dc); 1329706f2543Smrg glxWinReleaseDC(hwnd, dc, draw); 1330706f2543Smrg 1331706f2543Smrg if (gc->ctx == NULL) 1332706f2543Smrg { 1333706f2543Smrg ErrorF("wglCreateContext error: %s\n", glxWinErrorMessage()); 1334706f2543Smrg return; 1335706f2543Smrg } 1336706f2543Smrg 1337706f2543Smrg GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: attached context %p to native context %p drawable %p", gc, gc->ctx, draw); 1338706f2543Smrg 1339706f2543Smrg // if the native context was created successfully, shareLists if needed 1340706f2543Smrg if (gc->ctx && gc->shareContext) 1341706f2543Smrg { 1342706f2543Smrg GLWIN_DEBUG_MSG("glxWinCreateContextReal shareLists with context %p (native ctx %p)", gc->shareContext, gc->shareContext->ctx); 1343706f2543Smrg 1344706f2543Smrg if (!wglShareLists(gc->shareContext->ctx, gc->ctx)) 1345706f2543Smrg { 1346706f2543Smrg ErrorF("wglShareLists error: %s\n", glxWinErrorMessage()); 1347706f2543Smrg } 1348706f2543Smrg } 1349706f2543Smrg} 1350706f2543Smrg 1351706f2543Smrg/* ---------------------------------------------------------------------- */ 1352706f2543Smrg/* 1353706f2543Smrg * Context functions 1354706f2543Smrg */ 1355706f2543Smrg 1356706f2543Smrg 1357706f2543Smrg/* Context manipulation routines should return TRUE on success, FALSE on failure */ 1358706f2543Smrgstatic int 1359706f2543SmrgglxWinContextMakeCurrent(__GLXcontext *base) 1360706f2543Smrg{ 1361706f2543Smrg __GLXWinContext *gc = (__GLXWinContext *)base; 1362706f2543Smrg BOOL ret; 1363706f2543Smrg HDC drawDC; 1364706f2543Smrg HDC readDC = NULL; 1365706f2543Smrg __GLXdrawable *drawPriv; 1366706f2543Smrg __GLXdrawable *readPriv = NULL; 1367706f2543Smrg HWND hDrawWnd; 1368706f2543Smrg HWND hReadWnd; 1369706f2543Smrg 1370706f2543Smrg GLWIN_TRACE_MSG("glxWinContextMakeCurrent context %p (native ctx %p)", gc, gc->ctx); 1371706f2543Smrg glWinCallDelta(); 1372706f2543Smrg 1373706f2543Smrg /* Keep a note of the last active context in the drawable */ 1374706f2543Smrg drawPriv = gc->base.drawPriv; 1375706f2543Smrg ((__GLXWinDrawable *)drawPriv)->drawContext = gc; 1376706f2543Smrg 1377706f2543Smrg if (gc->ctx == NULL) 1378706f2543Smrg { 1379706f2543Smrg glxWinDeferredCreateContext(gc, (__GLXWinDrawable *)drawPriv); 1380706f2543Smrg } 1381706f2543Smrg 1382706f2543Smrg if (gc->ctx == NULL) 1383706f2543Smrg { 1384706f2543Smrg ErrorF("glxWinContextMakeCurrent: Native context is NULL\n"); 1385706f2543Smrg return FALSE; 1386706f2543Smrg } 1387706f2543Smrg 1388706f2543Smrg drawDC = glxWinMakeDC(gc, (__GLXWinDrawable *)drawPriv, &drawDC, &hDrawWnd); 1389706f2543Smrg if (drawDC == NULL) 1390706f2543Smrg { 1391706f2543Smrg ErrorF("glxWinMakeDC failed for drawDC\n"); 1392706f2543Smrg return FALSE; 1393706f2543Smrg } 1394706f2543Smrg 1395706f2543Smrg if ((gc->base.readPriv != NULL) && (gc->base.readPriv != gc->base.drawPriv)) 1396706f2543Smrg { 1397706f2543Smrg // XXX: should only occur with WGL_ARB_make_current_read 1398706f2543Smrg /* 1399706f2543Smrg If there is a separate read drawable, create a separate read DC, and 1400706f2543Smrg use the wglMakeContextCurrent extension to make the context current drawing 1401706f2543Smrg to one DC and reading from the other 1402706f2543Smrg */ 1403706f2543Smrg readPriv = gc->base.readPriv; 1404706f2543Smrg readDC = glxWinMakeDC(gc, (__GLXWinDrawable *)readPriv, &readDC, &hReadWnd); 1405706f2543Smrg if (readDC == NULL) 1406706f2543Smrg { 1407706f2543Smrg ErrorF("glxWinMakeDC failed for readDC\n"); 1408706f2543Smrg glxWinReleaseDC(hDrawWnd, drawDC, (__GLXWinDrawable *)drawPriv); 1409706f2543Smrg return FALSE; 1410706f2543Smrg } 1411706f2543Smrg 1412706f2543Smrg ret = wglMakeContextCurrentARBWrapper(drawDC, readDC, gc->ctx); 1413706f2543Smrg if (!ret) 1414706f2543Smrg { 1415706f2543Smrg ErrorF("wglMakeContextCurrentARBWrapper error: %s\n", glxWinErrorMessage()); 1416706f2543Smrg } 1417706f2543Smrg } 1418706f2543Smrg else 1419706f2543Smrg { 1420706f2543Smrg /* Otherwise, just use wglMakeCurrent */ 1421706f2543Smrg ret = wglMakeCurrent(drawDC, gc->ctx); 1422706f2543Smrg if (!ret) 1423706f2543Smrg { 1424706f2543Smrg ErrorF("wglMakeCurrent error: %s\n", glxWinErrorMessage()); 1425706f2543Smrg } 1426706f2543Smrg } 1427706f2543Smrg 1428706f2543Smrg // apparently make current could fail if the context is current in a different thread, 1429706f2543Smrg // but that shouldn't be able to happen in the current server... 1430706f2543Smrg 1431706f2543Smrg glxWinReleaseDC(hDrawWnd, drawDC, (__GLXWinDrawable *)drawPriv); 1432706f2543Smrg if (readDC) 1433706f2543Smrg glxWinReleaseDC(hReadWnd, readDC, (__GLXWinDrawable *)readPriv); 1434706f2543Smrg 1435706f2543Smrg return ret; 1436706f2543Smrg} 1437706f2543Smrg 1438706f2543Smrgstatic int 1439706f2543SmrgglxWinContextLoseCurrent(__GLXcontext *base) 1440706f2543Smrg{ 1441706f2543Smrg BOOL ret; 1442706f2543Smrg __GLXWinContext *gc = (__GLXWinContext *)base; 1443706f2543Smrg 1444706f2543Smrg GLWIN_TRACE_MSG("glxWinContextLoseCurrent context %p (native ctx %p)", gc, gc->ctx); 1445706f2543Smrg glWinCallDelta(); 1446706f2543Smrg 1447706f2543Smrg /* 1448706f2543Smrg An error seems to be reported if we try to make no context current 1449706f2543Smrg if there is already no current context, so avoid doing that... 1450706f2543Smrg */ 1451706f2543Smrg if (__glXLastContext != NULL) 1452706f2543Smrg { 1453706f2543Smrg ret = wglMakeCurrent(NULL, NULL); /* We don't need a DC when setting no current context */ 1454706f2543Smrg if (!ret) 1455706f2543Smrg ErrorF("glxWinContextLoseCurrent error: %s\n", glxWinErrorMessage()); 1456706f2543Smrg } 1457706f2543Smrg 1458706f2543Smrg return TRUE; 1459706f2543Smrg} 1460706f2543Smrg 1461706f2543Smrgstatic int 1462706f2543SmrgglxWinContextCopy(__GLXcontext *dst_base, __GLXcontext *src_base, unsigned long mask) 1463706f2543Smrg{ 1464706f2543Smrg __GLXWinContext *dst = (__GLXWinContext *)dst_base; 1465706f2543Smrg __GLXWinContext *src = (__GLXWinContext *)src_base; 1466706f2543Smrg BOOL ret; 1467706f2543Smrg 1468706f2543Smrg GLWIN_DEBUG_MSG("glxWinContextCopy"); 1469706f2543Smrg 1470706f2543Smrg ret = wglCopyContext(src->ctx, dst->ctx, mask); 1471706f2543Smrg if (!ret) 1472706f2543Smrg { 1473706f2543Smrg ErrorF("wglCopyContext error: %s\n", glxWinErrorMessage()); 1474706f2543Smrg } 1475706f2543Smrg 1476706f2543Smrg return ret; 1477706f2543Smrg} 1478706f2543Smrg 1479706f2543Smrgstatic int 1480706f2543SmrgglxWinContextForceCurrent(__GLXcontext *base) 1481706f2543Smrg{ 1482706f2543Smrg /* wglMakeCurrent always flushes the previous context, so this is equivalent to glxWinContextMakeCurrent */ 1483706f2543Smrg return glxWinContextMakeCurrent(base); 1484706f2543Smrg} 1485706f2543Smrg 1486706f2543Smrgstatic void 1487706f2543SmrgglxWinContextDestroy(__GLXcontext *base) 1488706f2543Smrg{ 1489706f2543Smrg __GLXWinContext *gc = (__GLXWinContext *)base; 1490706f2543Smrg 1491706f2543Smrg if (gc != NULL) 1492706f2543Smrg { 1493706f2543Smrg GLWIN_DEBUG_MSG("GLXcontext %p destroyed (native ctx %p)", base, gc->ctx); 1494706f2543Smrg 1495706f2543Smrg if (gc->ctx) 1496706f2543Smrg { 1497706f2543Smrg /* It's bad style to delete the context while it's still current */ 1498706f2543Smrg if (wglGetCurrentContext() == gc->ctx) 1499706f2543Smrg { 1500706f2543Smrg wglMakeCurrent(NULL, NULL); 1501706f2543Smrg } 1502706f2543Smrg 1503706f2543Smrg { 1504706f2543Smrg BOOL ret = wglDeleteContext(gc->ctx); 1505706f2543Smrg if (!ret) 1506706f2543Smrg ErrorF("wglDeleteContext error: %s\n", glxWinErrorMessage()); 1507706f2543Smrg } 1508706f2543Smrg 1509706f2543Smrg gc->ctx = NULL; 1510706f2543Smrg } 1511706f2543Smrg 1512706f2543Smrg free(gc); 1513706f2543Smrg } 1514706f2543Smrg} 1515706f2543Smrg 1516706f2543Smrgstatic __GLXcontext * 1517706f2543SmrgglxWinCreateContext(__GLXscreen *screen, 1518706f2543Smrg __GLXconfig *modes, 1519706f2543Smrg __GLXcontext *baseShareContext) 1520706f2543Smrg{ 1521706f2543Smrg __GLXWinContext *context; 1522706f2543Smrg __GLXWinContext *shareContext = (__GLXWinContext *)baseShareContext; 1523706f2543Smrg 1524706f2543Smrg static __GLXtextureFromPixmap glxWinTextureFromPixmap = 1525706f2543Smrg { 1526706f2543Smrg glxWinBindTexImage, 1527706f2543Smrg glxWinReleaseTexImage 1528706f2543Smrg }; 1529706f2543Smrg 1530706f2543Smrg context = (__GLXWinContext *)calloc(1, sizeof(__GLXWinContext)); 1531706f2543Smrg 1532706f2543Smrg if (!context) 1533706f2543Smrg return NULL; 1534706f2543Smrg 1535706f2543Smrg memset(context, 0, sizeof *context); 1536706f2543Smrg context->base.destroy = glxWinContextDestroy; 1537706f2543Smrg context->base.makeCurrent = glxWinContextMakeCurrent; 1538706f2543Smrg context->base.loseCurrent = glxWinContextLoseCurrent; 1539706f2543Smrg context->base.copy = glxWinContextCopy; 1540706f2543Smrg context->base.forceCurrent = glxWinContextForceCurrent; 1541706f2543Smrg context->base.textureFromPixmap = &glxWinTextureFromPixmap; 1542706f2543Smrg context->base.config = modes; 1543706f2543Smrg context->base.pGlxScreen = screen; 1544706f2543Smrg 1545706f2543Smrg // actual native GL context creation is deferred until attach() 1546706f2543Smrg context->ctx = NULL; 1547706f2543Smrg context->shareContext = shareContext; 1548706f2543Smrg 1549706f2543Smrg glWinSetupDispatchTable(); 1550706f2543Smrg 1551706f2543Smrg GLWIN_DEBUG_MSG("GLXcontext %p created", context); 1552706f2543Smrg 1553706f2543Smrg return &(context->base); 1554706f2543Smrg} 1555706f2543Smrg 1556706f2543Smrg/* ---------------------------------------------------------------------- */ 1557706f2543Smrg/* 1558706f2543Smrg * Utility functions 1559706f2543Smrg */ 1560706f2543Smrg 1561706f2543Smrgstatic int 1562706f2543SmrgfbConfigToPixelFormat(__GLXconfig *mode, PIXELFORMATDESCRIPTOR *pfdret, int drawableTypeOverride) 1563706f2543Smrg{ 1564706f2543Smrg PIXELFORMATDESCRIPTOR pfd = { 1565706f2543Smrg sizeof(PIXELFORMATDESCRIPTOR), /* size of this pfd */ 1566706f2543Smrg 1, /* version number */ 1567706f2543Smrg PFD_SUPPORT_OPENGL, /* support OpenGL */ 1568706f2543Smrg PFD_TYPE_RGBA, /* RGBA type */ 1569706f2543Smrg 24, /* 24-bit color depth */ 1570706f2543Smrg 0, 0, 0, 0, 0, 0, /* color bits ignored */ 1571706f2543Smrg 0, /* no alpha buffer */ 1572706f2543Smrg 0, /* shift bit ignored */ 1573706f2543Smrg 0, /* no accumulation buffer */ 1574706f2543Smrg 0, 0, 0, 0, /* accum bits ignored */ 1575706f2543Smrg 32, /* 32-bit z-buffer */ 1576706f2543Smrg 0, /* no stencil buffer */ 1577706f2543Smrg 0, /* no auxiliary buffer */ 1578706f2543Smrg PFD_MAIN_PLANE, /* main layer */ 1579706f2543Smrg 0, /* reserved */ 1580706f2543Smrg 0, 0, 0 /* layer masks ignored */ 1581706f2543Smrg }; 1582706f2543Smrg 1583706f2543Smrg if ((mode->drawableType | drawableTypeOverride) & GLX_WINDOW_BIT) 1584706f2543Smrg pfd.dwFlags |= PFD_DRAW_TO_WINDOW; /* support window */ 1585706f2543Smrg 1586706f2543Smrg if ((mode->drawableType | drawableTypeOverride) & GLX_PIXMAP_BIT) 1587706f2543Smrg pfd.dwFlags |= (PFD_DRAW_TO_BITMAP | PFD_SUPPORT_GDI); /* supports software rendering to bitmap */ 1588706f2543Smrg 1589706f2543Smrg if (mode->stereoMode) { 1590706f2543Smrg pfd.dwFlags |= PFD_STEREO; 1591706f2543Smrg } 1592706f2543Smrg if (mode->doubleBufferMode) { 1593706f2543Smrg pfd.dwFlags |= PFD_DOUBLEBUFFER; 1594706f2543Smrg } 1595706f2543Smrg 1596706f2543Smrg pfd.iPixelType = PFD_TYPE_RGBA; 1597706f2543Smrg pfd.cColorBits = mode->redBits + mode->greenBits + mode->blueBits; 1598706f2543Smrg pfd.cRedBits = mode->redBits; 1599706f2543Smrg pfd.cRedShift = 0; /* FIXME */ 1600706f2543Smrg pfd.cGreenBits = mode->greenBits; 1601706f2543Smrg pfd.cGreenShift = 0; /* FIXME */ 1602706f2543Smrg pfd.cBlueBits = mode->blueBits; 1603706f2543Smrg pfd.cBlueShift = 0; /* FIXME */ 1604706f2543Smrg pfd.cAlphaBits = mode->alphaBits; 1605706f2543Smrg pfd.cAlphaShift = 0; /* FIXME */ 1606706f2543Smrg 1607706f2543Smrg pfd.cAccumBits = mode->accumRedBits + mode->accumGreenBits + mode->accumBlueBits + mode->accumAlphaBits; 1608706f2543Smrg pfd.cAccumRedBits = mode->accumRedBits; 1609706f2543Smrg pfd.cAccumGreenBits = mode->accumGreenBits; 1610706f2543Smrg pfd.cAccumBlueBits = mode->accumBlueBits; 1611706f2543Smrg pfd.cAccumAlphaBits = mode->accumAlphaBits; 1612706f2543Smrg 1613706f2543Smrg pfd.cDepthBits = mode->depthBits; 1614706f2543Smrg pfd.cStencilBits = mode->stencilBits; 1615706f2543Smrg pfd.cAuxBuffers = mode->numAuxBuffers; 1616706f2543Smrg 1617706f2543Smrg /* mode->level ? */ 1618706f2543Smrg /* mode->pixmapMode ? */ 1619706f2543Smrg 1620706f2543Smrg *pfdret = pfd; 1621706f2543Smrg 1622706f2543Smrg return 0; 1623706f2543Smrg} 1624706f2543Smrg 1625706f2543Smrg#define SET_ATTR_VALUE(attr, value) { attribList[i++] = attr; attribList[i++] = value; assert(i < NUM_ELEMENTS(attribList)); } 1626706f2543Smrg 1627706f2543Smrgstatic int 1628706f2543SmrgfbConfigToPixelFormatIndex(HDC hdc, __GLXconfig *mode, int drawableTypeOverride, glxWinScreen *winScreen) 1629706f2543Smrg{ 1630706f2543Smrg UINT numFormats; 1631706f2543Smrg unsigned int i = 0; 1632706f2543Smrg 1633706f2543Smrg /* convert fbConfig to attr-value list */ 1634706f2543Smrg int attribList[60]; 1635706f2543Smrg 1636706f2543Smrg SET_ATTR_VALUE(WGL_SUPPORT_OPENGL_ARB, TRUE); 1637706f2543Smrg SET_ATTR_VALUE(WGL_PIXEL_TYPE_ARB, (mode->visualType == GLX_TRUE_COLOR) ? WGL_TYPE_RGBA_ARB : WGL_TYPE_COLORINDEX_ARB); 1638706f2543Smrg SET_ATTR_VALUE(WGL_COLOR_BITS_ARB, (mode->visualType == GLX_TRUE_COLOR) ? mode->rgbBits : mode->indexBits); 1639706f2543Smrg SET_ATTR_VALUE(WGL_RED_BITS_ARB, mode->redBits); 1640706f2543Smrg SET_ATTR_VALUE(WGL_GREEN_BITS_ARB, mode->greenBits); 1641706f2543Smrg SET_ATTR_VALUE(WGL_BLUE_BITS_ARB, mode->blueBits); 1642706f2543Smrg SET_ATTR_VALUE(WGL_ALPHA_BITS_ARB, mode->alphaBits); 1643706f2543Smrg SET_ATTR_VALUE(WGL_ACCUM_RED_BITS_ARB, mode->accumRedBits); 1644706f2543Smrg SET_ATTR_VALUE(WGL_ACCUM_GREEN_BITS_ARB, mode->accumGreenBits); 1645706f2543Smrg SET_ATTR_VALUE(WGL_ACCUM_BLUE_BITS_ARB, mode->accumBlueBits); 1646706f2543Smrg SET_ATTR_VALUE(WGL_ACCUM_ALPHA_BITS_ARB, mode->accumAlphaBits); 1647706f2543Smrg SET_ATTR_VALUE(WGL_DEPTH_BITS_ARB, mode->depthBits); 1648706f2543Smrg SET_ATTR_VALUE(WGL_STENCIL_BITS_ARB, mode->stencilBits); 1649706f2543Smrg SET_ATTR_VALUE(WGL_AUX_BUFFERS_ARB, mode->numAuxBuffers); 1650706f2543Smrg 1651706f2543Smrg if (mode->doubleBufferMode) 1652706f2543Smrg SET_ATTR_VALUE(WGL_DOUBLE_BUFFER_ARB, TRUE); 1653706f2543Smrg 1654706f2543Smrg if (mode->stereoMode) 1655706f2543Smrg SET_ATTR_VALUE(WGL_STEREO_ARB, TRUE); 1656706f2543Smrg 1657706f2543Smrg // Some attributes are only added to the list if the value requested is not 'don't care', as exactly matching that is daft.. 1658706f2543Smrg if (mode->swapMethod == GLX_SWAP_EXCHANGE_OML) 1659706f2543Smrg SET_ATTR_VALUE(WGL_SWAP_METHOD_ARB, WGL_SWAP_EXCHANGE_ARB); 1660706f2543Smrg 1661706f2543Smrg if (mode->swapMethod == GLX_SWAP_COPY_OML) 1662706f2543Smrg SET_ATTR_VALUE(WGL_SWAP_COPY_ARB, TRUE); 1663706f2543Smrg 1664706f2543Smrg // XXX: this should probably be the other way around, but that messes up drawableTypeOverride 1665706f2543Smrg if (mode->visualRating == GLX_SLOW_VISUAL_EXT) 1666706f2543Smrg SET_ATTR_VALUE(WGL_ACCELERATION_ARB, WGL_NO_ACCELERATION_ARB); 1667706f2543Smrg 1668706f2543Smrg // must support all the drawable types the mode supports 1669706f2543Smrg if ((mode->drawableType | drawableTypeOverride) & GLX_WINDOW_BIT) 1670706f2543Smrg SET_ATTR_VALUE(WGL_DRAW_TO_WINDOW_ARB,TRUE); 1671706f2543Smrg 1672706f2543Smrg // XXX: this is a horrible hacky heuristic, in fact this whole drawableTypeOverride thing is a bad idea 1673706f2543Smrg // try to avoid asking for formats which don't exist (by not asking for all when adjusting the config to include the drawableTypeOverride) 1674706f2543Smrg if (drawableTypeOverride == GLX_WINDOW_BIT) 1675706f2543Smrg { 1676706f2543Smrg if (mode->drawableType & GLX_PIXMAP_BIT) 1677706f2543Smrg SET_ATTR_VALUE(WGL_DRAW_TO_BITMAP_ARB, TRUE); 1678706f2543Smrg 1679706f2543Smrg if (mode->drawableType & GLX_PBUFFER_BIT) 1680706f2543Smrg if (winScreen->has_WGL_ARB_pbuffer) 1681706f2543Smrg SET_ATTR_VALUE(WGL_DRAW_TO_PBUFFER_ARB, TRUE); 1682706f2543Smrg } 1683706f2543Smrg else 1684706f2543Smrg { 1685706f2543Smrg if (drawableTypeOverride & GLX_PIXMAP_BIT) 1686706f2543Smrg SET_ATTR_VALUE(WGL_DRAW_TO_BITMAP_ARB, TRUE); 1687706f2543Smrg 1688706f2543Smrg if (drawableTypeOverride & GLX_PBUFFER_BIT) 1689706f2543Smrg if (winScreen->has_WGL_ARB_pbuffer) 1690706f2543Smrg SET_ATTR_VALUE(WGL_DRAW_TO_PBUFFER_ARB, TRUE); 1691706f2543Smrg } 1692706f2543Smrg 1693706f2543Smrg SET_ATTR_VALUE(0, 0); // terminator 1694706f2543Smrg 1695706f2543Smrg /* choose the first match */ 1696706f2543Smrg { 1697706f2543Smrg int pixelFormatIndex; 1698706f2543Smrg 1699706f2543Smrg if (!wglChoosePixelFormatARBWrapper(hdc, attribList, NULL, 1, &pixelFormatIndex, &numFormats)) 1700706f2543Smrg { 1701706f2543Smrg ErrorF("wglChoosePixelFormat error: %s\n", glxWinErrorMessage()); 1702706f2543Smrg } 1703706f2543Smrg else 1704706f2543Smrg { 1705706f2543Smrg if (numFormats > 0) 1706706f2543Smrg { 1707706f2543Smrg GLWIN_DEBUG_MSG("wglChoosePixelFormat: chose pixelFormatIndex %d)", pixelFormatIndex); 1708706f2543Smrg return pixelFormatIndex; 1709706f2543Smrg } 1710706f2543Smrg else 1711706f2543Smrg ErrorF("wglChoosePixelFormat couldn't decide\n"); 1712706f2543Smrg } 1713706f2543Smrg } 1714706f2543Smrg 1715706f2543Smrg return 0; 1716706f2543Smrg} 1717706f2543Smrg 1718706f2543Smrg/* ---------------------------------------------------------------------- */ 1719706f2543Smrg 1720706f2543Smrg#define BITS_AND_SHIFT_TO_MASK(bits,mask) (((1<<(bits))-1) << (mask)) 1721706f2543Smrg 1722706f2543Smrg// 1723706f2543Smrg// Create the GLXconfigs using DescribePixelFormat() 1724706f2543Smrg// 1725706f2543Smrgstatic void 1726706f2543SmrgglxWinCreateConfigs(HDC hdc, glxWinScreen *screen) 1727706f2543Smrg{ 1728706f2543Smrg GLXWinConfig *c, *result, *prev = NULL; 1729706f2543Smrg int numConfigs = 0; 1730706f2543Smrg int i = 0; 1731706f2543Smrg int n = 0; 1732706f2543Smrg PIXELFORMATDESCRIPTOR pfd; 1733706f2543Smrg 1734706f2543Smrg GLWIN_DEBUG_MSG("glxWinCreateConfigs"); 1735706f2543Smrg 1736706f2543Smrg screen->base.numFBConfigs = 0; 1737706f2543Smrg screen->base.fbconfigs = NULL; 1738706f2543Smrg 1739706f2543Smrg // get the number of pixelformats 1740706f2543Smrg numConfigs = DescribePixelFormat(hdc, 1, sizeof(PIXELFORMATDESCRIPTOR), NULL); 1741706f2543Smrg GLWIN_DEBUG_MSG("DescribePixelFormat says %d possible pixel formats", numConfigs); 1742706f2543Smrg 1743706f2543Smrg /* alloc */ 1744706f2543Smrg result = malloc(sizeof(GLXWinConfig) * numConfigs); 1745706f2543Smrg 1746706f2543Smrg if (NULL == result) 1747706f2543Smrg { 1748706f2543Smrg return; 1749706f2543Smrg } 1750706f2543Smrg 1751706f2543Smrg memset(result, 0, sizeof(GLXWinConfig) * numConfigs); 1752706f2543Smrg n = 0; 1753706f2543Smrg 1754706f2543Smrg /* fill in configs */ 1755706f2543Smrg for (i = 0; i < numConfigs; i++) 1756706f2543Smrg { 1757706f2543Smrg int rc; 1758706f2543Smrg 1759706f2543Smrg c = &(result[i]); 1760706f2543Smrg c->base.next = NULL; 1761706f2543Smrg c->pixelFormatIndex = i+1; 1762706f2543Smrg 1763706f2543Smrg rc = DescribePixelFormat(hdc, i+1, sizeof(PIXELFORMATDESCRIPTOR), &pfd); 1764706f2543Smrg 1765706f2543Smrg if (!rc) 1766706f2543Smrg { 1767706f2543Smrg ErrorF("DescribePixelFormat failed for index %d, error %s\n", i+1, glxWinErrorMessage()); 1768706f2543Smrg break; 1769706f2543Smrg } 1770706f2543Smrg 1771706f2543Smrg if (glxWinDebugSettings.dumpPFD) 1772706f2543Smrg pfdOut(&pfd); 1773706f2543Smrg 1774706f2543Smrg if (!(pfd.dwFlags & (PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP)) || !(pfd.dwFlags & PFD_SUPPORT_OPENGL)) 1775706f2543Smrg { 1776706f2543Smrg GLWIN_DEBUG_MSG("pixelFormat %d has unsuitable flags 0x%08lx, skipping", i+1, pfd.dwFlags); 1777706f2543Smrg continue; 1778706f2543Smrg } 1779706f2543Smrg 1780706f2543Smrg c->base.doubleBufferMode = (pfd.dwFlags & PFD_DOUBLEBUFFER) ? GL_TRUE : GL_FALSE; 1781706f2543Smrg c->base.stereoMode = (pfd.dwFlags & PFD_STEREO) ? GL_TRUE : GL_FALSE; 1782706f2543Smrg 1783706f2543Smrg c->base.redBits = pfd.cRedBits; 1784706f2543Smrg c->base.greenBits = pfd.cGreenBits; 1785706f2543Smrg c->base.blueBits = pfd.cBlueBits; 1786706f2543Smrg c->base.alphaBits = pfd.cAlphaBits; 1787706f2543Smrg 1788706f2543Smrg c->base.redMask = BITS_AND_SHIFT_TO_MASK(pfd.cRedBits, pfd.cRedShift); 1789706f2543Smrg c->base.greenMask = BITS_AND_SHIFT_TO_MASK(pfd.cGreenBits, pfd.cGreenShift); 1790706f2543Smrg c->base.blueMask = BITS_AND_SHIFT_TO_MASK(pfd.cBlueBits, pfd.cBlueShift); 1791706f2543Smrg c->base.alphaMask = BITS_AND_SHIFT_TO_MASK(pfd.cAlphaBits, pfd.cAlphaShift); 1792706f2543Smrg 1793706f2543Smrg c->base.rgbBits = pfd.cColorBits; 1794706f2543Smrg 1795706f2543Smrg if (pfd.iPixelType == PFD_TYPE_COLORINDEX) 1796706f2543Smrg { 1797706f2543Smrg c->base.indexBits = pfd.cColorBits; 1798706f2543Smrg } 1799706f2543Smrg else 1800706f2543Smrg { 1801706f2543Smrg c->base.indexBits = 0; 1802706f2543Smrg } 1803706f2543Smrg 1804706f2543Smrg c->base.accumRedBits = pfd.cAccumRedBits; 1805706f2543Smrg c->base.accumGreenBits = pfd.cAccumGreenBits; 1806706f2543Smrg c->base.accumBlueBits = pfd.cAccumBlueBits; 1807706f2543Smrg c->base.accumAlphaBits = pfd.cAccumAlphaBits; 1808706f2543Smrg // pfd.cAccumBits; 1809706f2543Smrg 1810706f2543Smrg c->base.depthBits = pfd.cDepthBits; 1811706f2543Smrg c->base.stencilBits = pfd.cStencilBits; 1812706f2543Smrg c->base.numAuxBuffers = pfd.cAuxBuffers; 1813706f2543Smrg 1814706f2543Smrg // pfd.iLayerType; // ignored 1815706f2543Smrg c->base.level = 0; 1816706f2543Smrg // pfd.dwLayerMask; // ignored 1817706f2543Smrg // pfd.dwDamageMask; // ignored 1818706f2543Smrg 1819706f2543Smrg c->base.pixmapMode = 0; 1820706f2543Smrg c->base.visualID = -1; // will be set by __glXScreenInit() 1821706f2543Smrg 1822706f2543Smrg /* EXT_visual_rating / GLX 1.2 */ 1823706f2543Smrg if (pfd.dwFlags & PFD_GENERIC_FORMAT) 1824706f2543Smrg { 1825706f2543Smrg c->base.visualRating = GLX_SLOW_VISUAL_EXT; 1826706f2543Smrg } 1827706f2543Smrg else 1828706f2543Smrg { 1829706f2543Smrg // PFD_GENERIC_ACCELERATED is not considered, so this may be MCD or ICD acclerated... 1830706f2543Smrg c->base.visualRating = GLX_NONE_EXT; 1831706f2543Smrg } 1832706f2543Smrg 1833706f2543Smrg /* EXT_visual_info / GLX 1.2 */ 1834706f2543Smrg if (pfd.iPixelType == PFD_TYPE_COLORINDEX) 1835706f2543Smrg { 1836706f2543Smrg c->base.visualType = GLX_STATIC_COLOR; 1837706f2543Smrg 1838706f2543Smrg if (!getenv("GLWIN_ENABLE_COLORINDEX_FBCONFIGS")) 1839706f2543Smrg { 1840706f2543Smrg GLWIN_DEBUG_MSG("pixelFormat %d is PFD_TYPE_COLORINDEX, skipping", i+1); 1841706f2543Smrg continue; 1842706f2543Smrg } 1843706f2543Smrg } 1844706f2543Smrg else 1845706f2543Smrg { 1846706f2543Smrg c->base.visualType = GLX_TRUE_COLOR; 1847706f2543Smrg } 1848706f2543Smrg 1849706f2543Smrg // pfd.dwVisibleMask; ??? 1850706f2543Smrg c->base.transparentPixel = GLX_NONE; 1851706f2543Smrg c->base.transparentRed = GLX_NONE; 1852706f2543Smrg c->base.transparentGreen = GLX_NONE; 1853706f2543Smrg c->base.transparentBlue = GLX_NONE; 1854706f2543Smrg c->base.transparentAlpha = GLX_NONE; 1855706f2543Smrg c->base.transparentIndex = GLX_NONE; 1856706f2543Smrg 1857706f2543Smrg /* ARB_multisample / SGIS_multisample */ 1858706f2543Smrg c->base.sampleBuffers = 0; 1859706f2543Smrg c->base.samples = 0; 1860706f2543Smrg 1861706f2543Smrg /* SGIX_fbconfig / GLX 1.3 */ 1862706f2543Smrg c->base.drawableType = (((pfd.dwFlags & PFD_DRAW_TO_WINDOW) ? GLX_WINDOW_BIT : 0) 1863706f2543Smrg | ((pfd.dwFlags & PFD_DRAW_TO_BITMAP) ? GLX_PIXMAP_BIT : 0)); 1864706f2543Smrg 1865706f2543Smrg if (pfd.iPixelType == PFD_TYPE_COLORINDEX) 1866706f2543Smrg { 1867706f2543Smrg c->base.renderType = GLX_RGBA_BIT | GLX_COLOR_INDEX_BIT; 1868706f2543Smrg } 1869706f2543Smrg else 1870706f2543Smrg { 1871706f2543Smrg c->base.renderType = GLX_RGBA_BIT; 1872706f2543Smrg } 1873706f2543Smrg 1874706f2543Smrg c->base.xRenderable = GL_TRUE; 1875706f2543Smrg c->base.fbconfigID = -1; // will be set by __glXScreenInit() 1876706f2543Smrg 1877706f2543Smrg /* SGIX_pbuffer / GLX 1.3 */ 1878706f2543Smrg // XXX: How can we find these values out ??? 1879706f2543Smrg c->base.maxPbufferWidth = -1; 1880706f2543Smrg c->base.maxPbufferHeight = -1; 1881706f2543Smrg c->base.maxPbufferPixels = -1; 1882706f2543Smrg c->base.optimalPbufferWidth = 0; // there is no optimal value 1883706f2543Smrg c->base.optimalPbufferHeight = 0; 1884706f2543Smrg 1885706f2543Smrg /* SGIX_visual_select_group */ 1886706f2543Smrg // arrange for visuals with the best acceleration to be preferred in selection 1887706f2543Smrg switch (pfd.dwFlags & (PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED)) 1888706f2543Smrg { 1889706f2543Smrg case 0: 1890706f2543Smrg c->base.visualSelectGroup = 2; 1891706f2543Smrg break; 1892706f2543Smrg 1893706f2543Smrg case PFD_GENERIC_ACCELERATED: 1894706f2543Smrg c->base.visualSelectGroup = 1; 1895706f2543Smrg break; 1896706f2543Smrg 1897706f2543Smrg case PFD_GENERIC_FORMAT: 1898706f2543Smrg c->base.visualSelectGroup = 0; 1899706f2543Smrg break; 1900706f2543Smrg 1901706f2543Smrg default: 1902706f2543Smrg ; 1903706f2543Smrg // "can't happen" 1904706f2543Smrg } 1905706f2543Smrg 1906706f2543Smrg /* OML_swap_method */ 1907706f2543Smrg if (pfd.dwFlags & PFD_SWAP_EXCHANGE) 1908706f2543Smrg c->base.swapMethod = GLX_SWAP_EXCHANGE_OML; 1909706f2543Smrg else if (pfd.dwFlags & PFD_SWAP_COPY) 1910706f2543Smrg c->base.swapMethod = GLX_SWAP_COPY_OML; 1911706f2543Smrg else 1912706f2543Smrg c->base.swapMethod = GLX_SWAP_UNDEFINED_OML; 1913706f2543Smrg 1914706f2543Smrg /* EXT_import_context */ 1915706f2543Smrg c->base.screen = screen->base.pScreen->myNum; 1916706f2543Smrg 1917706f2543Smrg /* EXT_texture_from_pixmap */ 1918706f2543Smrg c->base.bindToTextureRgb = -1; 1919706f2543Smrg c->base.bindToTextureRgba = -1; 1920706f2543Smrg c->base.bindToMipmapTexture = -1; 1921706f2543Smrg c->base.bindToTextureTargets = -1; 1922706f2543Smrg c->base.yInverted = -1; 1923706f2543Smrg 1924706f2543Smrg n++; 1925706f2543Smrg 1926706f2543Smrg // update previous config to point to this config 1927706f2543Smrg if (prev) 1928706f2543Smrg prev->base.next = &(c->base); 1929706f2543Smrg 1930706f2543Smrg prev = c; 1931706f2543Smrg } 1932706f2543Smrg 1933706f2543Smrg GLWIN_DEBUG_MSG("found %d pixelFormats suitable for conversion to fbConfigs", n); 1934706f2543Smrg 1935706f2543Smrg screen->base.numFBConfigs = n; 1936706f2543Smrg screen->base.fbconfigs = &(result->base); 1937706f2543Smrg} 1938706f2543Smrg 1939706f2543Smrg// helper function to access an attribute value from an attribute value array by attribute 1940706f2543Smrgstatic 1941706f2543Smrgint getAttrValue(const int attrs[], int values[], unsigned int num, int attr, int fallback) 1942706f2543Smrg{ 1943706f2543Smrg unsigned int i; 1944706f2543Smrg for (i = 0; i < num; i++) 1945706f2543Smrg { 1946706f2543Smrg if (attrs[i] == attr) 1947706f2543Smrg { 1948706f2543Smrg GLWIN_TRACE_MSG("getAttrValue attr 0x%x, value %d", attr, values[i]); 1949706f2543Smrg return values[i]; 1950706f2543Smrg } 1951706f2543Smrg } 1952706f2543Smrg 1953706f2543Smrg ErrorF("getAttrValue failed to find attr 0x%x, using default value %d\n", attr, fallback); 1954706f2543Smrg return fallback; 1955706f2543Smrg} 1956706f2543Smrg 1957706f2543Smrg// 1958706f2543Smrg// Create the GLXconfigs using wglGetPixelFormatAttribfvARB() extension 1959706f2543Smrg// 1960706f2543Smrgstatic void 1961706f2543SmrgglxWinCreateConfigsExt(HDC hdc, glxWinScreen *screen) 1962706f2543Smrg{ 1963706f2543Smrg GLXWinConfig *c, *result, *prev = NULL; 1964706f2543Smrg int i = 0; 1965706f2543Smrg int n = 0; 1966706f2543Smrg 1967706f2543Smrg const int attr = WGL_NUMBER_PIXEL_FORMATS_ARB; 1968706f2543Smrg int numConfigs; 1969706f2543Smrg 1970706f2543Smrg int attrs[50]; 1971706f2543Smrg unsigned int num_attrs = 0; 1972706f2543Smrg 1973706f2543Smrg GLWIN_DEBUG_MSG("glxWinCreateConfigsExt"); 1974706f2543Smrg 1975706f2543Smrg screen->base.numFBConfigs = 0; 1976706f2543Smrg screen->base.fbconfigs = NULL; 1977706f2543Smrg 1978706f2543Smrg if (!wglGetPixelFormatAttribivARBWrapper(hdc, 0, 0, 1, &attr, &numConfigs)) 1979706f2543Smrg { 1980706f2543Smrg ErrorF("wglGetPixelFormatAttribivARB failed for WGL_NUMBER_PIXEL_FORMATS_ARB: %s\n", glxWinErrorMessage()); 1981706f2543Smrg return; 1982706f2543Smrg } 1983706f2543Smrg 1984706f2543Smrg GLWIN_DEBUG_MSG("wglGetPixelFormatAttribivARB says %d possible pixel formats", numConfigs); 1985706f2543Smrg 1986706f2543Smrg /* alloc */ 1987706f2543Smrg result = malloc(sizeof(GLXWinConfig) * numConfigs); 1988706f2543Smrg 1989706f2543Smrg if (NULL == result) 1990706f2543Smrg { 1991706f2543Smrg return; 1992706f2543Smrg } 1993706f2543Smrg 1994706f2543Smrg memset(result, 0, sizeof(GLXWinConfig) * numConfigs); 1995706f2543Smrg n = 0; 1996706f2543Smrg 1997706f2543Smrg#define ADD_ATTR(a) { attrs[num_attrs++] = a; assert(num_attrs < NUM_ELEMENTS(attrs)); } 1998706f2543Smrg 1999706f2543Smrg ADD_ATTR(WGL_DRAW_TO_WINDOW_ARB); 2000706f2543Smrg ADD_ATTR(WGL_DRAW_TO_BITMAP_ARB); 2001706f2543Smrg ADD_ATTR(WGL_ACCELERATION_ARB); 2002706f2543Smrg ADD_ATTR(WGL_SWAP_LAYER_BUFFERS_ARB); 2003706f2543Smrg ADD_ATTR(WGL_NUMBER_OVERLAYS_ARB); 2004706f2543Smrg ADD_ATTR(WGL_NUMBER_UNDERLAYS_ARB); 2005706f2543Smrg ADD_ATTR(WGL_TRANSPARENT_ARB); 2006706f2543Smrg ADD_ATTR(WGL_TRANSPARENT_RED_VALUE_ARB); 2007706f2543Smrg ADD_ATTR(WGL_TRANSPARENT_GREEN_VALUE_ARB); 2008706f2543Smrg ADD_ATTR(WGL_TRANSPARENT_GREEN_VALUE_ARB); 2009706f2543Smrg ADD_ATTR(WGL_TRANSPARENT_ALPHA_VALUE_ARB); 2010706f2543Smrg ADD_ATTR(WGL_SUPPORT_OPENGL_ARB); 2011706f2543Smrg ADD_ATTR(WGL_DOUBLE_BUFFER_ARB); 2012706f2543Smrg ADD_ATTR(WGL_STEREO_ARB); 2013706f2543Smrg ADD_ATTR(WGL_PIXEL_TYPE_ARB); 2014706f2543Smrg ADD_ATTR(WGL_COLOR_BITS_ARB); 2015706f2543Smrg ADD_ATTR(WGL_RED_BITS_ARB); 2016706f2543Smrg ADD_ATTR(WGL_RED_SHIFT_ARB); 2017706f2543Smrg ADD_ATTR(WGL_GREEN_BITS_ARB); 2018706f2543Smrg ADD_ATTR(WGL_GREEN_SHIFT_ARB); 2019706f2543Smrg ADD_ATTR(WGL_BLUE_BITS_ARB); 2020706f2543Smrg ADD_ATTR(WGL_BLUE_SHIFT_ARB); 2021706f2543Smrg ADD_ATTR(WGL_ALPHA_BITS_ARB); 2022706f2543Smrg ADD_ATTR(WGL_ALPHA_SHIFT_ARB); 2023706f2543Smrg ADD_ATTR(WGL_ACCUM_RED_BITS_ARB); 2024706f2543Smrg ADD_ATTR(WGL_ACCUM_GREEN_BITS_ARB); 2025706f2543Smrg ADD_ATTR(WGL_ACCUM_BLUE_BITS_ARB); 2026706f2543Smrg ADD_ATTR(WGL_ACCUM_ALPHA_BITS_ARB); 2027706f2543Smrg ADD_ATTR(WGL_DEPTH_BITS_ARB); 2028706f2543Smrg ADD_ATTR(WGL_STENCIL_BITS_ARB); 2029706f2543Smrg ADD_ATTR(WGL_AUX_BUFFERS_ARB); 2030706f2543Smrg ADD_ATTR(WGL_SWAP_METHOD_ARB); 2031706f2543Smrg 2032706f2543Smrg if (screen->has_WGL_ARB_multisample) 2033706f2543Smrg { 2034706f2543Smrg // we may not query these attrs if WGL_ARB_multisample is not offered 2035706f2543Smrg ADD_ATTR(WGL_SAMPLE_BUFFERS_ARB); 2036706f2543Smrg ADD_ATTR(WGL_SAMPLES_ARB); 2037706f2543Smrg } 2038706f2543Smrg 2039706f2543Smrg if (screen->has_WGL_ARB_render_texture) 2040706f2543Smrg { 2041706f2543Smrg // we may not query these attrs if WGL_ARB_render_texture is not offered 2042706f2543Smrg ADD_ATTR(WGL_BIND_TO_TEXTURE_RGB_ARB); 2043706f2543Smrg ADD_ATTR(WGL_BIND_TO_TEXTURE_RGBA_ARB); 2044706f2543Smrg } 2045706f2543Smrg 2046706f2543Smrg if (screen->has_WGL_ARB_pbuffer) 2047706f2543Smrg { 2048706f2543Smrg // we may not query these attrs if WGL_ARB_pbuffer is not offered 2049706f2543Smrg ADD_ATTR(WGL_DRAW_TO_PBUFFER_ARB); 2050706f2543Smrg ADD_ATTR(WGL_MAX_PBUFFER_PIXELS_ARB); 2051706f2543Smrg ADD_ATTR(WGL_MAX_PBUFFER_WIDTH_ARB); 2052706f2543Smrg ADD_ATTR(WGL_MAX_PBUFFER_HEIGHT_ARB); 2053706f2543Smrg } 2054706f2543Smrg 2055706f2543Smrg /* fill in configs */ 2056706f2543Smrg for (i = 0; i < numConfigs; i++) 2057706f2543Smrg { 2058706f2543Smrg int values[num_attrs]; 2059706f2543Smrg 2060706f2543Smrg c = &(result[i]); 2061706f2543Smrg c->base.next = NULL; 2062706f2543Smrg c->pixelFormatIndex = i+1; 2063706f2543Smrg 2064706f2543Smrg if (!wglGetPixelFormatAttribivARBWrapper(hdc, i+1, 0, num_attrs, attrs, values)) 2065706f2543Smrg { 2066706f2543Smrg ErrorF("wglGetPixelFormatAttribivARB failed for index %d, error %s\n", i+1, glxWinErrorMessage()); 2067706f2543Smrg break; 2068706f2543Smrg } 2069706f2543Smrg 2070706f2543Smrg#define ATTR_VALUE(a, d) getAttrValue(attrs, values, num_attrs, (a), (d)) 2071706f2543Smrg 2072706f2543Smrg if (!ATTR_VALUE(WGL_SUPPORT_OPENGL_ARB, 0)) 2073706f2543Smrg { 2074706f2543Smrg GLWIN_DEBUG_MSG("pixelFormat %d isn't WGL_SUPPORT_OPENGL_ARB, skipping", i+1); 2075706f2543Smrg continue; 2076706f2543Smrg } 2077706f2543Smrg 2078706f2543Smrg c->base.doubleBufferMode = ATTR_VALUE(WGL_DOUBLE_BUFFER_ARB, 0) ? GL_TRUE : GL_FALSE; 2079706f2543Smrg c->base.stereoMode = ATTR_VALUE(WGL_STEREO_ARB, 0) ? GL_TRUE : GL_FALSE; 2080706f2543Smrg 2081706f2543Smrg c->base.redBits = ATTR_VALUE(WGL_RED_BITS_ARB, 0); 2082706f2543Smrg c->base.greenBits = ATTR_VALUE(WGL_GREEN_BITS_ARB, 0); 2083706f2543Smrg c->base.blueBits = ATTR_VALUE(WGL_BLUE_BITS_ARB, 0); 2084706f2543Smrg c->base.alphaBits = ATTR_VALUE(WGL_ALPHA_BITS_ARB, 0); 2085706f2543Smrg 2086706f2543Smrg c->base.redMask = BITS_AND_SHIFT_TO_MASK(c->base.redBits, ATTR_VALUE(WGL_RED_SHIFT_ARB, 0)); 2087706f2543Smrg c->base.greenMask = BITS_AND_SHIFT_TO_MASK(c->base.greenBits, ATTR_VALUE(WGL_GREEN_SHIFT_ARB, 0)); 2088706f2543Smrg c->base.blueMask = BITS_AND_SHIFT_TO_MASK(c->base.blueBits, ATTR_VALUE(WGL_BLUE_SHIFT_ARB, 0)); 2089706f2543Smrg c->base.alphaMask = BITS_AND_SHIFT_TO_MASK(c->base.alphaBits, ATTR_VALUE(WGL_ALPHA_SHIFT_ARB, 0)); 2090706f2543Smrg 2091706f2543Smrg switch (ATTR_VALUE(WGL_PIXEL_TYPE_ARB, 0)) 2092706f2543Smrg { 2093706f2543Smrg case WGL_TYPE_COLORINDEX_ARB: 2094706f2543Smrg c->base.indexBits = ATTR_VALUE(WGL_COLOR_BITS_ARB, 0); 2095706f2543Smrg c->base.rgbBits = 0; 2096706f2543Smrg c->base.visualType = GLX_STATIC_COLOR; 2097706f2543Smrg 2098706f2543Smrg if (!getenv("GLWIN_ENABLE_COLORINDEX_FBCONFIGS")) 2099706f2543Smrg { 2100706f2543Smrg GLWIN_DEBUG_MSG("pixelFormat %d is WGL_TYPE_COLORINDEX_ARB, skipping", i+1); 2101706f2543Smrg continue; 2102706f2543Smrg } 2103706f2543Smrg 2104706f2543Smrg break; 2105706f2543Smrg 2106706f2543Smrg case WGL_TYPE_RGBA_FLOAT_ARB: 2107706f2543Smrg GLWIN_DEBUG_MSG("pixelFormat %d is WGL_TYPE_RGBA_FLOAT_ARB, skipping", i+1); 2108706f2543Smrg continue; 2109706f2543Smrg 2110706f2543Smrg case WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT: 2111706f2543Smrg GLWIN_DEBUG_MSG("pixelFormat %d is WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT, skipping", i+1); 2112706f2543Smrg continue; 2113706f2543Smrg 2114706f2543Smrg case WGL_TYPE_RGBA_ARB: 2115706f2543Smrg c->base.indexBits = 0; 2116706f2543Smrg c->base.rgbBits = ATTR_VALUE(WGL_COLOR_BITS_ARB, 0); 2117706f2543Smrg c->base.visualType = GLX_TRUE_COLOR; 2118706f2543Smrg break; 2119706f2543Smrg 2120706f2543Smrg default: 2121706f2543Smrg ErrorF("wglGetPixelFormatAttribivARB returned unknown value 0x%x for WGL_PIXEL_TYPE_ARB\n", ATTR_VALUE(WGL_PIXEL_TYPE_ARB, 0)); 2122706f2543Smrg continue; 2123706f2543Smrg } 2124706f2543Smrg 2125706f2543Smrg c->base.accumRedBits = ATTR_VALUE(WGL_ACCUM_RED_BITS_ARB, 0); 2126706f2543Smrg c->base.accumGreenBits = ATTR_VALUE(WGL_ACCUM_GREEN_BITS_ARB, 0); 2127706f2543Smrg c->base.accumBlueBits = ATTR_VALUE(WGL_ACCUM_BLUE_BITS_ARB, 0); 2128706f2543Smrg c->base.accumAlphaBits = ATTR_VALUE(WGL_ACCUM_ALPHA_BITS_ARB, 0); 2129706f2543Smrg 2130706f2543Smrg c->base.depthBits = ATTR_VALUE(WGL_DEPTH_BITS_ARB, 0); 2131706f2543Smrg c->base.stencilBits = ATTR_VALUE(WGL_STENCIL_BITS_ARB, 0); 2132706f2543Smrg c->base.numAuxBuffers = ATTR_VALUE(WGL_AUX_BUFFERS_ARB, 0); 2133706f2543Smrg 2134706f2543Smrg { 2135706f2543Smrg int layers = ATTR_VALUE(WGL_NUMBER_OVERLAYS_ARB,0) + ATTR_VALUE(WGL_NUMBER_UNDERLAYS_ARB, 0); 2136706f2543Smrg 2137706f2543Smrg if (layers > 0) 2138706f2543Smrg { 2139706f2543Smrg 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)); 2140706f2543Smrg // XXX: need to iterate over layers? 2141706f2543Smrg } 2142706f2543Smrg } 2143706f2543Smrg c->base.level = 0; 2144706f2543Smrg 2145706f2543Smrg c->base.pixmapMode = 0; // ??? 2146706f2543Smrg c->base.visualID = -1; // will be set by __glXScreenInit() 2147706f2543Smrg 2148706f2543Smrg /* EXT_visual_rating / GLX 1.2 */ 2149706f2543Smrg switch (ATTR_VALUE(WGL_ACCELERATION_ARB, 0)) 2150706f2543Smrg { 2151706f2543Smrg default: 2152706f2543Smrg ErrorF("wglGetPixelFormatAttribivARB returned unknown value 0x%x for WGL_ACCELERATION_ARB\n", ATTR_VALUE(WGL_ACCELERATION_ARB, 0)); 2153706f2543Smrg 2154706f2543Smrg case WGL_NO_ACCELERATION_ARB: 2155706f2543Smrg c->base.visualRating = GLX_SLOW_VISUAL_EXT; 2156706f2543Smrg break; 2157706f2543Smrg 2158706f2543Smrg case WGL_GENERIC_ACCELERATION_ARB: 2159706f2543Smrg case WGL_FULL_ACCELERATION_ARB: 2160706f2543Smrg c->base.visualRating = GLX_NONE_EXT; 2161706f2543Smrg break; 2162706f2543Smrg } 2163706f2543Smrg 2164706f2543Smrg /* EXT_visual_info / GLX 1.2 */ 2165706f2543Smrg // c->base.visualType is set above 2166706f2543Smrg if (ATTR_VALUE(WGL_TRANSPARENT_ARB, 0)) 2167706f2543Smrg { 2168706f2543Smrg c->base.transparentPixel = (c->base.visualType == GLX_TRUE_COLOR) ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT; 2169706f2543Smrg c->base.transparentRed = ATTR_VALUE(WGL_TRANSPARENT_RED_VALUE_ARB, 0); 2170706f2543Smrg c->base.transparentGreen = ATTR_VALUE(WGL_TRANSPARENT_GREEN_VALUE_ARB, 0); 2171706f2543Smrg c->base.transparentBlue = ATTR_VALUE(WGL_TRANSPARENT_BLUE_VALUE_ARB, 0); 2172706f2543Smrg c->base.transparentAlpha = ATTR_VALUE(WGL_TRANSPARENT_ALPHA_VALUE_ARB, 0); 2173706f2543Smrg c->base.transparentIndex = ATTR_VALUE(WGL_TRANSPARENT_INDEX_VALUE_ARB, 0); 2174706f2543Smrg } 2175706f2543Smrg else 2176706f2543Smrg { 2177706f2543Smrg c->base.transparentPixel = GLX_NONE_EXT; 2178706f2543Smrg c->base.transparentRed = GLX_NONE; 2179706f2543Smrg c->base.transparentGreen = GLX_NONE; 2180706f2543Smrg c->base.transparentBlue = GLX_NONE; 2181706f2543Smrg c->base.transparentAlpha = GLX_NONE; 2182706f2543Smrg c->base.transparentIndex = GLX_NONE; 2183706f2543Smrg } 2184706f2543Smrg 2185706f2543Smrg /* ARB_multisample / SGIS_multisample */ 2186706f2543Smrg if (screen->has_WGL_ARB_multisample) 2187706f2543Smrg { 2188706f2543Smrg c->base.sampleBuffers = ATTR_VALUE(WGL_SAMPLE_BUFFERS_ARB, 0); 2189706f2543Smrg c->base.samples = ATTR_VALUE(WGL_SAMPLES_ARB, 0); 2190706f2543Smrg } 2191706f2543Smrg else 2192706f2543Smrg { 2193706f2543Smrg c->base.sampleBuffers = 0; 2194706f2543Smrg c->base.samples = 0; 2195706f2543Smrg } 2196706f2543Smrg 2197706f2543Smrg /* SGIX_fbconfig / GLX 1.3 */ 2198706f2543Smrg c->base.drawableType = ((ATTR_VALUE(WGL_DRAW_TO_WINDOW_ARB, 0) ? GLX_WINDOW_BIT : 0) 2199706f2543Smrg | (ATTR_VALUE(WGL_DRAW_TO_BITMAP_ARB, 0) ? GLX_PIXMAP_BIT : 0) 2200706f2543Smrg | (ATTR_VALUE(WGL_DRAW_TO_PBUFFER_ARB, 0) ? GLX_PBUFFER_BIT : 0)); 2201706f2543Smrg 2202706f2543Smrg /* 2203706f2543Smrg Assume OpenGL RGBA rendering is available on all visuals 2204706f2543Smrg (it is specified to render to red component in single-channel visuals, 2205706f2543Smrg if supported, but there doesn't seem to be any mechanism to check if it 2206706f2543Smrg is supported) 2207706f2543Smrg 2208706f2543Smrg Color index rendering is only supported on single-channel visuals 2209706f2543Smrg */ 2210706f2543Smrg if (c->base.visualType == GLX_STATIC_COLOR) 2211706f2543Smrg { 2212706f2543Smrg c->base.renderType = GLX_RGBA_BIT | GLX_COLOR_INDEX_BIT; 2213706f2543Smrg } 2214706f2543Smrg else 2215706f2543Smrg { 2216706f2543Smrg c->base.renderType = GLX_RGBA_BIT; 2217706f2543Smrg } 2218706f2543Smrg 2219706f2543Smrg c->base.xRenderable = GL_TRUE; 2220706f2543Smrg c->base.fbconfigID = -1; // will be set by __glXScreenInit() 2221706f2543Smrg 2222706f2543Smrg /* SGIX_pbuffer / GLX 1.3 */ 2223706f2543Smrg if (screen->has_WGL_ARB_pbuffer) 2224706f2543Smrg { 2225706f2543Smrg c->base.maxPbufferWidth = ATTR_VALUE(WGL_MAX_PBUFFER_WIDTH_ARB, -1); 2226706f2543Smrg c->base.maxPbufferHeight = ATTR_VALUE(WGL_MAX_PBUFFER_HEIGHT_ARB, -1); 2227706f2543Smrg c->base.maxPbufferPixels = ATTR_VALUE(WGL_MAX_PBUFFER_PIXELS_ARB, -1); 2228706f2543Smrg } 2229706f2543Smrg else 2230706f2543Smrg { 2231706f2543Smrg c->base.maxPbufferWidth = -1; 2232706f2543Smrg c->base.maxPbufferHeight = -1; 2233706f2543Smrg c->base.maxPbufferPixels = -1; 2234706f2543Smrg } 2235706f2543Smrg c->base.optimalPbufferWidth = 0; // there is no optimal value 2236706f2543Smrg c->base.optimalPbufferHeight = 0; 2237706f2543Smrg 2238706f2543Smrg /* SGIX_visual_select_group */ 2239706f2543Smrg // arrange for visuals with the best acceleration to be preferred in selection 2240706f2543Smrg switch (ATTR_VALUE(WGL_ACCELERATION_ARB, 0)) 2241706f2543Smrg { 2242706f2543Smrg case WGL_FULL_ACCELERATION_ARB: 2243706f2543Smrg c->base.visualSelectGroup = 2; 2244706f2543Smrg break; 2245706f2543Smrg 2246706f2543Smrg case WGL_GENERIC_ACCELERATION_ARB: 2247706f2543Smrg c->base.visualSelectGroup = 1; 2248706f2543Smrg break; 2249706f2543Smrg 2250706f2543Smrg default: 2251706f2543Smrg case WGL_NO_ACCELERATION_ARB: 2252706f2543Smrg c->base.visualSelectGroup = 0; 2253706f2543Smrg break; 2254706f2543Smrg } 2255706f2543Smrg 2256706f2543Smrg /* OML_swap_method */ 2257706f2543Smrg switch (ATTR_VALUE(WGL_SWAP_METHOD_ARB, 0)) 2258706f2543Smrg { 2259706f2543Smrg case WGL_SWAP_EXCHANGE_ARB: 2260706f2543Smrg c->base.swapMethod = GLX_SWAP_EXCHANGE_OML; 2261706f2543Smrg break; 2262706f2543Smrg 2263706f2543Smrg case WGL_SWAP_COPY_ARB: 2264706f2543Smrg c->base.swapMethod = GLX_SWAP_COPY_OML; 2265706f2543Smrg break; 2266706f2543Smrg 2267706f2543Smrg default: 2268706f2543Smrg ErrorF("wglGetPixelFormatAttribivARB returned unknown value 0x%x for WGL_SWAP_METHOD_ARB\n", ATTR_VALUE(WGL_SWAP_METHOD_ARB, 0)); 2269706f2543Smrg 2270706f2543Smrg case WGL_SWAP_UNDEFINED_ARB: 2271706f2543Smrg c->base.swapMethod = GLX_SWAP_UNDEFINED_OML; 2272706f2543Smrg } 2273706f2543Smrg 2274706f2543Smrg /* EXT_import_context */ 2275706f2543Smrg c->base.screen = screen->base.pScreen->myNum; 2276706f2543Smrg 2277706f2543Smrg /* EXT_texture_from_pixmap */ 2278706f2543Smrg /* 2279706f2543Smrg Mesa's DRI configs always have bindToTextureRgb/Rgba TRUE (see driCreateConfigs(), so setting 2280706f2543Smrg bindToTextureRgb/bindToTextureRgba to FALSE means that swrast can't find any fbConfigs to use, 2281706f2543Smrg so setting these to 0, even if we know bindToTexture isn't available, isn't a good idea... 2282706f2543Smrg */ 2283706f2543Smrg if (screen->has_WGL_ARB_render_texture) 2284706f2543Smrg { 2285706f2543Smrg c->base.bindToTextureRgb = ATTR_VALUE(WGL_BIND_TO_TEXTURE_RGB_ARB, -1); 2286706f2543Smrg c->base.bindToTextureRgba = ATTR_VALUE(WGL_BIND_TO_TEXTURE_RGBA_ARB, -1); 2287706f2543Smrg } 2288706f2543Smrg else 2289706f2543Smrg { 2290706f2543Smrg c->base.bindToTextureRgb = -1; 2291706f2543Smrg c->base.bindToTextureRgba = -1; 2292706f2543Smrg } 2293706f2543Smrg c->base.bindToMipmapTexture = -1; 2294706f2543Smrg c->base.bindToTextureTargets = GLX_TEXTURE_1D_BIT_EXT | GLX_TEXTURE_2D_BIT_EXT | GLX_TEXTURE_RECTANGLE_BIT_EXT; 2295706f2543Smrg c->base.yInverted = -1; 2296706f2543Smrg 2297706f2543Smrg n++; 2298706f2543Smrg 2299706f2543Smrg // update previous config to point to this config 2300706f2543Smrg if (prev) 2301706f2543Smrg prev->base.next = &(c->base); 2302706f2543Smrg 2303706f2543Smrg prev = c; 2304706f2543Smrg } 2305706f2543Smrg 2306706f2543Smrg screen->base.numFBConfigs = n; 2307706f2543Smrg screen->base.fbconfigs = &(result->base); 2308706f2543Smrg} 2309