summaryrefslogtreecommitdiff
path: root/GL/glx/glxglcore.c
diff options
context:
space:
mode:
Diffstat (limited to 'GL/glx/glxglcore.c')
-rw-r--r--GL/glx/glxglcore.c209
1 files changed, 116 insertions, 93 deletions
diff --git a/GL/glx/glxglcore.c b/GL/glx/glxglcore.c
index fd4e57d59..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->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 num_vis, 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));
-
- num_vis = 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 */
- 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;
-
- /* Mark this visual used */
- used[j] = 1;
- break;
+ 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;
}
- }
- 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" );
- }
+ return config;
+}
- num_vis++;
- }
+static void
+createFBConfigs(__GLXscreen *pGlxScreen, ScreenPtr pScreen)
+{
+ __GLcontextModes *configs;
+ int i;
- xfree(used);
+ /* 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);
+}
- screen->num_vis = num_vis;
- screen->xm_vis = pXMesaVisual;
+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;
+ }
- assert(screen->num_vis <= screen->base.numVisuals);
+ 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);
+ }
}
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;
}