loader: Factor out the common driver opening logic from each loader.

I copied the code from egl_dri2.c, but the functionality was equivalent
between all the loaders other than their particular environment variables.

v2: Drop the logging function equivalent to loader_default_logger()
    (requested by Eric, Emil).  Move the SCons workaround across.  Drop
    the now-unused driGetDriverExtensions() declaration that was lost in a
    rebase.

Reviewed-by: Eric Engestrom <eric.engestrom@intel.com> (v1)
Reviewed-by: Emil Velikov <emil.velikov@collabora.com> (v1)
This commit is contained in:
Eric Anholt
2018-11-15 13:54:49 -08:00
parent cc19815738
commit d971a4230d
15 changed files with 131 additions and 238 deletions

View File

@@ -119,8 +119,7 @@ AM_CFLAGS += \
-I$(top_srcdir)/src/egl/drivers/dri2 \ -I$(top_srcdir)/src/egl/drivers/dri2 \
-I$(top_srcdir)/src/gbm/backends/dri \ -I$(top_srcdir)/src/gbm/backends/dri \
-I$(top_builddir)/src/egl/wayland/wayland-drm \ -I$(top_builddir)/src/egl/wayland/wayland-drm \
-I$(top_srcdir)/src/egl/wayland/wayland-drm \ -I$(top_srcdir)/src/egl/wayland/wayland-drm
-DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\"
nodist_libEGL_common_la_SOURCES = \ nodist_libEGL_common_la_SOURCES = \
$(dri2_backend_GENERATED_FILES) $(dri2_backend_GENERATED_FILES)

View File

@@ -483,75 +483,14 @@ static const __DRIextension **
dri2_open_driver(_EGLDisplay *disp) dri2_open_driver(_EGLDisplay *disp)
{ {
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
const __DRIextension **extensions = NULL; static const char *search_path_vars[] = {
char path[PATH_MAX], *search_paths, *next, *end; "LIBGL_DRIVERS_PATH",
char *get_extensions_name; NULL,
const __DRIextension **(*get_extensions)(void); };
search_paths = NULL; return loader_open_driver(dri2_dpy->driver_name,
if (geteuid() == getuid()) { &dri2_dpy->driver,
/* don't allow setuid apps to use LIBGL_DRIVERS_PATH */ search_path_vars);
search_paths = getenv("LIBGL_DRIVERS_PATH");
}
if (search_paths == NULL)
search_paths = DEFAULT_DRIVER_DIR;
dri2_dpy->driver = NULL;
end = search_paths + strlen(search_paths);
for (char *p = search_paths; p < end; p = next + 1) {
int len;
next = strchr(p, ':');
if (next == NULL)
next = end;
len = next - p;
#if GLX_USE_TLS
snprintf(path, sizeof path,
"%.*s/tls/%s_dri.so", len, p, dri2_dpy->driver_name);
dri2_dpy->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
#endif
if (dri2_dpy->driver == NULL) {
snprintf(path, sizeof path,
"%.*s/%s_dri.so", len, p, dri2_dpy->driver_name);
dri2_dpy->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
if (dri2_dpy->driver == NULL)
_eglLog(_EGL_DEBUG, "failed to open %s: %s\n", path, dlerror());
}
/* not need continue to loop all paths once the driver is found */
if (dri2_dpy->driver != NULL)
break;
}
if (dri2_dpy->driver == NULL) {
_eglLog(_EGL_WARNING,
"DRI2: failed to open %s (search paths %s)",
dri2_dpy->driver_name, search_paths);
return NULL;
}
_eglLog(_EGL_DEBUG, "DRI2: dlopen(%s)", path);
get_extensions_name = loader_get_extensions_name(dri2_dpy->driver_name);
if (get_extensions_name) {
get_extensions = dlsym(dri2_dpy->driver, get_extensions_name);
if (get_extensions) {
extensions = get_extensions();
} else {
_eglLog(_EGL_DEBUG, "driver does not expose %s(): %s\n",
get_extensions_name, dlerror());
}
free(get_extensions_name);
}
if (!extensions)
extensions = dlsym(dri2_dpy->driver, __DRI_DRIVER_EXTENSIONS);
if (extensions == NULL) {
_eglLog(_EGL_WARNING,
"DRI2: driver exports no extensions (%s)", dlerror());
dlclose(dri2_dpy->driver);
}
return extensions;
} }
EGLBoolean EGLBoolean

