From a5d33bcbb43cd1738e45b803c1aa968aff55e7ab Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 2 Sep 2008 10:28:17 +0100 Subject: [PATCH] [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.] --- src/cairo-xlib-display.c | 29 ++++------------ src/cairo-xlib-private.h | 10 +++--- src/cairo-xlib-screen.c | 14 +++----- src/cairo-xlib-surface-private.h | 1 + src/cairo-xlib-surface.c | 57 ++++++++++++++++++-------------- 5 files changed, 49 insertions(+), 62 deletions(-) diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c index ff2e08ed2..5e6dba115 100644 --- a/src/cairo-xlib-display.c +++ b/src/cairo-xlib-display.c @@ -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 diff --git a/src/cairo-xlib-private.h b/src/cairo-xlib-private.h index e9622780e..e381e584d 100644 --- a/src/cairo-xlib-private.h +++ b/src/cairo-xlib-private.h @@ -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); diff --git a/src/cairo-xlib-screen.c b/src/cairo-xlib-screen.c index 83015a2eb..4a26eee5f 100644 --- a/src/cairo-xlib-screen.c +++ b/src/cairo-xlib-screen.c @@ -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; } diff --git a/src/cairo-xlib-surface-private.h b/src/cairo-xlib-surface-private.h index a16e8e4ee..e06fd978c 100644 --- a/src/cairo-xlib-surface-private.h +++ b/src/cairo-xlib-surface-private.h @@ -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; diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index e9ff65d0d..d6f41099f 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -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++) {