diff options
Diffstat (limited to 'GL/glx/glxglcore.c')
-rw-r--r-- | GL/glx/glxglcore.c | 213 |
1 files changed, 120 insertions, 93 deletions
diff --git a/GL/glx/glxglcore.c b/GL/glx/glxglcore.c index df9be07c0..0750e1282 100644 --- a/GL/glx/glxglcore.c +++ b/GL/glx/glxglcore.c @@ -70,7 +70,7 @@ struct __GLXMESAdrawable { XMesaBuffer xm_buf; }; -static XMesaVisual find_mesa_visual(__GLXscreen *screen, VisualID vid); +static XMesaVisual find_mesa_visual(__GLXscreen *screen, XID fbconfigID); static void @@ -118,7 +118,7 @@ __glXMesaDrawableSwapBuffers(__GLXdrawable *base) static __GLXdrawable * __glXMesaScreenCreateDrawable(__GLXscreen *screen, - DrawablePtr pDraw, + DrawablePtr pDraw, int type, XID drawId, __GLcontextModes *modes) { @@ -131,7 +131,8 @@ __glXMesaScreenCreateDrawable(__GLXscreen *screen, memset(glxPriv, 0, sizeof *glxPriv); - if (!__glXDrawableInit(&glxPriv->base, screen, pDraw, drawId, modes)) { + if (!__glXDrawableInit(&glxPriv->base, screen, + pDraw, type, drawId, modes)) { xfree(glxPriv); return NULL; } @@ -140,7 +141,7 @@ __glXMesaScreenCreateDrawable(__GLXscreen *screen, glxPriv->base.resize = __glXMesaDrawableResize; glxPriv->base.swapBuffers = __glXMesaDrawableSwapBuffers; - xm_vis = find_mesa_visual(screen, modes->visualID); + xm_vis = find_mesa_visual(screen, modes->fbconfigID); if (xm_vis == NULL) { ErrorF("find_mesa_visual returned NULL for visualID = 0x%04x\n", modes->visualID); @@ -154,6 +155,11 @@ __glXMesaScreenCreateDrawable(__GLXscreen *screen, glxPriv->xm_buf = XMesaCreatePixmapBuffer(xm_vis, (PixmapPtr)pDraw, 0); } + if (glxPriv->xm_buf == NULL) { + xfree(glxPriv); + return NULL; + } + return &glxPriv->base; } @@ -234,7 +240,7 @@ __glXMesaScreenCreateContext(__GLXscreen *screen, context->base.copy = __glXMesaContextCopy; context->base.forceCurrent = __glXMesaContextForceCurrent; - xm_vis = find_mesa_visual(screen, modes->visualID); + xm_vis = find_mesa_visual(screen, modes->fbconfigID); if (!xm_vis) { ErrorF("find_mesa_visual returned NULL for visualID = 0x%04x\n", modes->visualID); @@ -259,7 +265,7 @@ __glXMesaScreenDestroy(__GLXscreen *screen) int i; if (mesaScreen->xm_vis) { - for (i = 0; i < mesaScreen->num_vis; i++) { + for (i = 0; i < mesaScreen->base.numFBConfigs; i++) { if (mesaScreen->xm_vis[i]) XMesaDestroyVisual(mesaScreen->xm_vis[i]); } @@ -273,104 +279,122 @@ __glXMesaScreenDestroy(__GLXscreen *screen) } static XMesaVisual -find_mesa_visual(__GLXscreen *screen, VisualID vid) +find_mesa_visual(__GLXscreen *screen, XID fbconfigID) { __GLXMESAscreen *mesaScreen = (__GLXMESAscreen *) screen; const __GLcontextModes *modes; unsigned i = 0; - for ( modes = screen->modes ; modes != NULL ; modes = modes->next ) { - if ( modes->visualID == vid ) { - break; - } - + for (modes = screen->fbconfigs; modes != NULL; modes = modes->next) { + if (modes->fbconfigID == fbconfigID) + return mesaScreen->xm_vis[i]; i++; } - return (modes != NULL) ? mesaScreen->xm_vis[i] : NULL; + return NULL; } -static void init_screen_visuals(__GLXMESAscreen *screen) +const static int numBack = 2; +const static int numDepth = 2; +const static int numStencil = 2; + +static __GLcontextModes * +createFBConfigsForVisual(__GLXscreen *screen, ScreenPtr pScreen, + VisualPtr visual, __GLcontextModes *config) { - ScreenPtr pScreen = screen->base.pScreen; - __GLcontextModes *modes; - XMesaVisual *pXMesaVisual; - int *used; - int i, j, size; - - /* Alloc space for the list of XMesa visuals */ - size = screen->base.numVisuals * sizeof(XMesaVisual); - pXMesaVisual = (XMesaVisual *) xalloc(size); - memset(pXMesaVisual, 0, size); - - /* FIXME: Change 'used' to be a array of bits (rather than of ints), - * FIXME: create a stack array of 8 or 16 bytes. If 'numVisuals' is less - * FIXME: than 64 or 128 the stack array can be used instead of calling - * FIXME: __glXMalloc / __glXFree. If nothing else, convert 'used' to - * FIXME: array of bytes instead of ints! - */ - used = (int *) xalloc(pScreen->numVisuals * sizeof(int)); - memset(used, 0, pScreen->numVisuals * sizeof(int)); + int back, depth, stencil; + + /* FIXME: Ok, I'm making all this up... anybody has a better idea? */ + + for (back = numBack - 1; back >= 0; back--) + for (depth = 0; depth < numDepth; depth++) + for (stencil = 0; stencil < numStencil; stencil++) { + config->visualType = _gl_convert_from_x_visual_type(visual->class); + config->xRenderable = GL_TRUE; + config->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT; + config->rgbMode = (visual->class >= TrueColor); + config->colorIndexMode = !config->rgbMode; + config->renderType = + (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; + config->doubleBufferMode = back; + config->haveDepthBuffer = depth; + config->depthBits = depth ? visual->nplanes : 0; + config->haveStencilBuffer = stencil; + config->stencilBits = stencil ? visual->bitsPerRGBValue : 0; + config->haveAccumBuffer = 0; + + config->redBits = Ones(visual->redMask); + config->greenBits = Ones(visual->greenMask); + config->blueBits = Ones(visual->blueMask); + config->alphaBits = 0; + config->redMask = visual->redMask; + config->greenMask = visual->greenMask; + config->blueMask = visual->blueMask; + config->alphaMask = 0; + config->rgbBits = config->rgbMode ? visual->nplanes : 0; + config->indexBits = config->colorIndexMode ? visual->nplanes : 0; + config = config->next; + } + + return config; +} + +static void +createFBConfigs(__GLXscreen *pGlxScreen, ScreenPtr pScreen) +{ + __GLcontextModes *configs; + int i; + + /* We assume here that each existing visual correspond to a + * different visual class. Note, this runs before COMPOSITE adds + * its visual, so it's not entirely crazy. */ + pGlxScreen->numFBConfigs = pScreen->numVisuals * numBack * numDepth * numStencil; + pGlxScreen->fbconfigs = _gl_context_modes_create(pGlxScreen->numFBConfigs, + sizeof *configs); + + configs = pGlxScreen->fbconfigs; + for (i = 0; i < pScreen->numVisuals; i++) + configs = createFBConfigsForVisual(pGlxScreen, pScreen, + &pScreen->visuals[i], configs); +} + +static void +createMesaVisuals(__GLXMESAscreen *pMesaScreen) +{ + __GLcontextModes *config; + ScreenPtr pScreen; + VisualPtr visual = NULL; + int i, j; i = 0; - for ( modes = screen->base.modes; modes != NULL; modes = modes->next ) { - const int vis_class = _gl_convert_to_x_visual_type( modes->visualType ); - const int nplanes = (modes->rgbBits - modes->alphaBits); - const VisualPtr pVis = pScreen->visuals; - - for (j = 0; j < pScreen->numVisuals; j++) { - if (pVis[j].class == vis_class && - pVis[j].nplanes == nplanes && - pVis[j].redMask == modes->redMask && - pVis[j].greenMask == modes->greenMask && - pVis[j].blueMask == modes->blueMask && - !used[j]) { - - /* Create the XMesa visual */ - pXMesaVisual[i] = - XMesaCreateVisual(pScreen, - &pVis[j], - modes->rgbMode, - (modes->alphaBits > 0), - modes->doubleBufferMode, - modes->stereoMode, - GL_TRUE, /* ximage_flag */ - modes->depthBits, - modes->stencilBits, - modes->accumRedBits, - modes->accumGreenBits, - modes->accumBlueBits, - modes->accumAlphaBits, - modes->samples, - modes->level, - modes->visualRating); - /* Set the VisualID */ - modes->visualID = pVis[j].vid; - - /* Mark this visual used */ - used[j] = 1; + pScreen = pMesaScreen->base.pScreen; + pMesaScreen->xm_vis = + xcalloc(pMesaScreen->base.numFBConfigs, sizeof (XMesaVisual)); + for (config = pMesaScreen->base.fbconfigs; config != NULL; config = config->next) { + for (j = 0; j < pScreen->numVisuals; j++) + if (pScreen->visuals[j].vid == config->visualID) { + visual = &pScreen->visuals[j]; break; } - } - - if ( j == pScreen->numVisuals ) { - ErrorF("No matching visual for __GLcontextMode with " - "visual class = %d (%d), nplanes = %u\n", - vis_class, - modes->visualType, - (modes->rgbBits - modes->alphaBits) ); - } - else if ( modes->visualID == -1 ) { - FatalError( "Matching visual found, but visualID still -1!\n" ); - } - i++; + pMesaScreen->xm_vis[i++] = + XMesaCreateVisual(pScreen, + visual, + config->rgbMode, + (config->alphaBits > 0), + config->doubleBufferMode, + config->stereoMode, + GL_TRUE, /* ximage_flag */ + config->depthBits, + config->stencilBits, + config->accumRedBits, + config->accumGreenBits, + config->accumBlueBits, + config->accumAlphaBits, + config->samples, + config->level, + config->visualRating); } - - xfree(used); - - screen->num_vis = pScreen->numVisuals; - screen->xm_vis = pXMesaVisual; } static __GLXscreen * @@ -382,19 +406,22 @@ __glXMesaScreenProbe(ScreenPtr pScreen) if (screen == NULL) return NULL; + /* + * Find the GLX visuals that are supported by this screen and create + * XMesa's visuals. + */ + createFBConfigs(&screen->base, pScreen); + __glXScreenInit(&screen->base, pScreen); + /* Now that GLX has created the corresponding X visual, create the mesa visuals. */ + createMesaVisuals(screen); + screen->base.destroy = __glXMesaScreenDestroy; screen->base.createContext = __glXMesaScreenCreateContext; screen->base.createDrawable = __glXMesaScreenCreateDrawable; screen->base.pScreen = pScreen; - /* - * Find the GLX visuals that are supported by this screen and create - * XMesa's visuals. - */ - init_screen_visuals(screen); - return &screen->base; } |