From 0f2723cacbaf9b27ecb8d13581f4b72ff86dd911 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 7 Mar 2008 01:37:08 -0500 Subject: [PATCH] Simplify dri loading code by eliminating dlopen "cache". No need to jump through hoops to track __DRIdrivers and avoid dlopening the same .so more than twice, dlopen() does this internally. Besides, we were already bypassing this and dlopening drivers for each screen, whether or not they were already dlopened. --- src/glx/x11/dri_glx.c | 193 +++++++++------------------------------- src/glx/x11/dri_glx.h | 5 -- src/glx/x11/glxclient.h | 22 +---- src/glx/x11/glxext.c | 11 +-- 4 files changed, 46 insertions(+), 185 deletions(-) diff --git a/src/glx/x11/dri_glx.c b/src/glx/x11/dri_glx.c index c84e384cf34..078c9b6bad6 100644 --- a/src/glx/x11/dri_glx.c +++ b/src/glx/x11/dri_glx.c @@ -66,13 +66,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define DEFAULT_DRIVER_DIR "/usr/X11R6/lib/modules/dri" #endif -static __DRIdriver *Drivers = NULL; - - -/* - * printf wrappers - */ - static void InfoMessageF(const char *f, ...) { va_list args; @@ -187,22 +180,14 @@ static const char createNewScreenName[] = __DRI_CREATE_NEW_SCREEN_STRING; * \returns * A handle from \c dlopen, or \c NULL if driver file not found. */ -static __DRIdriver *OpenDriver(const char *driverName) +static void *OpenDriver(const char *driverName) { void *glhandle = NULL; char *libPaths = NULL; char libDir[1000]; + char realDriverName[200]; + void *handle = NULL; int i; - __DRIdriver *driver; - - /* First, search Drivers list to see if we've already opened this driver */ - for (driver = Drivers; driver; driver = driver->next) { - if (strcmp(driver->name, driverName) == 0) { - /* found it, increment library refcount & return */ - dlopen(driver->libpath, RTLD_NOW | RTLD_GLOBAL); - return driver; - } - } /* Attempt to make sure libGL symbols will be visible to the driver */ glhandle = dlopen("libGL.so.1", RTLD_NOW | RTLD_GLOBAL); @@ -217,10 +202,6 @@ static __DRIdriver *OpenDriver(const char *driverName) libPaths = DEFAULT_DRIVER_DIR; for ( i = 0 ; ExtractDir(i, libPaths, 1000, libDir) != 0 ; i++ ) { - char realDriverName[200]; - void *handle = NULL; - - /* If TLS support is enabled, try to open the TLS version of the driver * binary first. If that fails, try the non-TLS version. */ @@ -236,57 +217,19 @@ static __DRIdriver *OpenDriver(const char *driverName) handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL); } - if ( handle != NULL ) { - /* allocate __DRIdriver struct */ - driver = (__DRIdriver *) Xmalloc(sizeof(__DRIdriver)); - if (!driver) - break; /* out of memory! */ - /* init the struct */ - driver->name = __glXstrdup(driverName); - driver->libpath = __glXstrdup(realDriverName); - if (!driver->name || !driver->libpath) { - if (driver->name) - Xfree(driver->name); - if (driver->libpath) - Xfree(driver->libpath); - Xfree(driver); - driver = NULL; - break; /* out of memory! */ - } - - driver->createNewScreenFunc = (PFNCREATENEWSCREENFUNC) - dlsym(handle, createNewScreenName); - - if ( driver->createNewScreenFunc == NULL ) { - /* If the driver doesn't have this symbol then something's - * really, really wrong. - */ - ErrorMessageF("%s not defined in %s_dri.so!\n" - "Your driver may be too old for this libGL.\n", - createNewScreenName, driverName); - Xfree(driver); - driver = NULL; - dlclose(handle); - continue; - } - driver->handle = handle; - /* put at head of linked list */ - driver->next = Drivers; - Drivers = driver; - break; - } - else { + if ( handle != NULL ) + break; + else ErrorMessageF("dlopen %s failed (%s)\n", realDriverName, dlerror()); - } } - if (!driver) + if (!handle) ErrorMessageF("unable to load driver: %s_dri.so\n", driverName); if (glhandle) dlclose(glhandle); - return driver; + return handle; } @@ -330,11 +273,12 @@ static Bool GetDriverName(Display *dpy, int scrNum, char **driverName) * Given a display pointer and screen number, return a __DRIdriver handle. * Return NULL if anything goes wrong. */ -__DRIdriver *driGetDriver(Display *dpy, int scrNum) +static void *driGetDriver(Display *dpy, int scrNum) { char *driverName; + void *ret; + if (GetDriverName(dpy, scrNum, &driverName)) { - __DRIdriver *ret; ret = OpenDriver(driverName); if (driverName) Xfree(driverName); @@ -343,7 +287,6 @@ __DRIdriver *driGetDriver(Display *dpy, int scrNum) return NULL; } - /* * Exported function for querying the DRI driver for a given screen. * @@ -380,9 +323,9 @@ PUBLIC const char *glXGetScreenDriver (Display *dpy, int scrNum) { * Note: The driver remains opened after this function returns. */ PUBLIC const char *glXGetDriverConfig (const char *driverName) { - __DRIdriver *driver = OpenDriver (driverName); - if (driver) - return dlsym (driver->handle, "__driConfigOptions"); + void *handle = OpenDriver (driverName); + if (handle) + return dlsym (handle, "__driConfigOptions"); else return NULL; } @@ -564,7 +507,6 @@ static const __DRIextension *loader_extensions[] = { }; - /** * Perform the required libGL-side initialization and call the client-side * driver's \c __driCreateNewScreen function. @@ -766,6 +708,11 @@ void driCreateScreen(__GLXscreenConfigs *psc, int screen, __GLXdisplayPrivate *priv) { + PFNCREATENEWSCREENFUNC createNewScreen; + + if (priv->driDisplay.private == NULL) + return; + /* Create drawable hash */ psc->drawHash = __glxHashCreate(); if ( psc->drawHash == NULL ) @@ -773,22 +720,29 @@ driCreateScreen(__GLXscreenConfigs *psc, int screen, /* 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 != NULL) { - /* FIXME: Should it be some sort of an error if createNewScreen[i] - * FIXME: is NULL? - */ - if (priv->driDisplay.createNewScreen && - priv->driDisplay.createNewScreen[screen]) { - - psc->driScreen.private = - CallCreateNewScreen(psc->dpy, screen, psc, - & priv->driDisplay, - priv->driDisplay.createNewScreen[screen] ); - if (psc->driScreen.private != NULL) - __glXScrEnableDRIExtension(psc); - } - } + + psc->driver = driGetDriver(priv->dpy, screen); + createNewScreen = dlsym(psc->driver, createNewScreenName); + if (createNewScreenName == NULL) + return; + + psc->driScreen.private = + CallCreateNewScreen(psc->dpy, screen, psc, + &priv->driDisplay, createNewScreen); + if (psc->driScreen.private != NULL) + __glXScrEnableDRIExtension(psc); +} + +void driDestroyScreen(__GLXscreenConfigs *psc) +{ + /* Free the direct rendering per screen data */ + if (psc->driScreen.private) + (*psc->driScreen.destroyScreen)(&psc->driScreen); + psc->driScreen.private = NULL; + if (psc->drawHash) + __glxHashDestroy(psc->drawHash); + if (psc->driver) + dlclose(psc->driver); } /* Called from __glXFreeDisplayPrivate. @@ -797,35 +751,8 @@ static void driDestroyDisplay(Display *dpy, void *private) { __DRIdisplayPrivate *pdpyp = (__DRIdisplayPrivate *)private; - if (pdpyp) { - const int numScreens = ScreenCount(dpy); - int i; - for (i = 0; i < numScreens; i++) { - if (pdpyp->libraryHandles[i]) { - __DRIdriver *driver, *prev; - - /* Remove driver from Drivers list */ - for (prev = NULL, driver = Drivers; driver; - prev = driver, driver = driver->next) { - if (driver->handle == pdpyp->libraryHandles[i]) { - if (prev) - prev->next = driver->next; - else - Drivers = driver->next; - - Xfree(driver->name); - Xfree(driver->libpath); - Xfree(driver); - break; - } - } - - dlclose(pdpyp->libraryHandles[i]); - } - } - Xfree(pdpyp->libraryHandles); + if (pdpyp) Xfree(pdpyp); - } } @@ -836,11 +763,9 @@ static void driDestroyDisplay(Display *dpy, void *private) */ void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp) { - const int numScreens = ScreenCount(dpy); __DRIdisplayPrivate *pdpyp; int eventBase, errorBase; int major, minor, patch; - int scrn; /* Initialize these fields to NULL in case we fail. * If we don't do this we may later get segfaults trying to free random @@ -868,38 +793,6 @@ void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp) pdisp->destroyDisplay = driDestroyDisplay; - /* allocate array of pointers to createNewScreen funcs */ - pdisp->createNewScreen = (PFNCREATENEWSCREENFUNC *) - Xmalloc(numScreens * sizeof(void *)); - if (!pdisp->createNewScreen) { - Xfree(pdpyp); - return NULL; - } - - /* allocate array of library handles */ - pdpyp->libraryHandles = (void **) Xmalloc(numScreens * sizeof(void*)); - if (!pdpyp->libraryHandles) { - Xfree(pdisp->createNewScreen); - Xfree(pdpyp); - return NULL; - } - - /* dynamically discover DRI drivers for all screens, saving each - * driver's "__driCreateScreen" function pointer. That's the bootstrap - * entrypoint for all DRI drivers. - */ - for (scrn = 0; scrn < numScreens; scrn++) { - __DRIdriver *driver = driGetDriver(dpy, scrn); - if (driver) { - pdisp->createNewScreen[scrn] = driver->createNewScreenFunc; - pdpyp->libraryHandles[scrn] = driver->handle; - } - else { - pdisp->createNewScreen[scrn] = NULL; - pdpyp->libraryHandles[scrn] = NULL; - } - } - return (void *)pdpyp; } diff --git a/src/glx/x11/dri_glx.h b/src/glx/x11/dri_glx.h index 75561685c81..4dd62ed1133 100644 --- a/src/glx/x11/dri_glx.h +++ b/src/glx/x11/dri_glx.h @@ -44,11 +44,6 @@ struct __DRIdisplayPrivateRec { int driMajor; int driMinor; int driPatch; - - /* - ** Array of library handles [indexed by screen number] - */ - void **libraryHandles; }; typedef struct __DRIdisplayPrivateRec __DRIdisplayPrivate; diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h index a1fff0a65cc..e62eec822e8 100644 --- a/src/glx/x11/glxclient.h +++ b/src/glx/x11/glxclient.h @@ -103,24 +103,6 @@ struct __DRIdisplayRec { * \c NULL if direct rendering is not supported on this display. */ struct __DRIdisplayPrivateRec *private; - - /** - * Array of pointers to methods to create and initialize the private DRI - * screen data. - */ - PFNCREATENEWSCREENFUNC * createNewScreen; -}; - - -/* -** We keep a linked list of these structures, one per DRI device driver. -*/ -struct __DRIdriverRec { - const char *name; - const char *libpath; - void *handle; - PFNCREATENEWSCREENFUNC createNewScreenFunc; - struct __DRIdriverRec *next; }; /* @@ -130,8 +112,7 @@ struct __DRIdriverRec { extern void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp); extern void driCreateScreen(__GLXscreenConfigs *psc, int screen, __GLXdisplayPrivate *priv); - -extern __DRIdriver *driGetDriver(Display *dpy, int scrNum); +extern void driDestroyScreen(__GLXscreenConfigs *psc); extern void DRI_glXUseXFont( Font font, int first, int count, int listbase ); @@ -458,6 +439,7 @@ struct __GLXscreenConfigsRec { __glxHashTable *drawHash; Display *dpy; int scr; + void *driver; #ifdef __DRI_COPY_SUB_BUFFER __DRIcopySubBufferExtension *copySubBuffer; diff --git a/src/glx/x11/glxext.c b/src/glx/x11/glxext.c index e07312214be..61352a6098e 100644 --- a/src/glx/x11/glxext.c +++ b/src/glx/x11/glxext.c @@ -358,12 +358,7 @@ static void FreeScreenConfigs(__GLXdisplayPrivate *priv) Xfree((char*) psc->serverGLXexts); #ifdef GLX_DIRECT_RENDERING - /* Free the direct rendering per screen data */ - if (psc->driScreen.private) - (*psc->driScreen.destroyScreen)(&psc->driScreen); - psc->driScreen.private = NULL; - if (psc->drawHash) - __glxHashDestroy(psc->drawHash); + driDestroyScreen(psc); #endif } XFree((char*) priv->screenConfigs); @@ -394,10 +389,6 @@ static int __glXFreeDisplayPrivate(XExtData *extension) (*priv->driDisplay.destroyDisplay)(priv->dpy, priv->driDisplay.private); priv->driDisplay.private = NULL; - if (priv->driDisplay.createNewScreen) { - Xfree(priv->driDisplay.createNewScreen); /* free array of ptrs */ - priv->driDisplay.createNewScreen = NULL; - } #endif Xfree((char*) priv); -- 2.30.2