From 89c6108531e603bdc81faf2ea860f318a2e94a39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 19 Oct 2007 16:21:54 -0400 Subject: [PATCH] Fix software GL to provide a list of supported fbconfigs like the DRI case. --- GL/glx/glxglcore.c | 201 ++++++++++++++++++++++++-------------------- GL/glx/glxscreens.c | 28 +++--- 2 files changed, 126 insertions(+), 103 deletions(-) diff --git a/GL/glx/glxglcore.c b/GL/glx/glxglcore.c index b50967a16..6aa4e7f5c 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 @@ -141,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); @@ -155,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; } @@ -235,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); @@ -274,107 +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->fbconfigs ; 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 num_vis, j, size; + int back, depth, stencil; - /* Alloc space for the list of XMesa visuals */ - size = screen->base.numVisuals * sizeof(XMesaVisual); - pXMesaVisual = (XMesaVisual *) xalloc(size); - memset(pXMesaVisual, 0, size); + /* FIXME: Ok, I'm making all this up... anybody has a better idea? */ - /* 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)); + 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; - num_vis = 0; - for ( modes = screen->base.fbconfigs; 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; + 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; + } - 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]) { + return config; +} - /* Create the XMesa visual */ - assert(num_vis < screen->base.numVisuals); - pXMesaVisual[num_vis] = - 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; +static void +createFBConfigs(__GLXscreen *pGlxScreen, ScreenPtr pScreen) +{ + __GLcontextModes *configs; + int i; - /* Mark this visual used */ - used[j] = 1; + /* 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; + int i, j; + + i = 0; + 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" ); - } - - num_vis++; + 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 = num_vis; - screen->xm_vis = pXMesaVisual; - - assert(screen->num_vis <= screen->base.numVisuals); } static __GLXscreen * @@ -386,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; } diff --git a/GL/glx/glxscreens.c b/GL/glx/glxscreens.c index 511aa8ad9..2c8f810e6 100644 --- a/GL/glx/glxscreens.c +++ b/GL/glx/glxscreens.c @@ -469,8 +469,6 @@ addFullSet(__GLXscreen *pGlxScreen) return; } - ErrorF("addFullSet, setting numVisuals to %d\n", pGlxScreen->numFBConfigs); - pGlxScreen->numVisuals = pGlxScreen->numFBConfigs; for (i = 0, config = pGlxScreen->fbconfigs; config; config = config->next, i++) { pGlxScreen->visuals[i] = config; @@ -500,10 +498,24 @@ void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen) glxGeneration = serverGeneration; } + pGlxScreen->pScreen = pScreen; + pGlxScreen->GLextensions = xstrdup(GLServerExtensions); + pGlxScreen->GLXvendor = xstrdup(GLXServerVendorName); + pGlxScreen->GLXversion = xstrdup(GLXServerVersion); + pGlxScreen->GLXextensions = xstrdup(GLXServerExtensions); + + pGlxScreen->PositionWindow = pScreen->PositionWindow; + pScreen->PositionWindow = glxPositionWindow; + + pGlxScreen->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = glxCloseScreen; + i = 0; for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) { m->fbconfigID = FakeClientID(0); m->visualID = findVisualForConfig(pScreen, m); + ErrorF("mapping fbconfig id 0x%02lx to visual id 0x%02lx\n", + m->fbconfigID, m->visualID); i++; } pGlxScreen->numFBConfigs = i; @@ -526,18 +538,6 @@ void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen) break; } - pGlxScreen->pScreen = pScreen; - pGlxScreen->GLextensions = xstrdup(GLServerExtensions); - pGlxScreen->GLXvendor = xstrdup(GLXServerVendorName); - pGlxScreen->GLXversion = xstrdup(GLXServerVersion); - pGlxScreen->GLXextensions = xstrdup(GLXServerExtensions); - - pGlxScreen->PositionWindow = pScreen->PositionWindow; - pScreen->PositionWindow = glxPositionWindow; - - pGlxScreen->CloseScreen = pScreen->CloseScreen; - pScreen->CloseScreen = glxCloseScreen; - pScreen->devPrivates[glxScreenPrivateIndex].ptr = (pointer) pGlxScreen; }