#ifdef HAVE_XWIN_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include typedef unsigned char BYTE; typedef int BOOL; #ifdef _DEBUG #define PRINTF(...) ErrorF( __VA_ARGS__) #else #define PRINTF(...) #endif #undef PUBLIC #define PUBLIC __declspec(dllexport) BOOL colorIndexMode = FALSE; BOOL doubleBuffered = FALSE; struct __DRIscreenRec { int ScreenNum; const __DRIextension **extensions; const __DRIswrastLoaderExtension *swrast_loader; }; struct __DRIcontextRec { struct _glapi_table *Dispatch; void *driverPrivate; void *loaderPrivate; __DRIdrawable *driDrawablePriv; __DRIdrawable *driReadablePriv; __DRIscreen *driScreenPriv; }; struct __DRIdrawableRec { HDC hDC; HDC hDCFrontBuffer; HGLRC hGLRC; HPALETTE hPalette; HBITMAP hBitmap; int winWidth; int winHeight; int bitsPerPixel; VOID *bits; void *driverPrivate; void *loaderPrivate; __DRIscreen *driScreenPriv; int refcount; }; /* Struct used to manage color ramps */ struct colorIndexState { GLfloat amb[3]; /* ambient color / bottom of ramp */ GLfloat diff[3]; /* diffuse color / middle of ramp */ GLfloat spec[3]; /* specular color / top of ramp */ GLfloat ratio; /* ratio of diffuse to specular in ramp */ GLint indexes[3]; /* where ramp was placed in palette */ }; /* ** Each entry in this array corresponds to a color ramp in the ** palette. The indexes member of each struct is updated to ** reflect the placement of the color ramp in the palette. */ #define NUM_COLORS (sizeof(colors) / sizeof(colors[0])) struct colorIndexState colors[] = { { { 0.0F, 0.0F, 0.0F }, { 0.1F, 0.6F, 0.3F }, { 1.0F, 1.0F, 1.0F }, 0.75F, { 0, 0, 0 }, }, { { 0.0F, 0.0F, 0.0F }, { 0.0F, 0.2F, 0.5F }, { 1.0F, 1.0F, 1.0F }, 0.75F, { 0, 0, 0 }, }, { { 0.0F, 0.05F, 0.05F }, { 0.6F, 0.0F, 0.8F }, { 1.0F, 1.0F, 1.0F }, 0.75F, { 0, 0, 0 }, }, }; void setupPalette(__DRIdrawable * pdp) { PIXELFORMATDESCRIPTOR pfd; LOGPALETTE* pPal; int pixelFormat = GetPixelFormat(pdp->hDC); int paletteSize; PRINTF(__FUNCTION__": pdp %x\n", pdp); DescribePixelFormat(pdp->hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd); /* ** Determine if a palette is needed and if so what size. */ if (pfd.dwFlags & PFD_NEED_PALETTE) { paletteSize = 1 << pfd.cColorBits; } else if (pfd.iPixelType == PFD_TYPE_COLORINDEX) { paletteSize = 4096; } else { return; } pPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) + paletteSize * sizeof(PALETTEENTRY)); pPal->palVersion = 0x300; pPal->palNumEntries = paletteSize; if (pfd.iPixelType == PFD_TYPE_RGBA) { /* ** Fill the logical paletee with RGB color ramps */ int redMask = (1 << pfd.cRedBits) - 1; int greenMask = (1 << pfd.cGreenBits) - 1; int blueMask = (1 << pfd.cBlueBits) - 1; int i; for (i=0; ipalPalEntry[i].peRed = (((i >> pfd.cRedShift) & redMask) * 255) / redMask; pPal->palPalEntry[i].peGreen = (((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask; pPal->palPalEntry[i].peBlue = (((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask; pPal->palPalEntry[i].peFlags = 0; } } else { /* ** Fill the logical palette with color ramps. **pcp ** Set up the logical palette so that it can be realized ** into the system palette as an identity palette. ** ** 1) The default static entries should be present and at the right ** location. The easiest way to do this is to grab them from ** the current system palette. ** ** 2) All non-static entries should be initialized to unique values. ** The easiest way to do this is to ensure that all of the non-static ** entries have the PC_NOCOLLAPSE flag bit set. */ int numRamps = NUM_COLORS; int rampSize = (paletteSize - 20) / numRamps; int extra = (paletteSize - 20) - (numRamps * rampSize); int i, r; /* ** Initialize static entries by copying them from the ** current system palette. */ GetSystemPaletteEntries(pdp->hDC, 0, paletteSize, &pPal->palPalEntry[0]); /* ** Fill in non-static entries with desired colors. */ for (r=0; rpalPalEntry[rampBase]; int diffSize = (int) (rampSize * colors[r].ratio); int specSize = rampSize - diffSize; for (i=0; ipalPalEntry[index]; pe->peRed = (BYTE) 0; pe->peGreen = (BYTE) 0; pe->peBlue = (BYTE) 0; pe->peFlags = PC_NOCOLLAPSE; } } pdp->hPalette = CreatePalette(pPal); free(pPal); if (pdp->hPalette) { SelectPalette(pdp->hDC, pdp->hPalette, FALSE); RealizePalette(pdp->hDC); } } void setupPixelFormat(__DRIdrawable *pdp) { PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), /* size of this pfd */ 1, /* version num */ PFD_SUPPORT_OPENGL, /* support OpenGL */ 0, /* pixel type */ 0, /* 8-bit color depth */ 0, 0, 0, 0, 0, 0, /* color bits (ignored) */ 0, /* no alpha buffer */ 0, /* alpha bits (ignored) */ 0, /* no accumulation buffer */ 0, 0, 0, 0, /* accum bits (ignored) */ 16, /* depth buffer */ 0, /* no stencil buffer */ 0, /* no auxiliary buffers */ PFD_MAIN_PLANE, /* main layer */ 0, /* reserved */ 0, 0, 0, /* no layer, visible, damage masks */ }; int SelectedPixelFormat; BOOL retVal; PRINTF(__FUNCTION__": pdp %x\n", pdp); pfd.cColorBits = GetDeviceCaps(pdp->hDC, BITSPIXEL); if (colorIndexMode) { pfd.iPixelType = PFD_TYPE_COLORINDEX; } else { pfd.iPixelType = PFD_TYPE_RGBA; } if (doubleBuffered) { pfd.dwFlags |= PFD_DOUBLEBUFFER; } pfd.dwFlags |= PFD_DRAW_TO_BITMAP; SelectedPixelFormat = ChoosePixelFormat(pdp->hDC, &pfd); if (SelectedPixelFormat == 0) { (void) MessageBox(WindowFromDC(pdp->hDC), "Failed to find acceptable pixel format.", "OpenGL application error", MB_ICONERROR | MB_OK); exit(1); } retVal = SetPixelFormat(pdp->hDC, SelectedPixelFormat, &pfd); if (retVal != TRUE) { MessageBox(WindowFromDC(pdp->hDC), "Failed to set pixel format.", "OpenGL application error", MB_ICONERROR | MB_OK); exit(1); } } void setupDIB(__DRIdrawable * pdp) { HBITMAP hBitmap; BITMAPINFO *bmInfo; BITMAPINFOHEADER *bmHeader; UINT usage; VOID *base; int bmiSize; int bitsPerPixel; PRINTF(__FUNCTION__": pdp %x\n", pdp); bmiSize = sizeof(*bmInfo); bitsPerPixel = GetDeviceCaps(pdp->hDC, BITSPIXEL); pdp->bitsPerPixel=bitsPerPixel; switch (bitsPerPixel) { case 8: /* bmiColors is 256 WORD palette indices */ bmiSize += (256 * sizeof(WORD)) - sizeof(RGBQUAD); break; case 16: /* bmiColors is 3 WORD component masks */ bmiSize += (3 * sizeof(DWORD)) - sizeof(RGBQUAD); break; case 24: case 32: default: /* bmiColors not used */ break; } bmInfo = (BITMAPINFO *) calloc(1, bmiSize); bmHeader = &bmInfo->bmiHeader; bmHeader->biSize = sizeof(*bmHeader); bmHeader->biWidth = pdp->winWidth; bmHeader->biHeight = pdp->winHeight; bmHeader->biPlanes = 1; /* must be 1 */ bmHeader->biBitCount = bitsPerPixel; bmHeader->biXPelsPerMeter = 0; bmHeader->biYPelsPerMeter = 0; bmHeader->biClrUsed = 0; /* all are used */ bmHeader->biClrImportant = 0; /* all are important */ switch (bitsPerPixel) { case 8: bmHeader->biCompression = BI_RGB; bmHeader->biSizeImage = 0; usage = DIB_PAL_COLORS; /* bmiColors is 256 WORD palette indices */ { WORD *palIndex = (WORD *) &bmInfo->bmiColors[0]; int i; for (i=0; i<256; i++) { palIndex[i] = i; } } break; case 16: bmHeader->biCompression = BI_RGB; bmHeader->biSizeImage = 0; usage = DIB_RGB_COLORS; /* bmiColors is 3 WORD component masks */ { DWORD *compMask = (DWORD *) &bmInfo->bmiColors[0]; compMask[0] = 0xF800; compMask[1] = 0x07E0; compMask[2] = 0x001F; } break; case 24: case 32: default: bmHeader->biCompression = BI_RGB; bmHeader->biSizeImage = 0; usage = DIB_RGB_COLORS; /* bmiColors not used */ break; } hBitmap = CreateDIBSection(pdp->hDC, bmInfo, usage, &base, NULL, 0); if (hBitmap == NULL) { (void) MessageBox(WindowFromDC(pdp->hDC), "Failed to create DIBSection.", "OpenGL application error", MB_ICONERROR | MB_OK); exit(1); } pdp->bits=base; SelectObject(pdp->hDC, hBitmap); if (pdp->hBitmap) DeleteObject(pdp->hBitmap); pdp->hBitmap = hBitmap; free(bmInfo); } static void setupLoaderExtensions(__DRIscreen *psp, const __DRIextension **extensions) { int i; for (i = 0; extensions[i]; i++) { if (strcmp(extensions[i]->name, __DRI_SWRAST_LOADER) == 0) psp->swrast_loader = (__DRIswrastLoaderExtension *) extensions[i]; } } static const __DRItexBufferExtension swrastTexBufferExtension = { { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION }, NULL,// swrastSetTexBuffer, NULL // swrastSetTexBuffer2 }; static const __DRIextension *dri_screen_extensions[] = { &swrastTexBufferExtension.base, NULL }; struct gl_config { GLboolean rgbMode; GLboolean floatMode; GLboolean colorIndexMode; /* XXX is this used anywhere? */ GLuint doubleBufferMode; GLuint stereoMode; GLboolean haveAccumBuffer; GLboolean haveDepthBuffer; GLboolean haveStencilBuffer; GLint redBits, greenBits, blueBits, alphaBits; /* bits per comp */ GLuint redMask, greenMask, blueMask, alphaMask; GLint rgbBits; /* total bits for rgb */ GLint indexBits; /* total bits for colorindex */ GLint accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits; GLint depthBits; GLint stencilBits; GLint numAuxBuffers; GLint level; /* EXT_visual_rating / GLX 1.2 */ GLint visualRating; /* EXT_visual_info / GLX 1.2 */ GLint transparentPixel; /* colors are floats scaled to ints */ GLint transparentRed, transparentGreen, transparentBlue, transparentAlpha; GLint transparentIndex; /* ARB_multisample / SGIS_multisample */ GLint sampleBuffers; GLint samples; /* SGIX_pbuffer / GLX 1.3 */ GLint maxPbufferWidth; GLint maxPbufferHeight; GLint maxPbufferPixels; GLint optimalPbufferWidth; /* Only for SGIX_pbuffer. */ GLint optimalPbufferHeight; /* Only for SGIX_pbuffer. */ /* OML_swap_method */ GLint swapMethod; /* EXT_texture_from_pixmap */ GLint bindToTextureRgb; GLint bindToTextureRgba; GLint bindToMipmapTexture; GLint bindToTextureTargets; GLint yInverted; /* EXT_framebuffer_sRGB */ GLint sRGBCapable; }; struct __DRIconfigRec { struct gl_config modes; }; #define __ATTRIB(attrib, field) \ { attrib, offsetof(struct gl_config, field) } static const struct { unsigned int attrib, offset; } attribMap[] = { __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits), __ATTRIB(__DRI_ATTRIB_LEVEL, level), __ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits), __ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits), __ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits), __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits), __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE, depthBits), __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE, stencilBits), __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE, accumRedBits), __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE, accumGreenBits), __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE, accumBlueBits), __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE, accumAlphaBits), __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS, sampleBuffers), __ATTRIB(__DRI_ATTRIB_SAMPLES, samples), __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode), __ATTRIB(__DRI_ATTRIB_STEREO, stereoMode), __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS, numAuxBuffers), __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel), __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentPixel), __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE, transparentRed), __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE, transparentGreen), __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE, transparentBlue), __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE, transparentAlpha), __ATTRIB(__DRI_ATTRIB_FLOAT_MODE, floatMode), __ATTRIB(__DRI_ATTRIB_RED_MASK, redMask), __ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask), __ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask), __ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask), __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth), __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight), __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels), __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth), __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight), __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod), __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb), __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba), __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture), __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS, bindToTextureTargets), __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted), __ATTRIB(__DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE, sRGBCapable), /* The struct field doesn't matter here, these are handled by the * switch in driGetConfigAttribIndex. We need them in the array * so the iterator includes them though.*/ __ATTRIB(__DRI_ATTRIB_RENDER_TYPE, level), __ATTRIB(__DRI_ATTRIB_CONFIG_CAVEAT, level), __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, level) }; #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) __DRIconfig ** driCreateConfigs(GLenum fb_format, GLenum fb_type, const uint8_t * depth_bits, const uint8_t * stencil_bits, unsigned num_depth_stencil_bits, const GLenum * db_modes, unsigned num_db_modes, const uint8_t * msaa_samples, unsigned num_msaa_modes, GLboolean enable_accum) { static const uint8_t bits_table[4][4] = { /* R G B A */ { 3, 3, 2, 0 }, /* Any GL_UNSIGNED_BYTE_3_3_2 */ { 5, 6, 5, 0 }, /* Any GL_UNSIGNED_SHORT_5_6_5 */ { 8, 8, 8, 0 }, /* Any RGB with any GL_UNSIGNED_INT_8_8_8_8 */ { 8, 8, 8, 8 } /* Any RGBA with any GL_UNSIGNED_INT_8_8_8_8 */ }; static const uint32_t masks_table_rgb[6][4] = { { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2 */ { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV */ { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5 */ { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV */ { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000 }, /* 8_8_8_8 */ { 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 } /* 8_8_8_8_REV */ }; static const uint32_t masks_table_rgba[6][4] = { { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2 */ { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV */ { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5 */ { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV */ { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF }, /* 8_8_8_8 */ { 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 }, /* 8_8_8_8_REV */ }; static const uint32_t masks_table_bgr[6][4] = { { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2 */ { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV */ { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5 */ { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV */ { 0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000 }, /* 8_8_8_8 */ { 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 }, /* 8_8_8_8_REV */ }; static const uint32_t masks_table_bgra[6][4] = { { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2 */ { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV */ { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5 */ { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV */ { 0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF }, /* 8_8_8_8 */ { 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }, /* 8_8_8_8_REV */ }; static const uint8_t bytes_per_pixel[6] = { 1, /* 3_3_2 */ 1, /* 2_3_3_REV */ 2, /* 5_6_5 */ 2, /* 5_6_5_REV */ 4, /* 8_8_8_8 */ 4 /* 8_8_8_8_REV */ }; const uint8_t * bits; const uint32_t * masks; int index; __DRIconfig **configs, **c; struct gl_config *modes; unsigned i, j, k, h; unsigned num_modes; unsigned num_accum_bits = (enable_accum) ? 2 : 1; PRINTF(__FUNCTION__"\n"); switch ( fb_type ) { case GL_UNSIGNED_BYTE_3_3_2: index = 0; break; case GL_UNSIGNED_BYTE_2_3_3_REV: index = 1; break; case GL_UNSIGNED_SHORT_5_6_5: index = 2; break; case GL_UNSIGNED_SHORT_5_6_5_REV: index = 3; break; case GL_UNSIGNED_INT_8_8_8_8: index = 4; break; case GL_UNSIGNED_INT_8_8_8_8_REV: index = 5; break; default: fprintf( stderr, "[%s:%u] Unknown framebuffer type 0x%04x.\n", __FUNCTION__, __LINE__, fb_type ); return NULL; } /* Valid types are GL_UNSIGNED_SHORT_5_6_5 and GL_UNSIGNED_INT_8_8_8_8 and * the _REV versions. * * Valid formats are GL_RGBA, GL_RGB, and GL_BGRA. */ switch ( fb_format ) { case GL_RGB: masks = masks_table_rgb[ index ]; break; case GL_RGBA: masks = masks_table_rgba[ index ]; break; case GL_BGR: masks = masks_table_bgr[ index ]; break; case GL_BGRA: masks = masks_table_bgra[ index ]; break; default: fprintf( stderr, "[%s:%u] Unknown framebuffer format 0x%04x.\n", __FUNCTION__, __LINE__, fb_format ); return NULL; } switch ( bytes_per_pixel[ index ] ) { case 1: bits = bits_table[0]; break; case 2: bits = bits_table[1]; break; default: bits = ((fb_format == GL_RGB) || (fb_format == GL_BGR)) ? bits_table[2] : bits_table[3]; break; } num_modes = num_depth_stencil_bits * num_db_modes * num_accum_bits * num_msaa_modes; configs = calloc(1, (num_modes + 1) * sizeof *configs); if (configs == NULL) return NULL; c = configs; for ( k = 0 ; k < num_depth_stencil_bits ; k++ ) { for ( i = 0 ; i < num_db_modes ; i++ ) { for ( h = 0 ; h < num_msaa_modes; h++ ) { for ( j = 0 ; j < num_accum_bits ; j++ ) { *c = malloc (sizeof **c); modes = &(*c)->modes; c++; memset(modes, 0, sizeof *modes); modes->redBits = bits[0]; modes->greenBits = bits[1]; modes->blueBits = bits[2]; modes->alphaBits = bits[3]; modes->redMask = masks[0]; modes->greenMask = masks[1]; modes->blueMask = masks[2]; modes->alphaMask = masks[3]; modes->rgbBits = modes->redBits + modes->greenBits + modes->blueBits + modes->alphaBits; modes->accumRedBits = 16 * j; modes->accumGreenBits = 16 * j; modes->accumBlueBits = 16 * j; modes->accumAlphaBits = (masks[3] != 0) ? 16 * j : 0; modes->visualRating = (j == 0) ? GLX_NONE : GLX_SLOW_CONFIG; modes->stencilBits = stencil_bits[k]; modes->depthBits = depth_bits[k]; modes->transparentPixel = GLX_NONE; modes->transparentRed = GLX_DONT_CARE; modes->transparentGreen = GLX_DONT_CARE; modes->transparentBlue = GLX_DONT_CARE; modes->transparentAlpha = GLX_DONT_CARE; modes->transparentIndex = GLX_DONT_CARE; modes->rgbMode = GL_TRUE; if ( db_modes[i] == GLX_NONE ) { modes->doubleBufferMode = GL_FALSE; } else { modes->doubleBufferMode = GL_TRUE; modes->swapMethod = db_modes[i]; } modes->samples = msaa_samples[h]; modes->sampleBuffers = modes->samples ? 1 : 0; modes->haveAccumBuffer = ((modes->accumRedBits + modes->accumGreenBits + modes->accumBlueBits + modes->accumAlphaBits) > 0); modes->haveDepthBuffer = (modes->depthBits > 0); modes->haveStencilBuffer = (modes->stencilBits > 0); modes->bindToTextureRgb = GL_TRUE; modes->bindToTextureRgba = GL_TRUE; modes->bindToMipmapTexture = GL_FALSE; modes->bindToTextureTargets = __DRI_ATTRIB_TEXTURE_1D_BIT | __DRI_ATTRIB_TEXTURE_2D_BIT | __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT; modes->sRGBCapable = GL_FALSE; } } } } *c = NULL; return configs; } static __DRIconfig ** swrastFillInModes(__DRIscreen *psp, unsigned pixel_bits, unsigned depth_bits, unsigned stencil_bits, GLboolean have_back_buffer) { __DRIconfig **configs; unsigned depth_buffer_factor; unsigned back_buffer_factor; GLenum fb_format; GLenum fb_type; /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't * support pageflipping at all. */ static const GLenum back_buffer_modes[] = { GLX_NONE, GLX_SWAP_UNDEFINED_OML }; uint8_t depth_bits_array[4]; uint8_t stencil_bits_array[4]; uint8_t msaa_samples_array[1]; (void) psp; (void) have_back_buffer; PRINTF(__FUNCTION__"\n"); depth_bits_array[0] = 0; depth_bits_array[1] = 0; depth_bits_array[2] = depth_bits; depth_bits_array[3] = depth_bits; /* Just like with the accumulation buffer, always provide some modes * with a stencil buffer. */ stencil_bits_array[0] = 0; stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits; stencil_bits_array[2] = 0; stencil_bits_array[3] = (stencil_bits == 0) ? 8 : stencil_bits; msaa_samples_array[0] = 0; depth_buffer_factor = 4; back_buffer_factor = 2; switch (pixel_bits) { case 8: fb_format = GL_RGB; fb_type = GL_UNSIGNED_BYTE_2_3_3_REV; break; case 16: fb_format = GL_RGB; fb_type = GL_UNSIGNED_SHORT_5_6_5; break; case 24: fb_format = GL_BGR; fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; break; case 32: fb_format = GL_BGRA; fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; break; default: fprintf(stderr, "[%s:%u] bad depth %d\n", __FUNCTION__, __LINE__, pixel_bits); return NULL; } configs = driCreateConfigs(fb_format, fb_type, depth_bits_array, stencil_bits_array, depth_buffer_factor, back_buffer_modes, back_buffer_factor, msaa_samples_array, 1, GL_TRUE); if (configs == NULL) { fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __FUNCTION__, __LINE__); return NULL; } return configs; } __DRIconfig **driConcatConfigs(__DRIconfig **a, __DRIconfig **b) { __DRIconfig **all; int i, j, index; PRINTF(__FUNCTION__"\n"); i = 0; while (a[i] != NULL) i++; j = 0; while (b[j] != NULL) j++; all = malloc((i + j + 1) * sizeof *all); index = 0; for (i = 0; a[i] != NULL; i++) all[index++] = a[i]; for (j = 0; b[j] != NULL; j++) all[index++] = b[j]; all[index++] = NULL; free(a); free(b); return all; } static int driGetConfigAttribIndex(const __DRIconfig *config, unsigned int index, unsigned int *value) { switch (attribMap[index].attrib) { case __DRI_ATTRIB_RENDER_TYPE: /* no support for color index mode */ *value = __DRI_ATTRIB_RGBA_BIT; break; case __DRI_ATTRIB_CONFIG_CAVEAT: if (config->modes.visualRating == GLX_NON_CONFORMANT_CONFIG) *value = __DRI_ATTRIB_NON_CONFORMANT_CONFIG; else if (config->modes.visualRating == GLX_SLOW_CONFIG) *value = __DRI_ATTRIB_SLOW_BIT; else *value = 0; break; case __DRI_ATTRIB_SWAP_METHOD: /* XXX no return value??? */ break; case __DRI_ATTRIB_FLOAT_MODE: /* this field is not int-sized */ *value = config->modes.floatMode; break; default: /* any other int-sized field */ *value = *(unsigned int *) ((char *) &config->modes + attribMap[index].offset); break; } return GL_TRUE; } int driIndexConfigAttrib(const __DRIconfig *config, int index, unsigned int *attrib, unsigned int *value) { if (index >= 0 && index < ARRAY_SIZE(attribMap)) { *attrib = attribMap[index].attrib; return driGetConfigAttribIndex(config, index, value); } return GL_FALSE; } static const __DRIconfig **dri_init_screen(__DRIscreen * psp) { __DRIconfig **configs8, **configs16, **configs24, **configs32; PRINTF(__FUNCTION__": psp %x\n", psp); psp->extensions = dri_screen_extensions; configs8 = swrastFillInModes(psp, 8, 8, 0, 1); configs16 = swrastFillInModes(psp, 16, 16, 0, 1); configs24 = swrastFillInModes(psp, 24, 24, 8, 1); configs32 = swrastFillInModes(psp, 32, 24, 8, 1); configs16 = driConcatConfigs(configs8, configs16); configs24 = driConcatConfigs(configs16, configs24); configs32 = driConcatConfigs(configs24, configs32); return (const __DRIconfig **)configs32; } static __DRIscreen *driCreateNewScreen(int scrn, const __DRIextension **extensions, const __DRIconfig ***driver_configs, void *data) { static const __DRIextension *emptyExtensionList[] = { NULL }; __DRIscreen *psp; HDC hDc = GetDC(NULL); int bitsPerPixel= GetDeviceCaps(hDc, BITSPIXEL); ReleaseDC(NULL, hDc); if (bitsPerPixel<24) { PRINTF(__FUNCTION__": bitsPerPixel not supported %d\n", bitsPerPixel); return NULL; } psp = calloc(sizeof(struct __DRIscreenRec),1); if (!psp) return NULL; PRINTF(__FUNCTION__": psp %x\n", psp); setupLoaderExtensions(psp, extensions); psp->extensions = emptyExtensionList; psp->ScreenNum = scrn; *driver_configs = dri_init_screen(psp); if (*driver_configs == NULL) { free(psp); return NULL; } return psp; } static __DRIcontext *driCreateNewContext(__DRIscreen *psp, const __DRIconfig *config, __DRIcontext *shared, void *data) { __DRIcontext *pcp; void * const shareCtx = (shared != NULL) ? shared->driverPrivate : NULL; pcp = calloc(sizeof(struct __DRIcontextRec),1); if (!pcp) return NULL; PRINTF(__FUNCTION__": psp %x, shared %x, data %x, pcp %x\n", psp, shared, data, pcp); pcp->loaderPrivate = data; pcp->driScreenPriv = psp; pcp->driDrawablePriv = NULL; pcp->driReadablePriv = NULL; pcp->Dispatch=calloc(sizeof(void*), (sizeof(struct _glapi_table) / sizeof(void *) + MAX_EXTENSION_FUNCS)); _glapi_set_dispatch(pcp->Dispatch); glWinSetupDispatchTable(); return pcp; } static const __DRIextension **driGetExtensions(__DRIscreen *psp) { return psp->extensions; } static void driDrawableCheckSize(__DRIdrawable *pdp) { int x; int y; int w; int h; pdp->driScreenPriv->swrast_loader->getDrawableInfo(pdp, &x, &y, &w, &h, pdp->loaderPrivate); if (pdp->winWidth==w && pdp->winHeight==h) return; pdp->winWidth=w; pdp->winHeight=h; setupDIB(pdp); } static __DRIdrawable *driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config, void *data) { __DRIdrawable *pdp = calloc(sizeof(struct __DRIdrawableRec),1); if (!pdp) return NULL; PRINTF(__FUNCTION__": pdp %x, data %x\n", pdp, data); pdp->loaderPrivate = data; pdp->driScreenPriv = psp; pdp->refcount++; pdp->hDCFrontBuffer = GetDC(NULL); pdp->hDC = CreateCompatibleDC(pdp->hDCFrontBuffer); driDrawableCheckSize(pdp); setupPixelFormat(pdp); setupPalette(pdp); pdp->hGLRC = wglCreateContext(pdp->hDC); return pdp; } static __DRIcontext *current_pcp; static int driBindContext(__DRIcontext *pcp, __DRIdrawable *pdp, __DRIdrawable *prp) { PRINTF(__FUNCTION__": pcp %x, pdp %x, prp %x\n",pcp, pdp, prp); if (current_pcp) { driUnbindContext(current_pcp); current_pcp=NULL; } /* Bind the drawable to the context */ if (pcp) { static int Created=0; if (!pdp || !prp) { return GL_TRUE; } pcp->driDrawablePriv = pdp; pcp->driReadablePriv = prp; if (pdp) { pdp->refcount++; } if ( prp && pdp != prp ) { prp->refcount++; } if (wglGetCurrentContext()!=pdp->hGLRC) { if (!wglMakeCurrent(pdp->hDC, pdp->hGLRC)) ErrorF("Error making context current: pdp %x\n",pdp); PRINTF("pdp->hDC %x to pdp->hGLRC %x\n",pdp->hDC, pdp->hGLRC); } if (Created) { // initialize wgl extension proc pointers (don't call them before here...) // (but we need to have a current context for them to be resolvable) Created=1; wglResolveExtensionProcs(); } current_pcp=pcp; _glapi_set_dispatch(pcp->Dispatch); } return GL_TRUE; } static void driDestroyDrawable(__DRIdrawable *pdp) { if (pdp) { pdp->refcount--; if (pdp->refcount) return; PRINTF(__FUNCTION__": pdp %x\n", pdp); wglDeleteContext (pdp->hGLRC); DeleteDC(pdp->hDC); ReleaseDC(NULL, pdp->hDCFrontBuffer); DeleteObject(pdp->hBitmap); if (pdp->hPalette) DeleteObject(pdp->hPalette); free(pdp); } } static int driUnbindContext(__DRIcontext *pcp) { __DRIdrawable *pdp; __DRIdrawable *prp; PRINTF(__FUNCTION__": pcp %x\n", pcp); if (pcp == NULL) return GL_FALSE; pdp = pcp->driDrawablePriv; prp = pcp->driReadablePriv; /* already unbound */ if (!pdp && !prp) { PRINTF(__FUNCTION__": pcp %x already unbound\n", pcp); return GL_TRUE; } if (wglGetCurrentContext()==pdp->hGLRC) { current_pcp=NULL; wglMakeCurrent(pdp->hDC, NULL); PRINTF("pdp->hDC %x to NULL\n", pdp->hDC); } driDestroyDrawable(pdp); if (prp!=pdp) driDestroyDrawable(prp); pcp->driDrawablePriv = NULL; pcp->driReadablePriv = NULL; _glapi_set_dispatch(NULL); return GL_TRUE; } static void driDestroyContext(__DRIcontext *pcp) { PRINTF(__FUNCTION__": pcp %x\n", pcp); if (pcp) { driUnbindContext(pcp); free(pcp); } } static void driDestroyScreen(__DRIscreen *psp) { PRINTF(__FUNCTION__": psp %x\n", psp); if (psp) { free(psp); } } static void driSwapBuffers(__DRIdrawable *pdp) { // GET_CURRENT_CONTEXT(ctx); /* Revert image */ int Row; int UpRow; int ColCount; int HalfRowCount; int *pBits; //GdiFlush(); driDrawableCheckSize(pdp); ColCount=pdp->winWidth; HalfRowCount=pdp->winHeight/2; pBits=(int*)pdp->bits; for (Row=0,UpRow=2*HalfRowCount-1; RowdriScreenPriv->swrast_loader->putImage(pdp, __DRI_SWRAST_IMAGE_OP_SWAP, 0, 0, pdp->winWidth, pdp->winHeight, pdp->bits, pdp->loaderPrivate); } const __DRIcoreExtension driCoreExtension = { { __DRI_CORE, __DRI_CORE_VERSION }, NULL, /* driCreateNewScreen */ driDestroyScreen, driGetExtensions, NULL,// driGetConfigAttrib, driIndexConfigAttrib, NULL, /* driCreateNewDrawable */ driDestroyDrawable, driSwapBuffers, driCreateNewContext, NULL,// driCopyContext, driDestroyContext, driBindContext, driUnbindContext }; const __DRIswrastExtension driWGLExtension = { { __DRI_SWRAST, __DRI_SWRAST_VERSION }, driCreateNewScreen, driCreateNewDrawable, NULL // driCreateNewContextForAPI }; /* This is the table of extensions that the loader will dlsym() for. */ PUBLIC const __DRIextension *__driDriverExtensions[] = { &driCoreExtension.base, &driWGLExtension.base, NULL };