X-Git-Url: https://git.libre-soc.org/?p=mesa.git;a=blobdiff_plain;f=src%2Fglx%2Fdri_glx.c;h=3e0873524c065b062f70502007843548718a9d10;hp=859375013f1739e2bff2dcd6dde525dcde4e500a;hb=HEAD;hpb=fbbf5ec47169c3f8b9a43087e54ccd07f513431d diff --git a/src/glx/dri_glx.c b/src/glx/dri_glx.c index 859375013f1..3e0873524c0 100644 --- a/src/glx/dri_glx.c +++ b/src/glx/dri_glx.c @@ -40,7 +40,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "glxclient.h" #include "xf86dri.h" #include "dri2.h" -#include "sarea.h" +#include "dri_sarea.h" #include #include #include @@ -90,8 +90,6 @@ struct dri_drawable __DRIdrawable *driDrawable; }; -static const struct glx_context_vtable dri_context_vtable; - /* * Given a display pointer and screen number, determine the name of * the DRI driver for the screen (i.e., "i965", "radeon", "nouveau", etc). @@ -150,7 +148,7 @@ driGetDriverName(Display * dpy, int scrNum, char **driverName) * The returned char pointer points to a static array that will be * overwritten by subsequent calls. */ -_X_EXPORT const char * +_GLX_PUBLIC const char * glXGetScreenDriver(Display * dpy, int scrNum) { static char ret[32]; @@ -169,6 +167,70 @@ glXGetScreenDriver(Display * dpy, int scrNum) 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). * @@ -177,31 +239,44 @@ glXGetScreenDriver(Display * dpy, int scrNum) * * If the driver was not found or does not support configuration NULL is * returned. - * - * Note: The driver remains opened after this function returns. */ -_X_EXPORT const char * +_GLX_PUBLIC const char * glXGetDriverConfig(const char *driverName) { - void *handle = driOpenDriver(driverName); - const __DRIextension **extensions; + struct driver_config_entry *e; - if (!handle) - return NULL; + pthread_mutex_lock(&driver_config_mutex); - extensions = driGetDriverExtensions(handle, driverName); - if (extensions) { - for (int i = 0; extensions[i]; i++) { - if (strcmp(extensions[i]->name, __DRI_CONFIG_OPTIONS) == 0) - return ((__DRIconfigOptionsExtension *)extensions[i])->xml; - } + for (e = driver_config_cache; e; e = e->next) { + if (strcmp(e->driverName, driverName) == 0) + goto out; } - /* Fall back to the old method */ - return dlsym(handle, "__driConfigOptions"); -} + e = malloc(sizeof(*e)); + if (!e) + goto out; -#ifdef XDAMAGE_1_1_INTERFACE + 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; +} static GLboolean has_damage_post(Display * dpy) @@ -271,11 +346,10 @@ __glXReportDamage(__DRIdrawable * driDraw, } static const __DRIdamageExtension damageExtension = { - {__DRI_DAMAGE, __DRI_DAMAGE_VERSION}, - __glXReportDamage, -}; + .base = {__DRI_DAMAGE, 1 }, -#endif + .reportDamage = __glXReportDamage, +}; static GLboolean __glXDRIGetDrawableInfo(__DRIdrawable * drawable, @@ -307,9 +381,7 @@ static const __DRIgetDrawableInfoExtension getDrawableInfoExtension = { static const __DRIextension *loader_extensions[] = { &systemTimeExtension.base, &getDrawableInfoExtension.base, -#ifdef XDAMAGE_1_1_INTERFACE &damageExtension.base, -#endif NULL }; @@ -461,8 +533,10 @@ CallCreateNewScreen(Display *dpy, int scrn, struct dri_screen *psc, configs = driConvertConfigs(psc->core, psc->base.configs, driver_configs); visuals = driConvertConfigs(psc->core, psc->base.visuals, driver_configs); - if (!configs || !visuals) + if (!configs || !visuals) { + ErrorMessageF("No matching fbConfigs or visuals found\n"); goto handle_error; + } glx_config_destroy_list(psc->base.configs); psc->base.configs = configs; @@ -476,14 +550,14 @@ CallCreateNewScreen(Display *dpy, int scrn, struct dri_screen *psc, * non-conformant to prevent apps from picking them up accidentally. */ for (visual = psc->base.visuals; visual; visual = visual->next) { - XVisualInfo template; + XVisualInfo templ; XVisualInfo *visuals; int num_visuals; long mask; - template.visualid = visual->visualID; + templ.visualid = visual->visualID; mask = VisualIDMask; - visuals = XGetVisualInfo(dpy, mask, &template, &num_visuals); + visuals = XGetVisualInfo(dpy, mask, &templ, &num_visuals); if (visuals) { if (num_visuals > 0 && visuals->depth != DefaultDepth(dpy, scrn)) @@ -568,15 +642,15 @@ dri_unbind_context(struct glx_context *context, struct glx_context *new) } static const struct glx_context_vtable dri_context_vtable = { - dri_destroy_context, - dri_bind_context, - dri_unbind_context, - NULL, - NULL, - DRI_glXUseXFont, - NULL, - NULL, - NULL, /* get_proc_address */ + .destroy = dri_destroy_context, + .bind = dri_bind_context, + .unbind = dri_unbind_context, + .wait_gl = NULL, + .wait_x = NULL, + .use_x_font = DRI_glXUseXFont, + .bind_tex_image = NULL, + .release_tex_image = NULL, + .get_proc_address = NULL, }; static struct glx_context * @@ -807,8 +881,10 @@ driBindExtensions(struct dri_screen *psc, const __DRIextension **extensions) } static const struct glx_screen_vtable dri_screen_vtable = { - dri_create_context, - NULL + .create_context = dri_create_context, + .create_context_attribs = NULL, + .query_renderer_integer = NULL, + .query_renderer_string = NULL, }; static struct glx_screen * @@ -834,11 +910,7 @@ driCreateScreen(int screen, struct glx_display *priv) goto cleanup; } - psc->driver = driOpenDriver(driverName); - if (psc->driver == NULL) - goto cleanup; - - extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS); + extensions = driOpenDriver(driverName, &psc->driver); if (extensions == NULL) { ErrorMessageF("driver exports no extensions (%s)\n", dlerror()); goto cleanup;