mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-01-08 00:10:18 +01:00
[xlib] Keep a pointer to the cairo_xlib_display_t on the surface.
Cleanup the code somewhat by passing cairo_xlib_display_t around internally as opposed to a Display and then having to lookup the corresponding cairo_xlib_display_t each time. [To get a cairo_xlib_display_t from a Display is a list traversal under mutex (though the element we're looking for is most likely at the start), but to get the Display is just a lockless pointer dereference.]
This commit is contained in:
parent
939b836bfa
commit
a5d33bcbb4
5 changed files with 49 additions and 62 deletions
|
|
@ -90,7 +90,7 @@ _cairo_xlib_call_close_display_hooks (cairo_xlib_display_t *display)
|
|||
_cairo_xlib_remove_close_display_hook_internal (display, hook);
|
||||
|
||||
CAIRO_MUTEX_UNLOCK (display->mutex);
|
||||
hook->func (display->display, hook);
|
||||
hook->func (display, hook);
|
||||
CAIRO_MUTEX_LOCK (display->mutex);
|
||||
}
|
||||
display->closed = TRUE;
|
||||
|
|
@ -317,15 +317,10 @@ UNLOCK:
|
|||
return display;
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_xlib_add_close_display_hook (Display *dpy, cairo_xlib_hook_t *hook)
|
||||
void
|
||||
_cairo_xlib_add_close_display_hook (cairo_xlib_display_t *display,
|
||||
cairo_xlib_hook_t *hook)
|
||||
{
|
||||
cairo_xlib_display_t *display;
|
||||
|
||||
display = _cairo_xlib_display_get (dpy);
|
||||
if (display == NULL)
|
||||
return FALSE;
|
||||
|
||||
CAIRO_MUTEX_LOCK (display->mutex);
|
||||
hook->prev = NULL;
|
||||
hook->next = display->close_display_hooks;
|
||||
|
|
@ -333,10 +328,6 @@ _cairo_xlib_add_close_display_hook (Display *dpy, cairo_xlib_hook_t *hook)
|
|||
hook->next->prev = hook;
|
||||
display->close_display_hooks = hook;
|
||||
CAIRO_MUTEX_UNLOCK (display->mutex);
|
||||
|
||||
_cairo_xlib_display_destroy (display);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* display->mutex must be held */
|
||||
|
|
@ -357,20 +348,12 @@ _cairo_xlib_remove_close_display_hook_internal (cairo_xlib_display_t *display,
|
|||
}
|
||||
|
||||
void
|
||||
_cairo_xlib_remove_close_display_hook (Display *dpy,
|
||||
cairo_xlib_hook_t *hook)
|
||||
_cairo_xlib_remove_close_display_hook (cairo_xlib_display_t *display,
|
||||
cairo_xlib_hook_t *hook)
|
||||
{
|
||||
cairo_xlib_display_t *display;
|
||||
|
||||
display = _cairo_xlib_display_get (dpy);
|
||||
if (display == NULL)
|
||||
return;
|
||||
|
||||
CAIRO_MUTEX_LOCK (display->mutex);
|
||||
_cairo_xlib_remove_close_display_hook_internal (display, hook);
|
||||
CAIRO_MUTEX_UNLOCK (display->mutex);
|
||||
|
||||
_cairo_xlib_display_destroy (display);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ typedef void (*cairo_xlib_notify_resource_func) (Display *, XID);
|
|||
|
||||
struct _cairo_xlib_hook {
|
||||
cairo_xlib_hook_t *prev, *next; /* private */
|
||||
void (*func) (Display *display, void *data);
|
||||
void (*func) (cairo_xlib_display_t *display, void *data);
|
||||
};
|
||||
|
||||
struct _cairo_xlib_display {
|
||||
|
|
@ -113,11 +113,11 @@ _cairo_xlib_display_reference (cairo_xlib_display_t *info);
|
|||
cairo_private void
|
||||
_cairo_xlib_display_destroy (cairo_xlib_display_t *info);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_xlib_add_close_display_hook (Display *display, cairo_xlib_hook_t *hook);
|
||||
cairo_private void
|
||||
_cairo_xlib_add_close_display_hook (cairo_xlib_display_t *display, cairo_xlib_hook_t *hook);
|
||||
|
||||
cairo_private void
|
||||
_cairo_xlib_remove_close_display_hook (Display *display, cairo_xlib_hook_t *hook);
|
||||
_cairo_xlib_remove_close_display_hook (cairo_xlib_display_t *display, cairo_xlib_hook_t *hook);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_xlib_display_queue_work (cairo_xlib_display_t *display,
|
||||
|
|
@ -136,7 +136,7 @@ _cairo_xlib_display_get_xrender_format (cairo_xlib_display_t *display,
|
|||
cairo_format_t format);
|
||||
|
||||
cairo_private cairo_xlib_screen_info_t *
|
||||
_cairo_xlib_screen_info_get (Display *display, Screen *screen);
|
||||
_cairo_xlib_screen_info_get (cairo_xlib_display_t *display, Screen *screen);
|
||||
|
||||
cairo_private cairo_xlib_screen_info_t *
|
||||
_cairo_xlib_screen_info_reference (cairo_xlib_screen_info_t *info);
|
||||
|
|
|
|||
|
|
@ -346,19 +346,14 @@ _cairo_xlib_screen_info_destroy (cairo_xlib_screen_info_t *info)
|
|||
}
|
||||
|
||||
cairo_xlib_screen_info_t *
|
||||
_cairo_xlib_screen_info_get (Display *dpy, Screen *screen)
|
||||
_cairo_xlib_screen_info_get (cairo_xlib_display_t *display, Screen *screen)
|
||||
{
|
||||
cairo_xlib_display_t *display;
|
||||
cairo_xlib_screen_info_t *info = NULL, **prev;
|
||||
|
||||
display = _cairo_xlib_display_get (dpy);
|
||||
if (display == NULL)
|
||||
return NULL;
|
||||
|
||||
CAIRO_MUTEX_LOCK (display->mutex);
|
||||
if (display->closed) {
|
||||
CAIRO_MUTEX_UNLOCK (display->mutex);
|
||||
goto DONE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (prev = &display->screens; (info = *prev); prev = &(*prev)->next) {
|
||||
|
|
@ -394,7 +389,9 @@ _cairo_xlib_screen_info_get (Display *dpy, Screen *screen)
|
|||
sizeof (cairo_xlib_visual_info_t*));
|
||||
|
||||
if (screen) {
|
||||
Display *dpy = display->display;
|
||||
int event_base, error_base;
|
||||
|
||||
info->has_render = (XRenderQueryExtension (dpy, &event_base, &error_base) &&
|
||||
(XRenderFindVisualFormat (dpy, DefaultVisual (dpy, DefaultScreen (dpy))) != 0));
|
||||
_cairo_xlib_init_screen_font_options (dpy, info);
|
||||
|
|
@ -407,9 +404,6 @@ _cairo_xlib_screen_info_get (Display *dpy, Screen *screen)
|
|||
}
|
||||
}
|
||||
|
||||
DONE:
|
||||
_cairo_xlib_display_destroy (display);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ struct _cairo_xlib_surface {
|
|||
cairo_surface_t base;
|
||||
|
||||
Display *dpy;
|
||||
cairo_xlib_display_t *display;
|
||||
cairo_xlib_screen_info_t *screen_info;
|
||||
cairo_xlib_hook_t close_display_hook;
|
||||
|
||||
|
|
|
|||
|
|
@ -320,12 +320,14 @@ _cairo_xlib_surface_finish (void *abstract_surface)
|
|||
if (surface->screen_info != NULL)
|
||||
_cairo_xlib_screen_info_destroy (surface->screen_info);
|
||||
|
||||
if (surface->dpy != NULL) {
|
||||
_cairo_xlib_remove_close_display_hook (surface->dpy,
|
||||
if (surface->display != NULL) {
|
||||
_cairo_xlib_remove_close_display_hook (surface->display,
|
||||
&surface->close_display_hook);
|
||||
surface->dpy = NULL;
|
||||
_cairo_xlib_display_destroy (surface->display);
|
||||
}
|
||||
|
||||
surface->dpy = NULL;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
@ -2381,12 +2383,14 @@ _cairo_surface_is_xlib (cairo_surface_t *surface)
|
|||
|
||||
/* callback from CloseDisplay */
|
||||
static void
|
||||
_cairo_xlib_surface_detach_display (Display *dpy, void *data)
|
||||
_cairo_xlib_surface_detach_display (cairo_xlib_display_t *display, void *data)
|
||||
{
|
||||
cairo_xlib_surface_t *surface = cairo_container_of (data,
|
||||
cairo_xlib_surface_t,
|
||||
close_display_hook);
|
||||
Display *dpy;
|
||||
|
||||
dpy = surface->dpy;
|
||||
surface->dpy = NULL;
|
||||
|
||||
if (surface->dst_picture != None) {
|
||||
|
|
@ -2422,6 +2426,7 @@ _cairo_xlib_surface_create_internal (Display *dpy,
|
|||
int depth)
|
||||
{
|
||||
cairo_xlib_surface_t *surface;
|
||||
cairo_xlib_display_t *display;
|
||||
cairo_xlib_screen_info_t *screen_info;
|
||||
|
||||
CAIRO_MUTEX_INITIALIZE ();
|
||||
|
|
@ -2453,25 +2458,26 @@ _cairo_xlib_surface_create_internal (Display *dpy,
|
|||
if (depth == 0)
|
||||
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL));
|
||||
|
||||
screen_info = _cairo_xlib_screen_info_get (dpy, screen);
|
||||
if (screen_info == NULL)
|
||||
display = _cairo_xlib_display_get (dpy);
|
||||
if (display == NULL)
|
||||
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
|
||||
|
||||
screen_info = _cairo_xlib_screen_info_get (display, screen);
|
||||
if (screen_info == NULL) {
|
||||
_cairo_xlib_display_destroy (display);
|
||||
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
|
||||
}
|
||||
|
||||
surface = malloc (sizeof (cairo_xlib_surface_t));
|
||||
if (surface == NULL) {
|
||||
_cairo_xlib_screen_info_destroy (screen_info);
|
||||
_cairo_xlib_display_destroy (display);
|
||||
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
|
||||
}
|
||||
|
||||
/* initialize and hook into the CloseDisplay callback */
|
||||
surface->close_display_hook.func = _cairo_xlib_surface_detach_display;
|
||||
if (! _cairo_xlib_add_close_display_hook (dpy,
|
||||
&surface->close_display_hook))
|
||||
{
|
||||
free (surface);
|
||||
_cairo_xlib_screen_info_destroy (screen_info);
|
||||
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
|
||||
}
|
||||
_cairo_xlib_add_close_display_hook (display, &surface->close_display_hook);
|
||||
|
||||
if (! XRenderQueryVersion (dpy, &surface->render_major, &surface->render_minor)) {
|
||||
surface->render_major = -1;
|
||||
|
|
@ -2493,6 +2499,7 @@ _cairo_xlib_surface_create_internal (Display *dpy,
|
|||
_xrender_format_to_content (xrender_format));
|
||||
|
||||
surface->dpy = dpy;
|
||||
surface->display = display;
|
||||
surface->screen_info = screen_info;
|
||||
|
||||
surface->gc = NULL;
|
||||
|
|
@ -3000,8 +3007,8 @@ typedef struct _cairo_xlib_surface_font_private {
|
|||
|
||||
/* callback from CloseDisplay */
|
||||
static void
|
||||
_cairo_xlib_surface_remove_scaled_font (Display *dpy,
|
||||
void *data)
|
||||
_cairo_xlib_surface_remove_scaled_font (cairo_xlib_display_t *display,
|
||||
void *data)
|
||||
{
|
||||
cairo_xlib_surface_font_private_t *font_private;
|
||||
cairo_scaled_font_t *scaled_font;
|
||||
|
|
@ -3019,8 +3026,10 @@ _cairo_xlib_surface_remove_scaled_font (Display *dpy,
|
|||
CAIRO_MUTEX_UNLOCK (scaled_font->mutex);
|
||||
|
||||
if (font_private != NULL) {
|
||||
Display *dpy;
|
||||
int i;
|
||||
|
||||
dpy = display->display;
|
||||
for (i = 0; i < NUM_GLYPHSETS; i++) {
|
||||
cairo_xlib_font_glyphset_info_t *glyphset_info;
|
||||
|
||||
|
|
@ -3049,19 +3058,19 @@ _cairo_xlib_surface_font_init (Display *dpy,
|
|||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
font_private->scaled_font = scaled_font;
|
||||
|
||||
/* initialize and hook into the CloseDisplay callback */
|
||||
font_private->close_display_hook.func =
|
||||
_cairo_xlib_surface_remove_scaled_font;
|
||||
if (! _cairo_xlib_add_close_display_hook (dpy,
|
||||
&font_private->close_display_hook))
|
||||
{
|
||||
font_private->display = _cairo_xlib_display_get (dpy);
|
||||
if (font_private->display == NULL) {
|
||||
free (font_private);
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
/* initialize and hook into the CloseDisplay callback */
|
||||
font_private->close_display_hook.func =
|
||||
_cairo_xlib_surface_remove_scaled_font;
|
||||
_cairo_xlib_add_close_display_hook (font_private->display,
|
||||
&font_private->close_display_hook);
|
||||
|
||||
|
||||
font_private->display = _cairo_xlib_display_get (dpy);
|
||||
for (i = 0; i < NUM_GLYPHSETS; i++) {
|
||||
cairo_xlib_font_glyphset_info_t *glyphset_info = &font_private->glyphset_info[i];
|
||||
switch (i) {
|
||||
|
|
@ -3092,7 +3101,7 @@ _cairo_xlib_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font)
|
|||
int i;
|
||||
|
||||
display = font_private->display;
|
||||
_cairo_xlib_remove_close_display_hook (display->display,
|
||||
_cairo_xlib_remove_close_display_hook (display,
|
||||
&font_private->close_display_hook);
|
||||
|
||||
for (i = 0; i < NUM_GLYPHSETS; i++) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue