diff options
author | Kristian Høgsberg <[email protected]> | 2008-03-07 01:37:08 -0500 |
---|---|---|
committer | Kristian Høgsberg <[email protected]> | 2008-03-08 16:19:39 -0500 |
commit | 0f2723cacbaf9b27ecb8d13581f4b72ff86dd911 (patch) | |
tree | 38abc6f5fd165fc49650a69e4d783ff0e7f2ad9f /src/glx/x11/dri_glx.c | |
parent | 890d44e54f2c800f066f59eb074ad09e14d54483 (diff) |
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.
Diffstat (limited to 'src/glx/x11/dri_glx.c')
-rw-r--r-- | src/glx/x11/dri_glx.c | 193 |
1 files changed, 43 insertions, 150 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; } |