View File

@@ -93,9 +93,6 @@ if with_dri2
'drivers/dri2/egl_dri2.h', 'drivers/dri2/egl_dri2.h',
'drivers/dri2/egl_dri2_fallbacks.h', 'drivers/dri2/egl_dri2_fallbacks.h',
) )
c_args_for_egl += [
'-DDEFAULT_DRIVER_DIR="@0@"'.format(dri_search_path),
]
if with_platform_x11 if with_platform_x11
files_egl += files('drivers/dri2/platform_x11.c') files_egl += files('drivers/dri2/platform_x11.c')

View File

@@ -42,7 +42,6 @@ libgbm_la_SOURCES += \
$(gbm_dri_FILES) $(gbm_dri_FILES)
AM_CFLAGS += \ AM_CFLAGS += \
-DDEFAULT_DRIVER_DIR='"$(DRI_DRIVER_SEARCH_DIR)"' \
$(LIBDRM_CFLAGS) \ $(LIBDRM_CFLAGS) \
$(PTHREADSTUBS_CFLAGS) $(PTHREADSTUBS_CFLAGS)

View File

@@ -304,28 +304,6 @@ dri_bind_extensions(struct gbm_dri_device *dri,
static const __DRIextension ** static const __DRIextension **
dri_open_driver(struct gbm_dri_device *dri) dri_open_driver(struct gbm_dri_device *dri)
{ {
const __DRIextension **extensions = NULL;
char path[PATH_MAX], *search_paths, *p, *next, *end;
char *get_extensions_name;
search_paths = NULL;
/* don't allow setuid apps to use LIBGL_DRIVERS_PATH or GBM_DRIVERS_PATH */
if (geteuid() == getuid()) {
/* Read GBM_DRIVERS_PATH first for compatibility, but LIBGL_DRIVERS_PATH
* is recommended over GBM_DRIVERS_PATH.
*/
search_paths = getenv("GBM_DRIVERS_PATH");
/* Read LIBGL_DRIVERS_PATH if GBM_DRIVERS_PATH was not set.
* LIBGL_DRIVERS_PATH is recommended over GBM_DRIVERS_PATH.
*/
if (search_paths == NULL) {
search_paths = getenv("LIBGL_DRIVERS_PATH");
}
}
if (search_paths == NULL)
search_paths = DEFAULT_DRIVER_DIR;
/* Temporarily work around dri driver libs that need symbols in libglapi /* Temporarily work around dri driver libs that need symbols in libglapi
* but don't automatically link it in. * but don't automatically link it in.
*/ */
@@ -334,56 +312,18 @@ dri_open_driver(struct gbm_dri_device *dri)
*/ */
dlopen("libglapi.so.0", RTLD_LAZY | RTLD_GLOBAL); dlopen("libglapi.so.0", RTLD_LAZY | RTLD_GLOBAL);
dri->driver = NULL; static const char *search_path_vars[] = {
end = search_paths + strlen(search_paths); /* Read GBM_DRIVERS_PATH first for compatibility, but LIBGL_DRIVERS_PATH
for (p = search_paths; p < end && dri->driver == NULL; p = next + 1) { * is recommended over GBM_DRIVERS_PATH.
int len; */
next = strchr(p, ':'); "GBM_DRIVERS_PATH"
if (next == NULL) /* Read LIBGL_DRIVERS_PATH if GBM_DRIVERS_PATH was not set.
next = end; * LIBGL_DRIVERS_PATH is recommended over GBM_DRIVERS_PATH.
*/
len = next - p; "LIBGL_DRIVERS_PATH",
#if GLX_USE_TLS NULL
snprintf(path, sizeof path, };
"%.*s/tls/%s_dri.so", len, p, dri->driver_name); return loader_open_driver(dri->driver_name, &dri->driver, search_path_vars);
dri->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
#endif
if (dri->driver == NULL) {
snprintf(path, sizeof path,
"%.*s/%s_dri.so", len, p, dri->driver_name);
dri->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
}
/* not need continue to loop all paths once the driver is found */
if (dri->driver != NULL)
break;
}
if (dri->driver == NULL) {
fprintf(stderr, "gbm: failed to open any driver (search paths %s)\n",
search_paths);
fprintf(stderr, "gbm: Last dlopen error: %s\n", dlerror());
return NULL;
}
get_extensions_name = loader_get_extensions_name(dri->driver_name);
if (get_extensions_name) {
const __DRIextension **(*get_extensions)(void);
get_extensions = dlsym(dri->driver, get_extensions_name);
free(get_extensions_name);
if (get_extensions)
extensions = get_extensions();
}
if (!extensions)
extensions = dlsym(dri->driver, __DRI_DRIVER_EXTENSIONS);
if (extensions == NULL) {
fprintf(stderr, "gbm: driver exports no extensions (%s)", dlerror());
dlclose(dri->driver);
}
return extensions;
} }
static int static int

