1. Right now libGLcore has several entry-points for getting GLX visual information into the driver. The file programs/Xserver/GL/mesa/X/xf86glx.c contains all of this interface. The interface functions are __MESA_initVisuals, __MESA_setVisualConfigs, and __MESA_screenProbe. __MESA_screenProbe is analogous to __driCreateNewScreen. The other two functions server part of the purpose of __driCreateNewScreen, but they also do some work not related to the driver. They create a list of X (not GLX) visuals to give back to the X server. That functionality should be moved into libglx.a.
2. Mesa's X11 driver, which is the basis of libGLcore, depends on information from an X VisualInfo. Most of the uses can be eliminated trivially, but the depth / nplanes and ColomapEntries / colormap_size fields are another story. The problem here is that the __driCreateNewScreen doesn't, and can't, provide VIsualInfo structures to the driver.
3. libglx.a calls functions in directly instead of using a dispatch table. Let me clarify this a bit. On the client-side, the symbol glVertex3f is libGL.so. When an app calls that function, it looks up the "real" function and calls it. On the server-side, the symbol glVertex3f is in libGLcore.so (i.e., the driver). When a glVertex3f protocol message comes in, libglx.a calls this function directly. This function then may (or may not, as in the case of the Mac OS X libGLcore.a) do a dispatch table look-up. What should happen is the protocol functions should do the dispatch table look-up and call the function from the table.
Those are the big issues that I could find. The rest of it just looks like changing function parameters and data structures, or moving code from libGLcore to libglx. I've attached a patch that removes some of the dependance on the VisualInfo structure and removes some redundant fields from the mesa_visual structure. Unless there are objections, I will commit this soon. I've only tested this with stand-alone Mesa so far.
Index: include/GL/xmesa_x.h =================================================================== RCS file: /cvs/mesa/Mesa/include/GL/xmesa_x.h,v retrieving revision 1.3 diff -u -d -r1.3 xmesa_x.h --- include/GL/xmesa_x.h 5 Jun 2003 00:50:26 -0000 1.3 +++ include/GL/xmesa_x.h 16 Feb 2004 20:55:20 -0000 @@ -74,16 +74,11 @@ #define XMesaFreeGC XFreeGC #define GET_COLORMAP_SIZE(__v) __v->visinfo->colormap_size -#define GET_REDMASK(__v) __v->visinfo->red_mask -#define GET_GREENMASK(__v) __v->visinfo->green_mask -#define GET_BLUEMASK(__v) __v->visinfo->blue_mask -#if defined(__cplusplus) || defined(c_plusplus) -#define GET_VISUAL_CLASS(__v) __v->visinfo->c_class -#else -#define GET_VISUAL_CLASS(__v) __v->visinfo->class -#endif +#define GET_REDMASK(__v) __v->mesa_visual.redMask +#define GET_GREENMASK(__v) __v->mesa_visual.greenMask +#define GET_BLUEMASK(__v) __v->mesa_visual.blueMask #define GET_VISUAL_DEPTH(__v) __v->visinfo->depth -#define GET_BLACK_PIXEL(__v) BlackPixel(__v->display, __v->visinfo->screen) +#define GET_BLACK_PIXEL(__v) BlackPixel(__v->display, __v->mesa_visual.screen) #define CHECK_BYTE_ORDER(__v) host_byte_order()==ImageByteOrder(__v->display) #define CHECK_FOR_HPCR(__v) XInternAtom(__v->display, "_HP_RGB_SMOOTH_MAP_LIST", True) Index: include/GL/xmesa_xf86.h =================================================================== RCS file: /cvs/mesa/Mesa/include/GL/xmesa_xf86.h,v retrieving revision 1.6 diff -u -d -r1.6 xmesa_xf86.h --- include/GL/xmesa_xf86.h 5 Jun 2003 00:50:26 -0000 1.6 +++ include/GL/xmesa_xf86.h 16 Feb 2004 20:55:20 -0000 @@ -175,10 +175,9 @@ } while (0) #define GET_COLORMAP_SIZE(__v) __v->visinfo->ColormapEntries -#define GET_REDMASK(__v) __v->visinfo->redMask -#define GET_GREENMASK(__v) __v->visinfo->greenMask -#define GET_BLUEMASK(__v) __v->visinfo->blueMask -#define GET_VISUAL_CLASS(__v) __v->visinfo->class +#define GET_REDMASK(__v) __v->mesa_visual.redMask +#define GET_GREENMASK(__v) __v->mesa_visual.greenMask +#define GET_BLUEMASK(__v) __v->mesa_visual.blueMask #define GET_VISUAL_DEPTH(__v) __v->visinfo->nplanes #define GET_BLACK_PIXEL(__v) __v->display->blackPixel #define CHECK_BYTE_ORDER(__v) GL_TRUE Index: src/mesa/drivers/x11/fakeglx.c =================================================================== RCS file: /cvs/mesa/Mesa/src/mesa/drivers/x11/fakeglx.c,v retrieving revision 1.89 diff -u -d -r1.89 fakeglx.c --- src/mesa/drivers/x11/fakeglx.c 8 Feb 2004 00:11:14 -0000 1.89 +++ src/mesa/drivers/x11/fakeglx.c 16 Feb 2004 20:55:20 -0000 @@ -296,7 +296,7 @@ for (i=0; i<NumVisuals; i++) { XMesaVisual v = VisualTable[i]; if (v->display == dpy - && v->level == level + && v->mesa_visual.level == level && v->ximage_flag == ximageFlag && v->mesa_visual.rgbMode == rgbFlag && v->mesa_visual.doubleBufferMode == dbFlag @@ -1559,7 +1559,7 @@ *value = xmvis->visinfo->depth; return 0; case GLX_LEVEL: - *value = xmvis->level; + *value = xmvis->mesa_visual.level; return 0; case GLX_RGBA: if (xmvis->mesa_visual.rgbMode) { @@ -1623,11 +1623,11 @@ } return 0; case GLX_TRANSPARENT_TYPE_EXT: - if (xmvis->level==0) { + if (xmvis->mesa_visual.level==0) { /* normal planes */ *value = GLX_NONE_EXT; } - else if (xmvis->level>0) { + else if (xmvis->mesa_visual.level>0) { /* overlay */ if (xmvis->mesa_visual.rgbMode) { *value = GLX_TRANSPARENT_RGB_EXT; @@ -1636,7 +1636,7 @@ *value = GLX_TRANSPARENT_INDEX_EXT; } } - else if (xmvis->level<0) { + else if (xmvis->mesa_visual.level<0) { /* underlay */ *value = GLX_NONE_EXT; } @@ -1668,8 +1668,8 @@ */ case GLX_VISUAL_CAVEAT_EXT: /* test for zero, just in case */ - if (xmvis->VisualCaveat > 0) - *value = xmvis->VisualCaveat; + if (xmvis->mesa_visual.visualRating > 0) + *value = xmvis->mesa_visual.visualRating; else *value = GLX_NONE_EXT; return 0; Index: src/mesa/drivers/x11/xm_api.c =================================================================== RCS file: /cvs/mesa/Mesa/src/mesa/drivers/x11/xm_api.c,v retrieving revision 1.64 diff -u -d -r1.64 xm_api.c --- src/mesa/drivers/x11/xm_api.c 20 Jan 2004 02:49:29 -0000 1.64 +++ src/mesa/drivers/x11/xm_api.c 16 Feb 2004 20:55:20 -0000 @@ -1200,26 +1200,25 @@ * being color indexed. This is weird but might be useful to someone. */ v->dithered_pf = v->undithered_pf = PF_Index; - v->index_bits = GET_VISUAL_DEPTH(v); + v->mesa_visual.indexBits = GET_VISUAL_DEPTH(v); } else { /* RGB WINDOW: * We support RGB rendering into almost any kind of visual. */ - int xclass; - xclass = GET_VISUAL_CLASS(v); - if (xclass==TrueColor || xclass==DirectColor) { + const int xclass = v->mesa_visual.visualType; + if (xclass==GLX_TRUE_COLOR || xclass==GLX_DIRECT_COLOR) { setup_truecolor( v, b, cmap ); } - else if (xclass==StaticGray && GET_VISUAL_DEPTH(v)==1) { + else if (xclass==GLX_STATIC_GRAY && GET_VISUAL_DEPTH(v)==1) { setup_monochrome( v, b ); } - else if (xclass==GrayScale || xclass==StaticGray) { + else if (xclass==GLX_GRAY_SCALE || xclass==GLX_STATIC_GRAY) { if (!setup_grayscale( client, v, b, cmap )) { return GL_FALSE; } } - else if ((xclass==PseudoColor || xclass==StaticColor) + else if ((xclass==GLX_PSEUDO_COLOR || xclass==GLX_STATIC_COLOR) && GET_VISUAL_DEPTH(v)>=4 && GET_VISUAL_DEPTH(v)<=16) { if (!setup_dithered_color( client, v, b, cmap )) { return GL_FALSE; @@ -1229,7 +1228,7 @@ _mesa_warning(NULL, "XMesa: RGB mode rendering not supported in given visual."); return GL_FALSE; } - v->index_bits = 0; + v->mesa_visual.indexBits = 0; if (_mesa_getenv("MESA_NO_DITHER")) { v->dithered_pf = v->undithered_pf; @@ -1246,7 +1245,7 @@ _mesa_printf("X/Mesa visual = %p\n", (void *) v); _mesa_printf("X/Mesa dithered pf = %u\n", v->dithered_pf); _mesa_printf("X/Mesa undithered pf = %u\n", v->undithered_pf); - _mesa_printf("X/Mesa level = %d\n", v->level); + _mesa_printf("X/Mesa level = %d\n", v->mesa_visual.level); _mesa_printf("X/Mesa depth = %d\n", GET_VISUAL_DEPTH(v)); _mesa_printf("X/Mesa bits per pixel = %d\n", v->BitsPerPixel); } @@ -1410,6 +1409,34 @@ } +#define NUM_VISUAL_TYPES 6 + +/** + * Convert an X visual type to a GLX visual type. + * + * \param visualType X visual type (i.e., \c TrueColor, \c StaticGray, etc.) + * to be converted. + * \return If \c visualType is a valid X visual type, a GLX visual type will + * be returned. Otherwise \c GLX_NONE will be returned. + * + * \note + * This code was lifted directly from lib/GL/glx/glcontextmodes.c in the + * DRI CVS tree. + */ +static GLint +xmesa_convert_from_x_visual_type( int visualType ) +{ + static const int glx_visual_types[ NUM_VISUAL_TYPES ] = { + GLX_STATIC_GRAY, GLX_GRAY_SCALE, + GLX_STATIC_COLOR, GLX_PSEUDO_COLOR, + GLX_TRUE_COLOR, GLX_DIRECT_COLOR + }; + + return ( (unsigned) visualType < NUM_VISUAL_TYPES ) + ? glx_visual_types[ visualType ] : GLX_NONE; +} + + /**********************************************************************/ /***** Public Functions *****/ /**********************************************************************/ @@ -1499,19 +1526,6 @@ MEMCPY(v->visinfo, visinfo, sizeof(*visinfo)); #endif -#ifdef XFree86Server - /* Initialize the depth of the screen */ - { - PixmapFormatRec *format; - - for (format = screenInfo.formats; - format->depth != display->rootDepth; - format++) - ; - v->screen_depth = format->bitsPerPixel; - } -#endif - /* check for MESA_GAMMA environment variable */ gamma = _mesa_getenv("MESA_GAMMA"); if (gamma) { @@ -1526,15 +1540,32 @@ } v->ximage_flag = ximage_flag; - v->level = level; - v->VisualCaveat = visualCaveat; + +#ifdef XFree86Server + v->mesa_visual.redMask = visinfo->redMask; + v->mesa_visual.greenMask = visinfo->greenMask; + v->mesa_visual.blueMask = visinfo->blueMask; +#else + v->mesa_visual.redMask = visinfo->red_mask; + v->mesa_visual.greenMask = visinfo->green_mask; + v->mesa_visual.blueMask = visinfo->blue_mask; +#endif + +#if defined(XFree86Server) || !(defined(__cplusplus) || defined(c_plusplus)) + v->mesa_visual.visualType = xmesa_convert_from_x_visual_type(visinfo->class); +#else + v->mesa_visual.visualType = xmesa_convert_from_x_visual_type(visinfo->c_class); +#endif + + v->mesa_visual.visualRating = visualCaveat; + v->mesa_visual.visualID = visinfo->visualid; + v->mesa_visual.screen = visinfo->screen; (void) initialize_visual_and_buffer( 0, v, NULL, rgb_flag, 0, 0 ); { - int xclass; - xclass = GET_VISUAL_CLASS(v); - if (xclass==TrueColor || xclass==DirectColor) { + const int xclass = v->mesa_visual.visualType; + if (xclass==GLX_TRUE_COLOR || xclass==GLX_DIRECT_COLOR) { red_bits = bitcount(GET_REDMASK(v)); green_bits = bitcount(GET_GREENMASK(v)); blue_bits = bitcount(GET_BLUEMASK(v)); @@ -1561,12 +1592,14 @@ rgb_flag, db_flag, stereo_flag, red_bits, green_bits, blue_bits, alpha_bits, - v->index_bits, + v->mesa_visual.indexBits, depth_size, stencil_size, accum_red_size, accum_green_size, accum_blue_size, accum_alpha_size, 0 ); + + v->mesa_visual.level = level; return v; } @@ -1837,13 +1870,14 @@ } -/* +/** * Create a new XMesaBuffer from an X pixmap. - * Input: v - the XMesaVisual - * p - the pixmap - * cmap - the colormap, may be 0 if using a TrueColor or DirectColor - * visual for the pixmap - * Return: new XMesaBuffer or NULL if error + * + * \param v the XMesaVisual + * \param p the pixmap + * \param cmap the colormap, may be 0 if using a \c GLX_TRUE_COLOR or + * \c GLX_DIRECT_COLOR visual for the pixmap + * \returns new XMesaBuffer or NULL if error */ XMesaBuffer XMesaCreatePixmapBuffer( XMesaVisual v, XMesaPixmap p, XMesaColormap cmap ) Index: src/mesa/drivers/x11/xm_dd.c =================================================================== RCS file: /cvs/mesa/Mesa/src/mesa/drivers/x11/xm_dd.c,v retrieving revision 1.59 diff -u -d -r1.59 xm_dd.c --- src/mesa/drivers/x11/xm_dd.c 20 Jan 2004 02:49:29 -0000 1.59 +++ src/mesa/drivers/x11/xm_dd.c 16 Feb 2004 20:55:20 -0000 @@ -214,10 +214,10 @@ GLboolean rmask, GLboolean gmask, GLboolean bmask, GLboolean amask) { const XMesaContext xmesa = XMESA_CONTEXT(ctx); - int xclass = GET_VISUAL_CLASS(xmesa->xm_visual); + const int xclass = xmesa->xm_visual->mesa_visual.visualType; (void) amask; - if (xclass == TrueColor || xclass == DirectColor) { + if (xclass == GLX_TRUE_COLOR || xclass == GLX_DIRECT_COLOR) { unsigned long m; if (rmask && gmask && bmask) { m = ((unsigned long)~0L); Index: src/mesa/drivers/x11/xmesaP.h =================================================================== RCS file: /cvs/mesa/Mesa/src/mesa/drivers/x11/xmesaP.h,v retrieving revision 1.39 diff -u -d -r1.39 xmesaP.h --- src/mesa/drivers/x11/xmesaP.h 20 Jan 2004 02:49:29 -0000 1.39 +++ src/mesa/drivers/x11/xmesaP.h 16 Feb 2004 20:55:20 -0000 @@ -86,17 +86,12 @@ struct xmesa_visual { GLvisual mesa_visual; /* Device independent visual parameters */ XMesaDisplay *display; /* The X11 display */ -#ifdef XFree86Server - GLint screen_depth; /* The depth of the screen */ -#else +#ifndef XFree86Server XVisualInfo *vishandle; /* Only used in fakeglx.c */ #endif XMesaVisualInfo visinfo; /* X's visual info (pointer to private copy) */ GLint BitsPerPixel; /* True bits per pixel for XImages */ - GLint level; /* 0=normal, 1=overlay, etc */ - GLint VisualCaveat; /* for GLX_EXT_visual_rating extension */ - GLboolean ximage_flag; /* Use XImage for back buffer (not pixmap)? */ enum pixel_format dithered_pf; /* Pixel format when dithering */ @@ -106,9 +101,6 @@ GLfloat GreenGamma; GLfloat BlueGamma; - GLint rmult, gmult, bmult; /* Range of color values */ - GLint index_bits; /* Bits per pixel in CI mode */ - /* For PF_TRUECOLOR */ GLint rshift, gshift, bshift;/* Pixel color component shifts */ GLubyte Kernel[16]; /* Dither kernel */