glx: Move glXGet{ScreenDriver,DriverConfig} to common code

These no longer reference anything specific to a particular DRI
protocol.

Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7219>
This commit is contained in:
Adam Jackson 2020-10-16 17:32:25 -04:00
parent ce8530d6c9
commit e6e3d8951a
2 changed files with 155 additions and 155 deletions

View File

@ -602,4 +602,158 @@ dri2_check_no_error(uint32_t flags, struct glx_context *share_context,
return true;
}
/*
* Given a display pointer and screen number, determine the name of
* the DRI driver for the screen (i.e., "i965", "radeon", "nouveau", etc).
* Return True for success, False for failure.
*/
static Bool
driGetDriverName(Display * dpy, int scrNum, char **driverName)
{
struct glx_screen *glx_screen = GetGLXScreenConfigs(dpy, scrNum);
if (!glx_screen || !glx_screen->vtable->get_driver_name)
return False;
*driverName = glx_screen->vtable->get_driver_name(glx_screen);
return True;
}
/*
* Exported function for querying the DRI driver for a given screen.
*
* The returned char pointer points to a static array that will be
* overwritten by subsequent calls.
*/
_GLX_PUBLIC const char *
glXGetScreenDriver(Display * dpy, int scrNum)
{
static char ret[32];
char *driverName;
if (driGetDriverName(dpy, scrNum, &driverName)) {
int len;
if (!driverName)
return NULL;
len = strlen(driverName);
if (len >= 31)
return NULL;
memcpy(ret, driverName, len + 1);
free(driverName);
return ret;
}
return NULL;
}
/* glXGetDriverConfig must return a pointer with a static lifetime. To avoid
* keeping drivers loaded and other leaks, we keep a cache of results here that
* is cleared by an atexit handler.
*/
struct driver_config_entry {
struct driver_config_entry *next;
char *driverName;
char *config;
};
static pthread_mutex_t driver_config_mutex = PTHREAD_MUTEX_INITIALIZER;
static struct driver_config_entry *driver_config_cache = NULL;
/* Called as an atexit function. Otherwise, this would have to be called with
* driver_config_mutex locked.
*/
static void
clear_driver_config_cache()
{
while (driver_config_cache) {
struct driver_config_entry *e = driver_config_cache;
driver_config_cache = e->next;
free(e->driverName);
free(e->config);
free(e);
}
}
static char *
get_driver_config(const char *driverName)
{
void *handle;
char *config = NULL;
const __DRIextension **extensions = driOpenDriver(driverName, &handle);
if (extensions) {
for (int i = 0; extensions[i]; i++) {
if (strcmp(extensions[i]->name, __DRI_CONFIG_OPTIONS) != 0)
continue;
__DRIconfigOptionsExtension *ext =
(__DRIconfigOptionsExtension *)extensions[i];
if (ext->base.version >= 2)
config = ext->getXml(driverName);
else
config = strdup(ext->xml);
break;
}
}
if (!config) {
/* Fall back to the old method */
config = dlsym(handle, "__driConfigOptions");
if (config)
config = strdup(config);
}
dlclose(handle);
return config;
}
/*
* Exported function for obtaining a driver's option list (UTF-8 encoded XML).
*
* The returned char pointer points directly into the driver. Therefore
* it should be treated as a constant.
*
* If the driver was not found or does not support configuration NULL is
* returned.
*/
_GLX_PUBLIC const char *
glXGetDriverConfig(const char *driverName)
{
struct driver_config_entry *e;
pthread_mutex_lock(&driver_config_mutex);
for (e = driver_config_cache; e; e = e->next) {
if (strcmp(e->driverName, driverName) == 0)
goto out;
}
e = malloc(sizeof(*e));
if (!e)
goto out;
e->config = get_driver_config(driverName);
e->driverName = strdup(driverName);
if (!e->config || !e->driverName) {
free(e->config);
free(e->driverName);
free(e);
e = NULL;
goto out;
}
e->next = driver_config_cache;
driver_config_cache = e;
if (!e->next)
atexit(clear_driver_config_cache);
out:
pthread_mutex_unlock(&driver_config_mutex);
return e ? e->config : NULL;
}
#endif /* GLX_DIRECT_RENDERING */

View File