View File

@@ -37,7 +37,6 @@ incs_gbm = [
if with_dri2 if with_dri2
files_gbm += files('backends/dri/gbm_dri.c', 'backends/dri/gbm_driint.h') files_gbm += files('backends/dri/gbm_dri.c', 'backends/dri/gbm_driint.h')
deps_gbm += dep_libdrm # TODO: pthread-stubs deps_gbm += dep_libdrm # TODO: pthread-stubs
args_gbm += '-DDEFAULT_DRIVER_DIR="@0@"'.format(dri_search_path)
endif endif
if with_platform_wayland if with_platform_wayland
deps_gbm += dep_wayland_server deps_gbm += dep_wayland_server

View File

@@ -40,7 +40,6 @@ AM_CFLAGS = \
$(VISIBILITY_CFLAGS) \ $(VISIBILITY_CFLAGS) \
$(EXTRA_DEFINES_XF86VIDMODE) \ $(EXTRA_DEFINES_XF86VIDMODE) \
-D_REENTRANT \ -D_REENTRANT \
-DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" \
$(DEFINES) \ $(DEFINES) \
$(LIBDRM_CFLAGS) \ $(LIBDRM_CFLAGS) \
$(DRI2PROTO_CFLAGS) \ $(DRI2PROTO_CFLAGS) \

View File

@@ -26,8 +26,6 @@ env.Append(CPPDEFINES = [
'_REENTRANT', '_REENTRANT',
]) ])
env.Append(CPPDEFINES = ['DEFAULT_DRIVER_DIR=\\"/usr/local/lib/dri\\"'])
env.Prepend(LIBS = [ env.Prepend(LIBS = [
libloader, libloader,
mesautil, mesautil,

View File

@@ -77,9 +77,6 @@ dri_message(int level, const char *f, ...)
#define GL_LIB_NAME "libGL.so.1" #define GL_LIB_NAME "libGL.so.1"
#endif #endif
static const __DRIextension **
driGetDriverExtensions(void *handle, const char *driver_name);
/** /**
* Try to \c dlopen the named driver. * Try to \c dlopen the named driver.
* *
@@ -97,98 +94,23 @@ driGetDriverExtensions(void *handle, const char *driver_name);
_X_HIDDEN const __DRIextension ** _X_HIDDEN const __DRIextension **
driOpenDriver(const char *driverName, void **out_driver_handle) driOpenDriver(const char *driverName, void **out_driver_handle)
{ {
void *glhandle, *handle; void *glhandle;
const char *libPaths, *p, *next;
char realDriverName[200];
int len;
/* Attempt to make sure libGL symbols will be visible to the driver */ /* Attempt to make sure libGL symbols will be visible to the driver */
glhandle = dlopen(GL_LIB_NAME, RTLD_NOW | RTLD_GLOBAL); glhandle = dlopen(GL_LIB_NAME, RTLD_NOW | RTLD_GLOBAL);
libPaths = NULL; static const char *search_path_vars[] = {
if (geteuid() == getuid()) { "LIBGL_DRIVERS_PATH",
/* don't allow setuid apps to use LIBGL_DRIVERS_PATH */ "LIBGL_DRIVERS_DIR", /* deprecated */
libPaths = getenv("LIBGL_DRIVERS_PATH"); NULL
if (!libPaths) };
libPaths = getenv("LIBGL_DRIVERS_DIR"); /* deprecated */
}
if (libPaths == NULL)
libPaths = DEFAULT_DRIVER_DIR;
handle = NULL; const __DRIextension **extensions =
for (p = libPaths; *p; p = next) { loader_open_driver(driverName, out_driver_handle, search_path_vars);
next = strchr(p, ':');
if (next == NULL) {
len = strlen(p);
next = p + len;
}
else {
len = next - p;
next++;
}
#ifdef GLX_USE_TLS
snprintf(realDriverName, sizeof realDriverName,
"%.*s/tls/%s_dri.so", len, p, driverName);
InfoMessageF("OpenDriver: trying %s\n", realDriverName);
handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL);
#endif
if (handle == NULL) {
snprintf(realDriverName, sizeof realDriverName,
"%.*s/%s_dri.so", len, p, driverName);
InfoMessageF("OpenDriver: trying %s\n", realDriverName);
handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL);
}
if (handle != NULL)
break;
else
InfoMessageF("dlopen %s failed (%s)\n", realDriverName, dlerror());
}
if (!handle)
ErrorMessageF("unable to load driver: %s_dri.so\n", driverName);
if (glhandle) if (glhandle)
dlclose(glhandle); dlclose(glhandle);
const __DRIextension **extensions = driGetDriverExtensions(handle,
driverName);
if (!extensions) {
dlclose(handle);
handle = NULL;
}
*out_driver_handle = handle;
return extensions;
}
static const __DRIextension **
driGetDriverExtensions(void *handle, const char *driver_name)
{
const __DRIextension **extensions = NULL;
const __DRIextension **(*get_extensions)(void);
char *get_extensions_name = loader_get_extensions_name(driver_name);
if (get_extensions_name) {
get_extensions = dlsym(handle, get_extensions_name);
if (get_extensions) {
free(get_extensions_name);
return get_extensions();
} else {
InfoMessageF("driver does not expose %s(): %s\n",
get_extensions_name, dlerror());
free(get_extensions_name);
}
}
extensions = dlsym(handle, __DRI_DRIVER_EXTENSIONS);
if (extensions == NULL) {
ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
return NULL;
}
return extensions; return extensions;
} }

