Hello,
this is hopefully the final version of the per-screen dynamic GLX
extensions patch. Major changes from the last version:
- per-screen data in __GLXscreenConfigs
- __DRIscreen has an opaque pointer back to the screenConfigs
- Bumped the internal libGL API version to 20030813
- __glXExtensionBitIsEnabled must be per-screen too
- requires two helper functions to find the __GLXscreenConfigs from
either a GLXcontext or a display, screen pair
- Updated some comments in glxextensions.c
To test that the screen finding functions actually work as expected we
should test at least one of the SwapInverval-related extensions and one
of the FBConfig-related ones. Can someone point me to some simple test
cases. I remember some posts about glxgears with SwapInterval support.
Is that in Mesa CVS? It is a bit inconvenient for me to download a whole
mesa CVS tree through a modem connection. Ian, IIRC you made those
changes in glxgears. Could you send me only the updated glxgears source?
Regards,
Felix
------------ __\|/__ ___ ___ -------------------------
Felix ___\_e -_/___/ __\___/ __\_____ You can do anything,
K�hling (_____\�/____/ /_____/ /________) just not everything
[EMAIL PROTECTED] \___/ \___/ U at the same time.
? dri/DONE
? dri/Makefile
? dri/drm/DONE
? dri/drm/Makefile
? glx/DONE
? glx/Makefile
? glx/glxextensions.patch
? glx/glxextensions2.patch
Index: dri/dri_glx.c
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/dri/dri_glx.c,v
retrieving revision 1.29.4.1
diff -u -r1.29.4.1 dri_glx.c
--- dri/dri_glx.c 26 May 2003 17:41:59 -0000 1.29.4.1
+++ dri/dri_glx.c 14 Aug 2003 16:31:27 -0000
@@ -230,8 +230,6 @@
dlclose(handle);
continue;
}
- driver->registerExtensionsFunc = (RegisterExtensionsFunc)
- dlsym(handle, "__driRegisterExtensions");
driver->handle = handle;
/* put at head of linked list */
driver->next = Drivers;
@@ -435,7 +433,6 @@
* driver's "__driCreateScreen" function pointer. That's the bootstrap
* entrypoint for all DRI drivers.
*/
- __glXRegisterExtensions();
for (scrn = 0; scrn < numScreens; scrn++) {
__DRIdriver *driver = driGetDriver(dpy, scrn);
if (driver) {
@@ -451,71 +448,5 @@
return (void *)pdpyp;
}
-
-
-
-/*
-** Here we'll query the DRI driver for each screen and let each
-** driver register its GL extension functions. We only have to
-** do this once.
-**
-** In older versions of libGL (prior to October 2002) we _always_
-** called this function during libGL start-up. Now, we only call
-** it from glXGetProcAddress() as a last resort.
-**
-** Two key things changed along the way:
-** 1. _glapi_get_proc_address() now generates new dispatch stub functions
-** anytime it gets an unknown "gl*" function name. I.e. we always return
-** a valid function address and later patch it up to use the correct
-** dispatch offset.
-** 2. The GL API dispatch table is a fixed size (with plenty of extra slots).
-** This means we don't have to register all new functions before we create
-** the first dispatch table.
-*/
-void
-__glXRegisterExtensions(void)
-{
-#ifndef BUILT_IN_DRI_DRIVER
- static GLboolean alreadyCalled = GL_FALSE;
- int displayNum, maxDisplays;
-
- if (alreadyCalled)
- return;
- alreadyCalled = GL_TRUE;
-
- if (getenv("LIBGL_MULTIHEAD")) {
- /* we'd like to always take this path but doing so causes a second
- * or more of delay while the XOpenDisplay() function times out.
- */
- maxDisplays = 10; /* infinity, really */
- }
- else {
- /* just open the :0 display */
- maxDisplays = 1;
- }
-
- for (displayNum = 0; displayNum < maxDisplays; displayNum++) {
- char displayName[200];
- Display *dpy;
- snprintf(displayName, 199, ":%d.0", displayNum);
- dpy = XOpenDisplay(displayName);
- if (dpy) {
- const int numScreens = ScreenCount(dpy);
- int screenNum;
- for (screenNum = 0; screenNum < numScreens; screenNum++) {
- __DRIdriver *driver = driGetDriver(dpy, screenNum);
- if (driver && driver->registerExtensionsFunc) {
- (*driver->registerExtensionsFunc)();
- }
- }
- XCloseDisplay(dpy);
- }
- else {
- break;
- }
- }
-#endif
-}
-
#endif /* GLX_DIRECT_RENDERING */
Index: dri/dri_util.c
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/dri/dri_util.c,v
retrieving revision 1.13
diff -u -r1.13 dri_util.c
--- dri/dri_util.c 21 May 2003 17:32:04 -0000 1.13
+++ dri/dri_util.c 14 Aug 2003 16:31:42 -0000
@@ -1031,6 +1031,7 @@
if (!psp) {
return NULL;
}
+ psp->psc = psc;
psp->fullscreen = NULL;
psp->display = dpy;
psp->myNum = scrn;
Index: dri/dri_util.h
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/dri/dri_util.h,v
retrieving revision 1.8
diff -u -r1.8 dri_util.h
--- dri/dri_util.h 21 May 2003 17:32:05 -0000 1.8
+++ dri/dri_util.h 14 Aug 2003 16:31:46 -0000
@@ -406,6 +406,11 @@
*/
int numConfigs;
__GLXvisualConfig *configs;
+
+ /*
+ ** Point back to the containing __DRIscreen
+ */
+ __DRIscreen *psc;
};
Index: glx/glxclient.h
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/glx/glxclient.h,v
retrieving revision 1.28.2.1
diff -u -r1.28.2.1 glxclient.h
--- glx/glxclient.h 26 May 2003 17:41:59 -0000 1.28.2.1
+++ glx/glxclient.h 14 Aug 2003 16:31:54 -0000
@@ -167,6 +167,16 @@
** Added with internal API version "20030317".
*/
int (*getMSC)( void *screenPrivate, int64_t *msc );
+
+ /*
+ ** Opaque pointer that points back to the containing __GLXscreenConfigs.
+ ** This data structure is shared with DRI drivers but __GLXscreenConfigs
+ ** is not. However, they are needed by some GLX functions called by DRI
+ ** drivers.
+ **
+ ** Added with internal API version "20030813".
+ */
+ void *screenConfigs;
};
/*
@@ -292,8 +302,6 @@
typedef void *(*CreateScreenFunc)(Display *dpy, int scrn, __DRIscreen *psc,
int numConfigs, __GLXvisualConfig *config);
-typedef void *(*RegisterExtensionsFunc)(void);
-
/*
** We keep a linked list of these structures, one per DRI device driver.
*/
@@ -301,7 +309,6 @@
const char *name;
void *handle;
CreateScreenFunc createScreenFunc;
- RegisterExtensionsFunc registerExtensionsFunc;
struct __DRIdriverRec *next;
};
@@ -595,6 +602,11 @@
** Per screen direct rendering interface functions and data.
*/
__DRIscreen driScreen;
+ /*
+ ** Per screen dynamic client GLX extensions
+ */
+ unsigned char direct_support[8];
+ GLboolean ext_list_first_time;
#endif
} __GLXscreenConfigs;
@@ -641,6 +653,8 @@
#endif
};
+__GLXscreenConfigs *__glXFindGLXScreenConfigs(Display *dpy, int scrn);
+
void __glXFreeContext(__GLXcontext*);
extern GLubyte *__glXFlushRenderBuffer(__GLXcontext*, GLubyte*);
@@ -650,15 +664,6 @@
/* Initialize the GLX extension for dpy */
extern __GLXdisplayPrivate *__glXInitialize(Display*);
-
-/* Query drivers for dynamically registered extensions */
-extern void __glXRegisterExtensions(void);
-
-/* Functions for extending the GLX API: */
-extern void *__glXRegisterGLXFunction(const char *funcName, void *funcAddr);
-extern void __glXRegisterGLXExtensionString(const char *extName);
-typedef void * (* PFNGLXREGISTERGLXFUNCTIONPROC) ( const char * funcName,
- void * funcAdd );
/************************************************************************/
Index: glx/glxcmds.c
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/glx/glxcmds.c,v
retrieving revision 1.41.2.1
diff -u -r1.41.2.1 glxcmds.c
--- glx/glxcmds.c 26 May 2003 17:41:59 -0000 1.41.2.1
+++ glx/glxcmds.c 14 Aug 2003 16:32:24 -0000
@@ -104,6 +104,21 @@
static const char __glXGLXClientVersion[] = "1.2";
/****************************************************************************/
+
+static __GLXscreenConfigs *
+GetGLXScreenConfigs( GLXContext gc )
+{
+ __GLXscreenConfigs *psc = NULL;
+
+ if (gc != NULL) {
+ __GLXdisplayPrivate *priv = __glXInitialize(gc->currentDpy);
+ if (priv->screenConfigs)
+ psc = &priv->screenConfigs[gc->screen];
+ }
+
+ return psc;
+}
+
/**
* Get the write __DRIdrawable bound to the specificed GLXContext
*
@@ -1330,7 +1345,7 @@
screen, GLX_EXTENSIONS);
}
- psc->effectiveGLXexts = (char *) __glXGetUsableExtensions(psc->serverGLXexts);
+ psc->effectiveGLXexts = (char *) __glXGetUsableExtensions(psc,
psc->serverGLXexts);
}
return psc->effectiveGLXexts;
@@ -1872,7 +1887,10 @@
}
#ifdef GLX_DIRECT_RENDERING
- if ( gc->isDirect && __glXExtensionBitIsEnabled( SGI_swap_control_bit ) ) {
+ {
+ __GLXscreenConfigs *psc = GetGLXScreenConfigs( gc );
+ if ( gc->isDirect &&
+ __glXExtensionBitIsEnabled( psc, SGI_swap_control_bit ) ) {
__DRIdrawable *pdraw = GetDRIDrawable( gc );
if ( pdraw != NULL ) {
@@ -1880,6 +1898,7 @@
return 0;
}
}
+ }
#endif
dpy = gc->currentDpy;
opcode = __glXSetupForCommand(dpy);
@@ -1913,6 +1932,7 @@
{
#ifdef GLX_DIRECT_RENDERING
GLXContext gc = __glXGetCurrentContext();
+ __GLXscreenConfigs *psc = GetGLXScreenConfigs( gc );
__DRIdrawable *pdraw = GetDRIDrawable( gc );
if ( pdraw == NULL ) {
@@ -1923,7 +1943,7 @@
return GLX_BAD_VALUE;
}
- if ( __glXExtensionBitIsEnabled( MESA_swap_control_bit ) ) {
+ if ( __glXExtensionBitIsEnabled( psc, MESA_swap_control_bit ) ) {
pdraw->swap_interval = interval;
return 0;
}
@@ -1938,10 +1958,11 @@
{
#ifdef GLX_DIRECT_RENDERING
GLXContext gc = __glXGetCurrentContext();
+ __GLXscreenConfigs *psc = GetGLXScreenConfigs( gc );
__DRIdrawable *pdraw = GetDRIDrawable( gc );
- if ( pdraw && __glXExtensionBitIsEnabled( MESA_swap_control_bit ) ) {
+ if ( pdraw && __glXExtensionBitIsEnabled( psc, MESA_swap_control_bit ) ) {
return pdraw->swap_interval;
}
#endif
@@ -1959,10 +1980,12 @@
int status = GLX_BAD_CONTEXT;
#ifdef GLX_DIRECT_RENDERING
GLXContext gc = __glXGetCurrentContext();
+ __GLXscreenConfigs *psc = GetGLXScreenConfigs( gc );
__DRIdrawable *pdraw;
__GLXdisplayPrivate *priv;
- if ( (gc != NULL) && __glXExtensionBitIsEnabled( MESA_swap_frame_usage_bit ) ) {
+ if ( (gc != NULL) &&
+ __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) {
priv = __glXInitialize(gc->currentDpy);
if (priv->driDisplay.private) {
__GLXscreenConfigs *psc = &priv->screenConfigs[gc->screen];
@@ -1992,10 +2015,12 @@
int status = GLX_BAD_CONTEXT;
#ifdef GLX_DIRECT_RENDERING
GLXContext gc = __glXGetCurrentContext();
+ __GLXscreenConfigs *psc = GetGLXScreenConfigs( gc );
__DRIdrawable *pdraw;
__GLXdisplayPrivate *priv;
- if ( (gc != NULL) && __glXExtensionBitIsEnabled( MESA_swap_frame_usage_bit ) ) {
+ if ( (gc != NULL) &&
+ __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) {
priv = __glXInitialize(gc->currentDpy);
if (priv->driDisplay.private) {
__GLXscreenConfigs *psc = &priv->screenConfigs[gc->screen];
@@ -2026,10 +2051,11 @@
int status = GLX_BAD_CONTEXT;
#ifdef GLX_DIRECT_RENDERING
GLXContext gc = __glXGetCurrentContext();
+ __GLXscreenConfigs *psc = GetGLXScreenConfigs( gc );
__DRIdrawable *pdraw = GetDRIDrawable( gc );
if ( (pdraw != NULL ) && (pdraw->queryFrameTracking != NULL)
- && __glXExtensionBitIsEnabled( MESA_swap_frame_usage_bit ) ) {
+ && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) {
int64_t sbc, missedFrames;
float lastMissedUsage;
@@ -2053,10 +2079,11 @@
int status = GLX_BAD_CONTEXT;
#ifdef GLX_DIRECT_RENDERING
GLXContext gc = __glXGetCurrentContext();
+ __GLXscreenConfigs *psc = GetGLXScreenConfigs( gc );
__DRIdrawable *pdraw = GetDRIDrawable( gc );
if ( (pdraw != NULL ) && (pdraw->queryFrameTracking != NULL)
- && __glXExtensionBitIsEnabled( MESA_swap_frame_usage_bit ) ) {
+ && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) {
float usage;
status = pdraw->queryFrameTracking( dpy, pdraw->private, sbc,
@@ -2085,10 +2112,10 @@
*/
#ifdef GLX_DIRECT_RENDERING
GLXContext gc = __glXGetCurrentContext();
-
+ __GLXscreenConfigs *psc = GetGLXScreenConfigs( gc );
if ( (gc != NULL) && gc->isDirect
- && __glXExtensionBitIsEnabled( SGI_video_sync_bit ) ) {
+ && __glXExtensionBitIsEnabled( psc, SGI_video_sync_bit ) ) {
__GLXdisplayPrivate *priv = __glXInitialize(gc->currentDpy);
if (priv->driDisplay.private) {
__GLXscreenConfigs *psc = &priv->screenConfigs[gc->screen];
@@ -2112,13 +2139,14 @@
{
#ifdef GLX_DIRECT_RENDERING
GLXContext gc = __glXGetCurrentContext();
+ __GLXscreenConfigs *psc = GetGLXScreenConfigs( gc );
__DRIdrawable *pdraw = GetDRIDrawable( gc );
if ( divisor <= 0 || remainder < 0 )
return GLX_BAD_VALUE;
if (pdraw && pdraw->waitForMSC
- && __glXExtensionBitIsEnabled( SGI_video_sync_bit )) {
+ && __glXExtensionBitIsEnabled( psc, SGI_video_sync_bit )) {
int ret;
int64_t msc;
int64_t sbc;
@@ -2181,9 +2209,9 @@
GLXPixmap xid = None;
CARD8 opcode;
__GLXFBConfig * fbconfig = (__GLXFBConfig *) config;
+ __GLXscreenConfigs *psc = __glXFindGLXScreenConfigs( dpy, fbconfig->screen );
-
- if ( __glXExtensionBitIsEnabled( SGIX_fbconfig_bit ) ) {
+ if ( __glXExtensionBitIsEnabled( psc, SGIX_fbconfig_bit ) ) {
opcode = __glXSetupForCommand(dpy);
if (!opcode) {
return None;
@@ -2216,8 +2244,9 @@
__GLXdisplayPrivate *priv;
#endif
__GLXFBConfig * fbconfig = (__GLXFBConfig *) config;
+ __GLXscreenConfigs *psc = __glXFindGLXScreenConfigs( dpy, fbconfig->screen );
- if ( __glXExtensionBitIsEnabled( SGIX_fbconfig_bit ) ) {
+ if ( __glXExtensionBitIsEnabled( psc, SGIX_fbconfig_bit ) ) {
if (!dpy || !fbconfig)
return NULL;
@@ -2475,11 +2504,13 @@
{
#ifdef GLX_DIRECT_RENDERING
GLXContext gc = __glXGetCurrentContext();
+ __GLXscreenConfigs *psc = GetGLXScreenConfigs( gc );
__DRIdrawable *pdraw;
__GLXdisplayPrivate *priv;
int ret;
- if ( (gc != NULL) && __glXExtensionBitIsEnabled( OML_sync_control_bit ) ) {
+ if ( (gc != NULL) &&
+ __glXExtensionBitIsEnabled( psc, OML_sync_control_bit ) ) {
priv = __glXInitialize(gc->currentDpy);
if (priv->driDisplay.private) {
__GLXscreenConfigs *psc = &priv->screenConfigs[gc->screen];
@@ -2598,6 +2629,7 @@
{
#ifdef GLX_DIRECT_RENDERING
GLXContext gc = __glXGetCurrentContext();
+ __GLXscreenConfigs *psc = GetGLXScreenConfigs( gc );
__DRIdrawable *pdraw = GetDRIDrawable( gc );
/* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE
@@ -2610,7 +2642,7 @@
if ( divisor > 0 && remainder >= divisor )
return -1;
- if (pdraw && __glXExtensionBitIsEnabled( OML_sync_control_bit )) {
+ if (pdraw && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit )) {
return (*pdraw->swapBuffersMSC)(dpy, pdraw->private, target_msc,
divisor, remainder);
}
@@ -2632,6 +2664,7 @@
{
#ifdef GLX_DIRECT_RENDERING
GLXContext gc = __glXGetCurrentContext();
+ __GLXscreenConfigs *psc = GetGLXScreenConfigs( gc );
__DRIdrawable *pdraw = GetDRIDrawable( gc );
int ret;
@@ -2644,7 +2677,7 @@
return False;
if ( (pdraw != NULL) && (pdraw->waitForMSC != NULL)
- && __glXExtensionBitIsEnabled( OML_sync_control_bit )) {
+ && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit )) {
ret = (*pdraw->waitForMSC)( dpy, pdraw->private, target_msc,
divisor, remainder, msc, sbc );
@@ -2673,6 +2706,7 @@
{
#ifdef GLX_DIRECT_RENDERING
GLXContext gc = __glXGetCurrentContext();
+ __GLXscreenConfigs *psc = GetGLXScreenConfigs( gc );
__DRIdrawable *pdraw = GetDRIDrawable( gc );
int ret;
@@ -2683,7 +2717,7 @@
return False;
if ( (pdraw != NULL) && (pdraw->waitForSBC != NULL)
- && __glXExtensionBitIsEnabled( OML_sync_control_bit )) {
+ && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit )) {
ret = (*pdraw->waitForSBC)( dpy, pdraw->private, target_sbc, msc, sbc );
/* __glXGetUST returns zero on success and non-zero on failure.
@@ -2936,13 +2970,10 @@
{ "__glXInitialize", (GLvoid *) __glXInitialize, NULL },
{ "__glXFindDRIScreen", (GLvoid *) __glXFindDRIScreen, NULL },
{ "__glXGetInternalVersion", (GLvoid *) __glXGetInternalVersion, NULL },
- { "__glXRegisterGLXExtensionString", (GLvoid *) __glXRegisterGLXExtensionString,
NULL },
- { "__glXRegisterGLXFunction", (GLvoid *) __glXRegisterGLXFunction, NULL },
{ "__glXWindowExists", (GLvoid *) __glXWindowExists, NULL },
- { "__glXEnableExtension", (GLvoid *) __glXEnableExtension, NULL },
- { "__glXDisableExtension", (GLvoid *) __glXDisableExtension, NULL },
- { "__glXAddExtension", (GLvoid *) __glXAddExtension, NULL },
+ { "__glXScrEnableExtension", (GLvoid *) __glXScrEnableExtension, NULL },
+ { "__glXScrDisableExtension", (GLvoid *) __glXScrDisableExtension, NULL },
{ "__glXGetUST", (GLvoid *) __glXGetUST, NULL },
@@ -2950,85 +2981,11 @@
};
-static struct name_address_pair *Dynamic_GLX_functions = NULL;
-
-
-/*
- * Drivers can call this function to append the name of a new GLX
- * extension string to __glXGLXClientExtensions. Then, when the user
- * calls glXGetClientString() they'll see it listed.
- * This is a companion to __glXRegisterGLXFunction().
- */
-void
-__glXRegisterGLXExtensionString(const char *extName)
-{
- __glXEnableExtension( extName, GL_TRUE );
-}
-
-
-/**
- * DRI drivers should call this function if they want to extend
- * the GLX API. After registering a new GLX function, the user
- * can query and use it by calling \c glXGetProcAddress.
- *
- * \param funcName name of new GLX function
- * \param funcAddr pointer to the function
- * \return Address of previously registered function with this name or NULL.
- *
- * \sa __glXEnableExtension glXGetProcAddress
- */
-void *
-__glXRegisterGLXFunction(const char *funcName, void *funcAddr)
-{
- struct name_address_pair *ext;
-
- assert(funcName);
- assert(funcName[0] == 'g');
- assert(funcName[1] == 'l');
- assert(funcName[2] == 'X');
-
- /* look if the function is already registered */
- for (ext = Dynamic_GLX_functions; ext; ext = ext->Next) {
- if (strcmp(ext->Name, funcName) == 0) {
- /* It's up the caller to use this return value if he wants
- * to chain-call or wrap the previously registered function.
- */
- void *prevAddr = ext->Address;
- ext->Address = funcAddr;
- return prevAddr;
- }
- }
-
- /* add new function */
- ext = Xmalloc(sizeof(struct name_address_pair));
- if (!ext)
- return NULL;
- ext->Name = __glXstrdup(funcName);
- if (!ext->Name) {
- Xfree(ext);
- return NULL;
- }
- ext->Address = funcAddr;
- ext->Next = Dynamic_GLX_functions;
- Dynamic_GLX_functions = ext;
- return NULL;
-}
-
-
static const GLvoid *
get_glx_proc_address(const char *funcName, GLboolean dynamic_only)
{
- const struct name_address_pair *ext;
GLuint i;
- /* try dynamic functions */
- for (ext = Dynamic_GLX_functions; ext; ext = ext->Next) {
- if (strcmp(ext->Name, funcName) == 0) {
- return ext->Address;
- }
- }
-
- /* try static functions */
if ( ! dynamic_only ) {
for (i = 0; GLX_functions[i].Name; i++) {
if (strcmp(GLX_functions[i].Name, funcName) == 0)
@@ -3056,7 +3013,6 @@
* dynamically added by a driver. Call __glXRegisterExtensions()
* to try to make that happen.
*/
- __glXRegisterExtensions();
f = (gl_function) get_glx_proc_address((const char *) procName, GL_TRUE);
return f; /* may be NULL */
}
@@ -3163,8 +3119,9 @@
* GLX_MESA_swap_frame_usage, GLX_OML_swap_method,
* GLX_{ARB,SGIS}_multisample, and
* GLX_SGIX_visual_select_group.
+ * 20030813 - Made support for dynamic extensions multi-head aware.
*/
- return 20030317;
+ return 20030813;
}
Index: glx/glxext.c
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/glx/glxext.c,v
retrieving revision 1.28
diff -u -r1.28 glxext.c
--- glx/glxext.c 13 May 2003 13:48:21 -0000 1.28
+++ glx/glxext.c 14 Aug 2003 16:32:37 -0000
@@ -771,22 +771,20 @@
UnlockDisplay(dpy);
#ifdef GLX_DIRECT_RENDERING
+ /* Initialize per screen dynamic client GLX extensions */
+ psc->ext_list_first_time = GL_TRUE;
/* Initialize the direct rendering per screen data and functions */
if (priv->driDisplay.private &&
priv->driDisplay.createScreen &&
priv->driDisplay.createScreen[i]) {
- /* register glx extensions */
- __DRIdriver *driver = driGetDriver(dpy, i);
- if (driver && driver->registerExtensionsFunc)
- (*driver->registerExtensionsFunc)();
/* screen initialization (bootstrap the driver) */
-
if ( (psc->old_configs == NULL)
&& !FillInVisuals(psc) ) {
FreeScreenConfigs(priv);
return GL_FALSE;
}
-
+
+ psc->driScreen.screenConfigs = (void *)psc;
psc->driScreen.private =
(*(priv->driDisplay.createScreen[i]))(dpy, i, &psc->driScreen,
psc->numOldConfigs,
@@ -1064,11 +1062,10 @@
/************************************************************************/
-#ifdef GLX_DIRECT_RENDERING
-/* Return the DRI per screen structure */
-__DRIscreen *__glXFindDRIScreen(Display *dpy, int scrn)
+/* Return the GLX per screen structure */
+__GLXscreenConfigs *__glXFindGLXScreenConfigs(Display *dpy, int scrn)
{
- __DRIscreen *pDRIScreen = NULL;
+ __GLXscreenConfigs *pGLXScreen = NULL;
XExtDisplayInfo *info = __glXFindDisplay(dpy);
XExtData **privList, *found;
__GLXdisplayPrivate *dpyPriv;
@@ -1082,8 +1079,21 @@
if (found) {
dpyPriv = (__GLXdisplayPrivate *)found->private_data;
- pDRIScreen = &dpyPriv->screenConfigs[scrn].driScreen;
+ pGLXScreen = &dpyPriv->screenConfigs[scrn];
}
+
+ return pGLXScreen;
+}
+
+#ifdef GLX_DIRECT_RENDERING
+/* Return the DRI per screen structure */
+__DRIscreen *__glXFindDRIScreen(Display *dpy, int scrn)
+{
+ __DRIscreen *pDRIScreen = NULL;
+ __GLXscreenConfigs *pGLXScreen = __glXFindGLXScreenConfigs(dpy, scrn);
+
+ if (pGLXScreen)
+ pDRIScreen = &pGLXScreen->driScreen;
return pDRIScreen;
}
Index: glx/glxextensions.c
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/glx/glxextensions.c,v
retrieving revision 1.3
diff -u -r1.3 glxextensions.c
--- glx/glxextensions.c 3 May 2003 05:19:30 -0000 1.3
+++ glx/glxextensions.c 14 Aug 2003 16:32:43 -0000
@@ -116,18 +116,22 @@
{ NULL }
};
+/* global list of available extensions */
static struct glx_extension ext_list;
static GLboolean ext_list_first_time = GL_TRUE;
-static GLuint next_bit = 0;
+/* global bit-fields of available extensions and their characteristics */
static unsigned char client_support[8];
-static unsigned char direct_support[8];
static unsigned char client_only[8];
static unsigned char direct_only[8];
+/* extensions enabled by default on all screens */
+static unsigned char direct_support[8];
+/* client extensions string */
static const char * __glXGLXClientExtensions = NULL;
static void __glXExtensionsCtr( void );
+static void __glXExtensionsCtrScreen( __GLXscreenConfigs *psc );
static void __glXProcessServerString( const char * server_string,
unsigned char * server_support );
@@ -209,53 +213,49 @@
/**
- * Enable a named GLX extension.
+ * Enable a named GLX extension on a given screen.
*
+ * \param psc Pointer to GLX per-screen record.
* \param name Name of the extension to enable.
- * \param force_client Enable client-side support also. If this is set
- * to GL_TRUE, then the driver MUST supply function
- * entry-points via \c __glXRegisterGLXFunction.
- * \sa __glXRegisterGLXFunction, __glXDisableExtension
+ * \sa __glXDisableExtension
*/
void
-__glXEnableExtension( const char * name, GLboolean force_client )
+__glXScrEnableExtension( __GLXscreenConfigs *psc, const char * name )
{
- if ( __glXGLXClientExtensions == NULL ) {
- __glXExtensionsCtr();
- set_glx_extension( name, strlen( name ), GL_TRUE, direct_support );
- if ( force_client ) {
- set_glx_extension( name, strlen( name ), GL_TRUE, client_support );
- }
- }
+ __glXExtensionsCtr();
+ __glXExtensionsCtrScreen(psc);
+ set_glx_extension( name, strlen( name ), GL_TRUE, psc->direct_support );
}
/**
- * Disable a named GLX extension.
+ * Disable a named GLX extension on a given screen.
*
+ * \param psc Pointer to GLX per-screen record.
* \param name Name of the extension to disable.
* \sa __glXEnableExtension
*/
void
-__glXDisableExtension( const char * name )
+__glXScrDisableExtension( __GLXscreenConfigs *psc, const char * name )
{
- if ( __glXGLXClientExtensions == NULL ) {
- __glXExtensionsCtr();
- set_glx_extension( name, strlen( name ), GL_FALSE, direct_support );
- }
+ __glXExtensionsCtr();
+ __glXExtensionsCtrScreen(psc);
+ set_glx_extension( name, strlen( name ), GL_FALSE, psc->direct_support );
}
/**
* Add an extension to the global list of known GLX extensions.
*
- * \param enabled Default state of the extension.
- * \param name Text name of the extension.
- * \param version_major Major GLX version that requires this extension.
- * \param version_minor Minor GLX version that requires this extension.
- * \param bit Bit number in the global table that is set if this
- * extension is enabled.
- * \param client_only_flag Is this extension client-side only?
+ * \param name Text name of the extension.
+ * \param version_major Major GLX version that requires this extension.
+ * \param version_minor Minor GLX version that requires this extension.
+ * \param bit Bit number in the global table that is set if
+ * this extension is enabled.
+ * \param client_enabled_flag Client-side support in libGL present?
+ * \param direct_enabled_flag Direct-rendering support in DRI driver present?
+ * \param client_only_flag Is this extension client-side only?
+ * \param direct_only_flag Is this extension direct-rendering only?
*/
static void
add_extension( const char * name, GLuint version_major, GLuint version_minor,
@@ -312,39 +312,9 @@
}
-
-
/**
- * Add a new extension string to the set of possible strings. This is
- * intended to be used by drivers to advertise support for unlisted,
- * proprietary extensions.
- *
- * \param enabled Is the extension enabled by default?
- * \param name Name of the extension.
- * \param client_only Is the extension client-side only?
+ * Make sure that global extension support tables are initialized.
*/
-void
-__glXAddExtension( GLboolean enabled, const char * name,
- GLboolean client_only )
-{
- if ( __glXGLXClientExtensions == NULL ) {
- GLuint bit;
-
- __glXExtensionsCtr();
-
- bit = next_bit;
- if ( next_bit < 255 ) {
- next_bit++;
- }
-
- add_extension( name, 0, 0, bit, enabled, enabled,
- client_only, GL_TRUE );
- }
-}
-
-
-
-
static void
__glXExtensionsCtr( void )
{
@@ -370,26 +340,41 @@
default_glx_extensions[i].direct_support,
default_glx_extensions[i].client_only,
default_glx_extensions[i].direct_only );
- if ( default_glx_extensions[i].bit >= next_bit ) {
- next_bit = default_glx_extensions[i].bit + 1;
- }
}
}
}
+/**
+ * Make sure that per-screen direct-support table is initialized.
+ *
+ * \param psc Pointer to GLX per-screen record.
+ */
+static void
+__glXExtensionsCtrScreen( __GLXscreenConfigs *psc )
+{
+ if (psc->ext_list_first_time) {
+ psc->ext_list_first_time = GL_FALSE;
+ (void) memcpy( psc->direct_support, direct_support, sizeof( direct_support ) );
+ }
+}
+/**
+ * Check if a certain extension is enabled on a given screen.
+ *
+ * \param psc Pointer to GLX per-screen record.
+ * \param bit Bit index in the direct-support table.
+ */
GLboolean
-__glXExtensionBitIsEnabled( unsigned bit )
+__glXExtensionBitIsEnabled( __GLXscreenConfigs *psc, unsigned bit )
{
__glXExtensionsCtr();
- return EXT_ENABLED( bit, direct_support );
+ __glXExtensionsCtrScreen( psc );
+ return EXT_ENABLED( bit, psc->direct_support );
}
-
-
/**
* Convert a bit-field to a string of supported extensions.
*/
@@ -448,16 +433,19 @@
/**
* Get the list of application usable extensions.
*
- * \returns A pointer to the string.
+ * \param psc Pointer to GLX per-screen record.
+ * \param server_string Extension string describing server-side support.
+ * \returns A pointer to the string of usable extensions.
*/
char *
-__glXGetUsableExtensions( const char * server_string )
+__glXGetUsableExtensions( __GLXscreenConfigs *psc, const char * server_string )
{
unsigned char server_support[8];
unsigned char usable[8];
unsigned i;
__glXExtensionsCtr();
+ __glXExtensionsCtrScreen( psc );
__glXProcessServerString( server_string, server_support );
/* An extension is supported if the client-side (i.e., libGL) supports
@@ -467,8 +455,8 @@
*/
for ( i = 0 ; i < 8 ; i++ ) {
usable[i] = (client_support[i] & client_only[i])
- | (client_support[i] & (direct_support[i] & server_support[i]))
- | (client_support[i] & (direct_support[i] & direct_only[i]));
+ | (client_support[i] & psc->direct_support[i] & server_support[i])
+ | (client_support[i] & psc->direct_support[i] & direct_only[i]);
}
return __glXGetStringFromTable( usable );
Index: glx/glxextensions.h
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/glx/glxextensions.h,v
retrieving revision 1.2
diff -u -r1.2 glxextensions.h
--- glx/glxextensions.h 30 Apr 2003 01:50:35 -0000 1.2
+++ glx/glxextensions.h 14 Aug 2003 16:32:43 -0000
@@ -69,15 +69,19 @@
SUN_get_transparent_index_bit
};
-extern GLboolean __glXExtensionBitIsEnabled( unsigned bit );
+extern GLboolean __glXExtensionBitIsEnabled( __GLXscreenConfigs *psc, unsigned bit );
extern const char * __glXGetClientExtensions( void );
-extern char * __glXGetUsableExtensions( const char * server_string );
-extern void __glXAddExtension( GLboolean enabled, const char * name,
- GLboolean client_side );
-extern void __glXEnableExtension( const char * name, GLboolean force_client );
-extern void __glXDisableExtension( const char * name );
+extern char * __glXGetUsableExtensions( __GLXscreenConfigs *psc, const char *
server_string );
+extern void __glXScrEnableExtension( __GLXscreenConfigs *psc, const char * name );
+extern void __glXScrDisableExtension( __GLXscreenConfigs *psc, const char * name );
-typedef void (* PFNGLXADDEXTENSIONPROC) ( GLboolean enabled, const char * name );
+/* The void pointers here are because __GLXscreenConfigs is opaque for
+ * DRI drivers. */
+typedef void (* PFNGLXSCRENABLEEXTENSIONPROC) ( void *psc, const char * name );
+typedef void (* PFNGLXSCRDISABLEEXTENSIONPROC) ( void *psc, const char * name );
+
+/* Source-level backwards compatibility with old drivers. They won't
+ * find the respective functions, though. */
typedef void (* PFNGLXENABLEEXTENSIONPROC) ( const char * name,
GLboolean force_client );
typedef void (* PFNGLXDISABLEEXTENSIONPROC) ( const char * name );