diff options
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 c84e384cf3..078c9b6bad 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; } |