View File

@@ -134,7 +134,6 @@ endif
gl_lib_cargs = [ gl_lib_cargs = [
'-D_REENTRANT', '-D_REENTRANT',
'-DDEFAULT_DRIVER_DIR="@0@"'.format(dri_search_path),
] ]
if dep_xxf86vm.found() if dep_xxf86vm.found()

View File

@@ -28,6 +28,7 @@ noinst_LTLIBRARIES = libloader.la
AM_CPPFLAGS = \ AM_CPPFLAGS = \
-I$(top_builddir)/src/util/ \ -I$(top_builddir)/src/util/ \
-DUSE_DRICONF \ -DUSE_DRICONF \
-DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" \
$(DEFINES) \ $(DEFINES) \
-I$(top_srcdir)/include \ -I$(top_srcdir)/include \
-I$(top_srcdir)/include/drm-uapi \ -I$(top_srcdir)/include/drm-uapi \

View File

@@ -12,6 +12,8 @@ if env['drm']:
env.PkgUseModules('DRM') env.PkgUseModules('DRM')
env.Append(CPPDEFINES = ['HAVE_LIBDRM']) env.Append(CPPDEFINES = ['HAVE_LIBDRM'])
env.Append(CPPDEFINES = ['DEFAULT_DRIVER_DIR=\\"/usr/local/lib/dri\\"'])
# parse Makefile.sources # parse Makefile.sources
sources = env.ParseSourceList('Makefile.sources', 'LOADER_C_FILES') sources = env.ParseSourceList('Makefile.sources', 'LOADER_C_FILES')

View File