@ -91,23 +91,6 @@ struct dri_drawable
__DRIdrawable *driDrawable;
};
/*
* Given a display pointer and screen number, determine the name of
* the DRI driver for the screen (i.e., "i965", "radeon", "nouveau", etc).
* Return True for success, False for failure.
*/
static Bool
driGetDriverName(Display * dpy, int scrNum, char **driverName)
{
struct glx_screen *glx_screen = GetGLXScreenConfigs(dpy, scrNum);
if (!glx_screen || !glx_screen->vtable->get_driver_name)
return False;
*driverName = glx_screen->vtable->get_driver_name(glx_screen);
return True;
}
static char *
dri_get_driver_name(struct glx_screen *psc)
{
@ -146,143 +129,6 @@ dri_get_driver_name(struct glx_screen *psc)
return NULL;
}
/*
* Exported function for querying the DRI driver for a given screen.
*
* The returned char pointer points to a static array that will be
* overwritten by subsequent calls.
*/
_GLX_PUBLIC const char *
glXGetScreenDriver(Display * dpy, int scrNum)
{
static char ret[32];
char *driverName;
if (driGetDriverName(dpy, scrNum, &driverName)) {
int len;
if (!driverName)
return NULL;
len = strlen(driverName);
if (len >= 31)
return NULL;
memcpy(ret, driverName, len + 1);
free(driverName);
return ret;
}
return NULL;
}
/* glXGetDriverConfig must return a pointer with a static lifetime. To avoid
* keeping drivers loaded and other leaks, we keep a cache of results here that
* is cleared by an atexit handler.
*/
struct driver_config_entry {
struct driver_config_entry *next;
char *driverName;
char *config;
};
static pthread_mutex_t driver_config_mutex = PTHREAD_MUTEX_INITIALIZER;
static struct driver_config_entry *driver_config_cache = NULL;
/* Called as an atexit function. Otherwise, this would have to be called with
* driver_config_mutex locked.
*/
static void
clear_driver_config_cache()
{
while (driver_config_cache) {
struct driver_config_entry *e = driver_config_cache;
driver_config_cache = e->next;
free(e->driverName);
free(e->config);
free(e);
}
}
static char *
get_driver_config(const char *driverName)
{
void *handle;
char *config = NULL;
const __DRIextension **extensions = driOpenDriver(driverName, &handle);
if (extensions) {
for (int i = 0; extensions[i]; i++) {
if (strcmp(extensions[i]->name, __DRI_CONFIG_OPTIONS) != 0)
continue;
__DRIconfigOptionsExtension *ext =
(__DRIconfigOptionsExtension *)extensions[i];
if (ext->base.version >= 2)
config = ext->getXml(driverName);
else
config = strdup(ext->xml);
break;
}
}
if (!config) {
/* Fall back to the old method */
config = dlsym(handle, "__driConfigOptions");
if (config)
config = strdup(config);
}
dlclose(handle);
return config;
}
/*
* Exported function for obtaining a driver's option list (UTF-8 encoded XML).
*
* The returned char pointer points directly into the driver. Therefore
* it should be treated as a constant.
*
* If the driver was not found or does not support configuration NULL is
* returned.
*/
_GLX_PUBLIC const char *
glXGetDriverConfig(const char *driverName)
{
struct driver_config_entry *e;
pthread_mutex_lock(&driver_config_mutex);
for (e = driver_config_cache; e; e = e->next) {
if (strcmp(e->driverName, driverName) == 0)
goto out;
}
e = malloc(sizeof(*e));
if (!e)
goto out;
e->config = get_driver_config(driverName);
e->driverName = strdup(driverName);
if (!e->config || !e->driverName) {
free(e->config);
free(e->driverName);
free(e);
e = NULL;
goto out;
}
e->next = driver_config_cache;
driver_config_cache = e;
if (!e->next)
atexit(clear_driver_config_cache);
out:
pthread_mutex_unlock(&driver_config_mutex);
return e ? e->config : NULL;
}
/**
* Get the unadjusted system time (UST). Currently, the UST is measured in
* microseconds since Epoc. The actual resolution of the UST may vary from
@ -961,7 +807,7 @@ driCreateScreen(int screen, struct glx_display *priv)
return NULL;
}
if (!driGetDriverName(priv->dpy, screen, &driverName)) {
if (!(driverName = dri_get_driver_name(&psc->base))) {
goto cleanup;
}