diff options
Diffstat (limited to 'src/glx/x11/dri_glx.c')
-rw-r--r-- | src/glx/x11/dri_glx.c | 66 |
1 files changed, 50 insertions, 16 deletions
diff --git a/src/glx/x11/dri_glx.c b/src/glx/x11/dri_glx.c index 21e07c19355..e637c96ac9b 100644 --- a/src/glx/x11/dri_glx.c +++ b/src/glx/x11/dri_glx.c @@ -64,6 +64,20 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. static __DRIdriver *Drivers = NULL; +/** If non-zero, prefer an "egl_foo_dri.so" driver over "foo_dri.so" */ +static int PreferEGL = 0; + + +/** + * This may be called by libEGL.so to tell libGL to prefer "egl_" drivers + * over regular DRI drivers". + */ +void __glXPreferEGL(int state) +{ + PreferEGL = state; +} + + /* * printf wrappers */ @@ -161,6 +175,33 @@ ExtractDir(int index, const char *paths, int dirLen, char *dir) /** + * Try to dlopen() a driver. + * \param libDir the directory to search + * \param driverName the name of the driver (such as "r300"). + * \param tls if true, try to find TLS version of driver + * \param preferEGL if true, try to find EGL-specific driver + * \return handle from dlopen(), will be NULL if fails. + */ +static void * +try_open(const char *libDir, const char *driverName, + GLboolean tls, GLboolean preferEGL) +{ + const char *tlsDir = tls ? "/tls/" : ""; + const char *eglPrefix = preferEGL ? "egl_" : ""; + char fullPathName[200]; + void *handle = NULL; + + snprintf(fullPathName, 200, "%s%s/%s%s_dri.so", + libDir, tlsDir, eglPrefix, driverName); + InfoMessageF("OpenDriver: trying %s\n", fullPathName); + handle = dlopen(fullPathName, RTLD_NOW | RTLD_GLOBAL); + + return handle; +} + + + +/** * Versioned name of the expected \c __driCreateNewScreen function. * * The version of the last incompatible loader/driver inteface change is @@ -214,24 +255,16 @@ 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. - */ + if (PreferEGL) + handle = try_open(libDir, driverName, GL_FALSE, GL_TRUE); #ifdef GLX_USE_TLS - snprintf(realDriverName, 200, "%s/tls/%s_dri.so", libDir, driverName); - InfoMessageF("OpenDriver: trying %s\n", realDriverName); - handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL); + if (!handle) + handle = try_open(libDir, driverName, GL_TRUE, GL_FALSE); #endif - - if ( handle == NULL ) { - snprintf(realDriverName, 200, "%s/%s_dri.so", libDir, driverName); - InfoMessageF("OpenDriver: trying %s\n", realDriverName); - handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL); - } + if (!handle) + handle = try_open(libDir, driverName, GL_FALSE, GL_FALSE); if ( handle != NULL ) { /* allocate __DRIdriver struct */ @@ -268,7 +301,8 @@ static __DRIdriver *OpenDriver(const char *driverName) break; } else { - ErrorMessageF("dlopen %s failed (%s)\n", realDriverName, dlerror()); + ErrorMessageF("Unable to find/open driver for %s (%s)\n", + driverName, dlerror()); } } @@ -402,7 +436,7 @@ static void driDestroyDisplay(Display *dpy, void *private) else Drivers = driver->next; - Xfree(driver->name); + Xfree((void *) driver->name); Xfree(driver); break; } |