@@ -26,6 +26,7 @@
* Rob Clark <robclark@freedesktop.org> * Rob Clark <robclark@freedesktop.org>
*/ */
#include <dlfcn.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/stat.h> #include <sys/stat.h>
@@ -35,6 +36,7 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/param.h>
#ifdef MAJOR_IN_MKDEV #ifdef MAJOR_IN_MKDEV
#include <sys/mkdev.h> #include <sys/mkdev.h>
#endif #endif
@@ -510,3 +512,91 @@ loader_get_extensions_name(const char *driver_name)
return name; return name;
} }
/**
* Opens a DRI driver using its driver name, returning the __DRIextension
* entrypoints.
*
* \param driverName - a name like "i965", "radeon", "nouveau", etc.
* \param out_driver - Address where the dlopen() return value will be stored.
* \param search_path_vars - NULL-terminated list of env vars that can be used
* to override the DEFAULT_DRIVER_DIR search path.
*/
const struct __DRIextensionRec **
loader_open_driver(const char *driver_name,
void **out_driver_handle,
const char **search_path_vars)
{
char path[PATH_MAX], *search_paths, *next, *end;
char *get_extensions_name;
const struct __DRIextensionRec **extensions = NULL;
const struct __DRIextensionRec **(*get_extensions)(void);
search_paths = NULL;
if (geteuid() == getuid() && search_path_vars) {
for (int i = 0; search_path_vars[i] != NULL; i++) {
search_paths = getenv(search_path_vars[i]);
if (search_paths)
break;
}
}
if (search_paths == NULL)
search_paths = DEFAULT_DRIVER_DIR;
void *driver = NULL;
end = search_paths + strlen(search_paths);
for (char *p = search_paths; p < end; p = next + 1) {
int len;
next = strchr(p, ':');
if (next == NULL)
next = end;
len = next - p;
#if GLX_USE_TLS
snprintf(path, sizeof(path), "%.*s/tls/%s_dri.so", len, p, driver_name);
driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
#endif
if (driver == NULL) {
snprintf(path, sizeof(path), "%.*s/%s_dri.so", len, p, driver_name);
driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
if (driver == NULL)
log_(_LOADER_DEBUG, "MESA-LOADER: failed to open %s: %s\n",
path, dlerror());
}
/* not need continue to loop all paths once the driver is found */
if (driver != NULL)
break;
}
if (driver == NULL) {
log_(_LOADER_WARNING, "MESA-LOADER: failed to open %s (search paths %s)\n",
driver_name, search_paths);
*out_driver_handle = NULL;
return NULL;
}
log_(_LOADER_DEBUG, "MESA-LOADER: dlopen(%s)\n", path);
get_extensions_name = loader_get_extensions_name(driver_name);
if (get_extensions_name) {
get_extensions = dlsym(driver, get_extensions_name);
if (get_extensions) {
extensions = get_extensions();
} else {
log_(_LOADER_DEBUG, "MESA-LOADER: driver does not expose %s(): %s\n",
get_extensions_name, dlerror());
}
free(get_extensions_name);
}
if (!extensions)
extensions = dlsym(driver, __DRI_DRIVER_EXTENSIONS);
if (extensions == NULL) {
log_(_LOADER_WARNING,
"MESA-LOADER: driver exports no extensions (%s)\n", dlerror());
dlclose(driver);
}
*out_driver_handle = driver;
return extensions;
}

View File

@@ -33,6 +33,8 @@
extern "C" { extern "C" {
#endif #endif
struct __DRIextensionRec;
/* Helpers to figure out driver and device name, eg. from pci-id, etc. */ /* Helpers to figure out driver and device name, eg. from pci-id, etc. */
int int
@@ -47,6 +49,11 @@ loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id);
char * char *
loader_get_driver_for_fd(int fd); loader_get_driver_for_fd(int fd);
const struct __DRIextensionRec **
loader_open_driver(const char *driver_name,
void **out_driver_handle,
const char **search_path_vars);
char * char *
loader_get_device_name_for_fd(int fd); loader_get_device_name_for_fd(int fd);

View File

@@ -39,7 +39,9 @@ libloader = static_library(
'loader', 'loader',
['loader.c', 'loader.h', 'pci_id_driver_map.c', 'pci_id_driver_map.h', ['loader.c', 'loader.h', 'pci_id_driver_map.c', 'pci_id_driver_map.h',
xmlpool_options_h], xmlpool_options_h],
c_args : [c_vis_args, '-DUSE_DRICONF'], c_args : [c_vis_args, '-DUSE_DRICONF',
'-DDEFAULT_DRIVER_DIR="@0@"'.format(dri_search_path),
],
include_directories : [inc_include, inc_src, inc_util], include_directories : [inc_include, inc_src, inc_util],
dependencies : [dep_libdrm, dep_thread], dependencies : [dep_libdrm, dep_thread],
build_by_default : false, build_by_default : false,