[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:
Chris Wilson 2008-09-02 10:28:17 +01:00
parent 939b836bfa
commit a5d33bcbb4
5 changed files with 49 additions and 62 deletions

View file

@ -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

View file

@ -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);

View file

@ -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;
}

View file

@ -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;

View file

@ -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++) {