[cairo-commit] src/cairo-xlib-display.c src/cairo-xlib-private.h src/cairo-xlib-screen.c src/cairo-xlib-surface.c src/cairo-xlib-surface-private.h

Benjamin Otte company at kemper.freedesktop.org
Sun Apr 18 14:29:04 PDT 2010


 src/cairo-xlib-display.c         |  234 ++++++----------
 src/cairo-xlib-private.h         |   66 ++--
 src/cairo-xlib-screen.c          |  161 ++---------
 src/cairo-xlib-surface-private.h |    2 
 src/cairo-xlib-surface.c         |  557 +++++++++++++++++++++++----------------
 5 files changed, 494 insertions(+), 526 deletions(-)

New commits:
commit f74ad37e66bbdcc4d727ed6d931dde870d84c2f4
Author: Benjamin Otte <otte at redhat.com>
Date:   Sun Apr 18 23:20:02 2010 +0200

    xlib: Make display a cairo_device_t
    
    The code now uses the locking of the cairo_device_t instead of its own
    mutexes.
    
    The code was modified so that cairo_surface_t does no longer reference
    the display directly. Instead, it calls _cairo_xlib_display_acquire().
    If a function assumes an already acquired display, it now requires the
    caller to provide a cairo_xlib_display_t parameter. Functions that do
    not require an acquired display will not require the display parameter
    or they will take the cairo_device_t instead.

diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c
index 69b7c66..be65c22 100644
--- a/src/cairo-xlib-display.c
+++ b/src/cairo-xlib-display.c
@@ -39,32 +39,9 @@
 #include "cairo-xlib-xrender-private.h"
 
 #include "cairo-error-private.h"
-#include "cairo-freelist-private.h"
 
 #include <X11/Xlibint.h>	/* For XESetCloseDisplay */
 
-struct _cairo_xlib_display {
-    cairo_xlib_display_t *next;
-    cairo_reference_count_t ref_count;
-    cairo_mutex_t mutex;
-
-    Display *display;
-    cairo_xlib_screen_t *screens;
-
-    int render_major;
-    int render_minor;
-    XRenderPictFormat *cached_xrender_formats[CAIRO_FORMAT_RGB16_565 + 1];
-
-    cairo_xlib_job_t *workqueue;
-    cairo_freelist_t wq_freelist;
-
-    cairo_xlib_hook_t *close_display_hooks;
-    unsigned int buggy_gradients :1;
-    unsigned int buggy_pad_reflect :1;
-    unsigned int buggy_repeat :1;
-    unsigned int closed :1;
-};
-
 typedef int (*cairo_xlib_error_func_t) (Display     *display,
 					XErrorEvent *event);
 
@@ -99,11 +76,8 @@ _cairo_xlib_call_close_display_hooks (cairo_xlib_display_t *display)
     cairo_xlib_screen_t	    *screen;
     cairo_xlib_hook_t		    *hook;
 
-    /* call all registered shutdown routines */
-    CAIRO_MUTEX_LOCK (display->mutex);
-
     for (screen = display->screens; screen != NULL; screen = screen->next)
-	_cairo_xlib_screen_close_display (screen);
+	_cairo_xlib_screen_close_display (display, screen);
 
     while (TRUE) {
 	hook = display->close_display_hooks;
@@ -112,13 +86,9 @@ _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, hook);
-	CAIRO_MUTEX_LOCK (display->mutex);
     }
     display->closed = TRUE;
-
-    CAIRO_MUTEX_UNLOCK (display->mutex);
 }
 
 static void
@@ -126,10 +96,8 @@ _cairo_xlib_display_discard_screens (cairo_xlib_display_t *display)
 {
     cairo_xlib_screen_t *screens;
 
-    CAIRO_MUTEX_LOCK (display->mutex);
     screens = display->screens;
     display->screens = NULL;
-    CAIRO_MUTEX_UNLOCK (display->mutex);
 
     while (screens != NULL) {
 	cairo_xlib_screen_t *screen = screens;
@@ -139,23 +107,10 @@ _cairo_xlib_display_discard_screens (cairo_xlib_display_t *display)
     }
 }
 
-cairo_xlib_display_t *
-_cairo_xlib_display_reference (cairo_xlib_display_t *display)
-{
-    assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&display->ref_count));
-
-    _cairo_reference_count_inc (&display->ref_count);
-
-    return display;
-}
-
-void
-_cairo_xlib_display_destroy (cairo_xlib_display_t *display)
+static void
+_cairo_xlib_display_destroy (void *abstract_display)
 {
-    assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&display->ref_count));
-
-    if (! _cairo_reference_count_dec_and_test (&display->ref_count))
-	return;
+    cairo_xlib_display_t *display = abstract_display;
 
     /* destroy all outstanding notifies */
     while (display->workqueue != NULL) {
@@ -169,8 +124,6 @@ _cairo_xlib_display_destroy (cairo_xlib_display_t *display)
     }
     _cairo_freelist_fini (&display->wq_freelist);
 
-    CAIRO_MUTEX_FINI (display->mutex);
-
     free (display);
 }
 
@@ -180,6 +133,60 @@ _noop_error_handler (Display     *display,
 {
     return False;		/* return value is ignored */
 }
+
+static void
+_cairo_xlib_display_notify (cairo_xlib_display_t *display)
+{
+    cairo_xlib_job_t *jobs, *job, *freelist;
+    Display *dpy = display->display;
+
+    /* Optimistic atomic pointer read -- don't care if it is wrong due to
+     * contention as we will check again very shortly.
+     */
+    if (display->workqueue == NULL)
+	return;
+
+    jobs = display->workqueue;
+    while (jobs != NULL) {
+	display->workqueue = NULL;
+
+	/* reverse the list to obtain FIFO order */
+	job = NULL;
+	do {
+	    cairo_xlib_job_t *next = jobs->next;
+	    jobs->next = job;
+	    job = jobs;
+	    jobs = next;
+	} while (jobs != NULL);
+	freelist = jobs = job;
+
+	do {
+	    job = jobs;
+	    jobs = job->next;
+
+	    switch (job->type){
+	    case WORK:
+		job->func.work.notify (dpy, job->func.work.data);
+		if (job->func.work.destroy != NULL)
+		    job->func.work.destroy (job->func.work.data);
+		break;
+
+	    case RESOURCE:
+		job->func.resource.notify (dpy, job->func.resource.xid);
+		break;
+	    }
+	} while (jobs != NULL);
+
+	do {
+	    job = freelist;
+	    freelist = job->next;
+	    _cairo_freelist_free (&display->wq_freelist, job);
+	} while (freelist != NULL);
+
+	jobs = display->workqueue;
+    }
+}
+
 static int
 _cairo_xlib_close_display (Display *dpy, XExtCodes *codes)
 {
@@ -198,12 +205,15 @@ _cairo_xlib_close_display (Display *dpy, XExtCodes *codes)
     XSync (dpy, False);
     old_handler = XSetErrorHandler (_noop_error_handler);
 
+    if (cairo_device_acquire (&display->base))
+        return 0;
     _cairo_xlib_display_notify (display);
     _cairo_xlib_call_close_display_hooks (display);
     _cairo_xlib_display_discard_screens (display);
 
     /* catch any that arrived before marking the display as closed */
     _cairo_xlib_display_notify (display);
+    cairo_device_release (&display->base);
 
     XSync (dpy, False);
     XSetErrorHandler (old_handler);
@@ -231,6 +241,17 @@ _cairo_xlib_close_display (Display *dpy, XExtCodes *codes)
     return 0;
 }
 
+static const cairo_device_backend_t _cairo_xlib_device_backend = {
+    CAIRO_DEVICE_TYPE_XLIB,
+
+    NULL,
+    NULL,
+
+    NULL, /* flush */
+    NULL, /* finish */
+    _cairo_xlib_display_destroy,
+};
+
 cairo_status_t
 _cairo_xlib_display_get (Display *dpy,
 			 cairo_xlib_display_t **out)
@@ -266,7 +287,7 @@ _cairo_xlib_display_get (Display *dpy,
     }
 
     if (display != NULL) {
-	display = _cairo_xlib_display_reference (display);
+        cairo_device_reference (&display->base);
 	goto UNLOCK;
     }
 
@@ -309,12 +330,13 @@ _cairo_xlib_display_get (Display *dpy,
 	goto UNLOCK;
     }
 
+    _cairo_device_init (&display->base, &_cairo_xlib_device_backend);
+
     XESetCloseDisplay (dpy, codes->extension, _cairo_xlib_close_display);
 
     _cairo_freelist_init (&display->wq_freelist, sizeof (cairo_xlib_job_t));
 
-    CAIRO_REFERENCE_COUNT_INIT (&display->ref_count, 2); /* add one for the CloseDisplay */
-    CAIRO_MUTEX_INIT (display->mutex);
+    cairo_device_reference (&display->base); /* add one for the CloseDisplay */
     display->display = dpy;
     display->screens = NULL;
     display->workqueue = NULL;
@@ -419,16 +441,13 @@ void
 _cairo_xlib_add_close_display_hook (cairo_xlib_display_t	*display,
 				    cairo_xlib_hook_t		*hook)
 {
-    CAIRO_MUTEX_LOCK (display->mutex);
     hook->prev = NULL;
     hook->next = display->close_display_hooks;
     if (hook->next != NULL)
 	hook->next->prev = hook;
     display->close_display_hooks = hook;
-    CAIRO_MUTEX_UNLOCK (display->mutex);
 }
 
-/* display->mutex must be held */
 static void
 _cairo_xlib_remove_close_display_hook_internal (cairo_xlib_display_t *display,
 						cairo_xlib_hook_t *hook)
@@ -449,9 +468,7 @@ void
 _cairo_xlib_remove_close_display_hook (cairo_xlib_display_t	*display,
 				       cairo_xlib_hook_t	*hook)
 {
-    CAIRO_MUTEX_LOCK (display->mutex);
     _cairo_xlib_remove_close_display_hook_internal (display, hook);
-    CAIRO_MUTEX_UNLOCK (display->mutex);
 }
 
 cairo_status_t
@@ -462,7 +479,6 @@ _cairo_xlib_display_queue_resource (cairo_xlib_display_t *display,
     cairo_xlib_job_t *job;
     cairo_status_t status = CAIRO_STATUS_NO_MEMORY;
 
-    CAIRO_MUTEX_LOCK (display->mutex);
     if (display->closed == FALSE) {
 	job = _cairo_freelist_alloc (&display->wq_freelist);
 	if (job != NULL) {
@@ -476,7 +492,6 @@ _cairo_xlib_display_queue_resource (cairo_xlib_display_t *display,
 	    status = CAIRO_STATUS_SUCCESS;
 	}
     }
-    CAIRO_MUTEX_UNLOCK (display->mutex);
 
     return status;
 }
@@ -490,7 +505,6 @@ _cairo_xlib_display_queue_work (cairo_xlib_display_t *display,
     cairo_xlib_job_t *job;
     cairo_status_t status = CAIRO_STATUS_NO_MEMORY;
 
-    CAIRO_MUTEX_LOCK (display->mutex);
     if (display->closed == FALSE) {
 	job = _cairo_freelist_alloc (&display->wq_freelist);
 	if (job != NULL) {
@@ -505,66 +519,22 @@ _cairo_xlib_display_queue_work (cairo_xlib_display_t *display,
 	    status = CAIRO_STATUS_SUCCESS;
 	}
     }
-    CAIRO_MUTEX_UNLOCK (display->mutex);
 
     return status;
 }
 
-void
-_cairo_xlib_display_notify (cairo_xlib_display_t *display)
+cairo_status_t
+_cairo_xlib_display_acquire (cairo_device_t *device, cairo_xlib_display_t **display)
 {
-    cairo_xlib_job_t *jobs, *job, *freelist;
-    Display *dpy = display->display;
-
-    /* Optimistic atomic pointer read -- don't care if it is wrong due to
-     * contention as we will check again very shortly.
-     */
-    if (display->workqueue == NULL)
-	return;
-
-    CAIRO_MUTEX_LOCK (display->mutex);
-    jobs = display->workqueue;
-    while (jobs != NULL) {
-	display->workqueue = NULL;
-	CAIRO_MUTEX_UNLOCK (display->mutex);
-
-	/* reverse the list to obtain FIFO order */
-	job = NULL;
-	do {
-	    cairo_xlib_job_t *next = jobs->next;
-	    jobs->next = job;
-	    job = jobs;
-	    jobs = next;
-	} while (jobs != NULL);
-	freelist = jobs = job;
+    cairo_status_t status;
 
-	do {
-	    job = jobs;
-	    jobs = job->next;
+    status = cairo_device_acquire (device);
+    if (status)
+        return status;
 
-	    switch (job->type){
-	    case WORK:
-		job->func.work.notify (dpy, job->func.work.data);
-		if (job->func.work.destroy != NULL)
-		    job->func.work.destroy (job->func.work.data);
-		break;
-
-	    case RESOURCE:
-		job->func.resource.notify (dpy, job->func.resource.xid);
-		break;
-	    }
-	} while (jobs != NULL);
-
-	CAIRO_MUTEX_LOCK (display->mutex);
-	do {
-	    job = freelist;
-	    freelist = job->next;
-	    _cairo_freelist_free (&display->wq_freelist, job);
-	} while (freelist != NULL);
-
-	jobs = display->workqueue;
-    }
-    CAIRO_MUTEX_UNLOCK (display->mutex);
+    *display = (cairo_xlib_display_t *) device;
+    _cairo_xlib_display_notify (*display);
+    return status;
 }
 
 XRenderPictFormat *
@@ -579,7 +549,6 @@ _cairo_xlib_display_get_xrender_format (cairo_xlib_display_t	*display,
 	return xrender_format;
 #endif
 
-    CAIRO_MUTEX_LOCK (display->mutex);
     xrender_format = display->cached_xrender_formats[format];
     if (xrender_format == NULL) {
 	int pict_format;
@@ -605,10 +574,8 @@ _cairo_xlib_display_get_xrender_format (cairo_xlib_display_t	*display,
 	            break;
 	        }
 	    }
-	    if (!visual) {
-	        CAIRO_MUTEX_UNLOCK (display->mutex);
+	    if (!visual)
 	        return NULL;
-	    }
 	    xrender_format = XRenderFindVisualFormat(display->display, visual);
 	    break;
 	}
@@ -623,17 +590,10 @@ _cairo_xlib_display_get_xrender_format (cairo_xlib_display_t	*display,
 		                                        pict_format);
 	display->cached_xrender_formats[format] = xrender_format;
     }
-    CAIRO_MUTEX_UNLOCK (display->mutex);
 
     return xrender_format;
 }
 
-Display *
-_cairo_xlib_display_get_dpy (cairo_xlib_display_t *display)
-{
-    return display->display;
-}
-
 void
 _cairo_xlib_display_remove_screen (cairo_xlib_display_t *display,
 				   cairo_xlib_screen_t *screen)
@@ -641,14 +601,12 @@ _cairo_xlib_display_remove_screen (cairo_xlib_display_t *display,
     cairo_xlib_screen_t **prev;
     cairo_xlib_screen_t *list;
 
-    CAIRO_MUTEX_LOCK (display->mutex);
     for (prev = &display->screens; (list = *prev); prev = &list->next) {
 	if (list == screen) {
 	    *prev = screen->next;
 	    break;
 	}
     }
-    CAIRO_MUTEX_UNLOCK (display->mutex);
 }
 
 cairo_status_t
@@ -658,11 +616,8 @@ _cairo_xlib_display_get_screen (cairo_xlib_display_t *display,
 {
     cairo_xlib_screen_t *info = NULL, **prev;
 
-    CAIRO_MUTEX_LOCK (display->mutex);
-    if (display->closed) {
-	CAIRO_MUTEX_UNLOCK (display->mutex);
+    if (display->closed)
 	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
-    }
 
     for (prev = &display->screens; (info = *prev); prev = &(*prev)->next) {
 	if (info->screen == screen) {
@@ -677,7 +632,6 @@ _cairo_xlib_display_get_screen (cairo_xlib_display_t *display,
 	    break;
 	}
     }
-    CAIRO_MUTEX_UNLOCK (display->mutex);
 
     *out = info;
     return CAIRO_STATUS_SUCCESS;
@@ -688,10 +642,8 @@ void
 _cairo_xlib_display_add_screen (cairo_xlib_display_t *display,
 				cairo_xlib_screen_t *screen)
 {
-    CAIRO_MUTEX_LOCK (display->mutex);
     screen->next = display->screens;
     display->screens = screen;
-    CAIRO_MUTEX_UNLOCK (display->mutex);
 }
 
 void
@@ -703,19 +655,19 @@ _cairo_xlib_display_get_xrender_version (cairo_xlib_display_t *display,
 }
 
 cairo_bool_t
-_cairo_xlib_display_has_repeat (cairo_xlib_display_t *display)
+_cairo_xlib_display_has_repeat (cairo_device_t *device)
 {
-    return ! display->buggy_repeat;
+    return ! ((cairo_xlib_display_t *) device)->buggy_repeat;
 }
 
 cairo_bool_t
-_cairo_xlib_display_has_reflect (cairo_xlib_display_t *display)
+_cairo_xlib_display_has_reflect (cairo_device_t *device)
 {
-    return ! display->buggy_pad_reflect;
+    return ! ((cairo_xlib_display_t *) device)->buggy_pad_reflect;
 }
 
 cairo_bool_t
-_cairo_xlib_display_has_gradients (cairo_xlib_display_t *display)
+_cairo_xlib_display_has_gradients (cairo_device_t *device)
 {
-    return ! display->buggy_gradients;
+    return ! ((cairo_xlib_display_t *) device)->buggy_gradients;
 }
diff --git a/src/cairo-xlib-private.h b/src/cairo-xlib-private.h
index afdf6a6..550520d 100644
--- a/src/cairo-xlib-private.h
+++ b/src/cairo-xlib-private.h
@@ -41,7 +41,8 @@
 #include "cairo-xlib-xrender-private.h"
 
 #include "cairo-compiler-private.h"
-#include "cairo-mutex-private.h"
+#include "cairo-device-private.h"
+#include "cairo-freelist-private.h"
 #include "cairo-reference-count-private.h"
 #include "cairo-types-private.h"
 
@@ -63,6 +64,28 @@ struct _cairo_xlib_hook {
 /* size of gray ramp */
 #define RAMP_SIZE 16
 
+struct _cairo_xlib_display {
+    cairo_device_t base;
+
+    cairo_xlib_display_t *next;
+
+    Display *display;
+    cairo_xlib_screen_t *screens;
+
+    int render_major;
+    int render_minor;
+    XRenderPictFormat *cached_xrender_formats[CAIRO_FORMAT_RGB16_565 + 1];
+
+    cairo_xlib_job_t *workqueue;
+    cairo_freelist_t wq_freelist;
+
+    cairo_xlib_hook_t *close_display_hooks;
+    unsigned int buggy_gradients :1;
+    unsigned int buggy_pad_reflect :1;
+    unsigned int buggy_repeat :1;
+    unsigned int closed :1;
+};
+
 typedef struct _cairo_xlib_visual_info {
     VisualID visualid;
     struct { uint8_t a, r, g, b; } colors[256];
@@ -75,9 +98,8 @@ typedef struct _cairo_xlib_visual_info {
 struct _cairo_xlib_screen {
     cairo_xlib_screen_t *next;
     cairo_reference_count_t ref_count;
-    cairo_mutex_t mutex;
 
-    cairo_xlib_display_t *display;
+    cairo_device_t *device;
     Screen *screen;
     cairo_bool_t has_render;
 
@@ -93,21 +115,6 @@ struct _cairo_xlib_screen {
 cairo_private cairo_status_t
 _cairo_xlib_display_get (Display *display, cairo_xlib_display_t **out);
 
-cairo_private cairo_xlib_display_t *
-_cairo_xlib_display_reference (cairo_xlib_display_t *info);
-
-cairo_private void
-_cairo_xlib_display_destroy (cairo_xlib_display_t *info);
-
-cairo_private void
-_cairo_xlib_display_lock (cairo_xlib_display_t *display);
-
-cairo_private void
-_cairo_xlib_display_unlock (cairo_xlib_display_t *display);
-
-cairo_private Display *
-_cairo_xlib_display_get_dpy (cairo_xlib_display_t *info);
-
 cairo_private void
 _cairo_xlib_display_add_screen (cairo_xlib_display_t *display,
 				cairo_xlib_screen_t *screen);
@@ -136,21 +143,22 @@ cairo_private cairo_status_t
 _cairo_xlib_display_queue_resource (cairo_xlib_display_t *display,
 	                           cairo_xlib_notify_resource_func notify,
 				   XID resource);
-cairo_private void
-_cairo_xlib_display_notify (cairo_xlib_display_t *display);
+cairo_private cairo_status_t
+_cairo_xlib_display_acquire (cairo_device_t *device,
+                             cairo_xlib_display_t **display);
 
 cairo_private void
 _cairo_xlib_display_get_xrender_version (cairo_xlib_display_t *display,
 					 int *major, int *minor);
 
 cairo_private cairo_bool_t
-_cairo_xlib_display_has_repeat (cairo_xlib_display_t *display);
+_cairo_xlib_display_has_repeat (cairo_device_t *device);
 
 cairo_private cairo_bool_t
-_cairo_xlib_display_has_reflect (cairo_xlib_display_t *display);
+_cairo_xlib_display_has_reflect (cairo_device_t *device);
 
 cairo_private cairo_bool_t
-_cairo_xlib_display_has_gradients (cairo_xlib_display_t *display);
+_cairo_xlib_display_has_gradients (cairo_device_t *device);
 
 cairo_private XRenderPictFormat *
 _cairo_xlib_display_get_xrender_format (cairo_xlib_display_t	*display,
@@ -167,15 +175,18 @@ cairo_private void
 _cairo_xlib_screen_destroy (cairo_xlib_screen_t *info);
 
 cairo_private void
-_cairo_xlib_screen_close_display (cairo_xlib_screen_t *info);
+_cairo_xlib_screen_close_display (cairo_xlib_display_t *display,
+                                  cairo_xlib_screen_t *info);
 
 cairo_private GC
-_cairo_xlib_screen_get_gc (cairo_xlib_screen_t *info,
+_cairo_xlib_screen_get_gc (cairo_xlib_display_t *display,
+                           cairo_xlib_screen_t *info,
 			   int depth,
 			   Drawable drawable);
 
 cairo_private void
-_cairo_xlib_screen_put_gc (cairo_xlib_screen_t *info,
+_cairo_xlib_screen_put_gc (cairo_xlib_display_t *display,
+                           cairo_xlib_screen_t *info,
 			   int depth,
 			   GC gc);
 
@@ -183,7 +194,8 @@ cairo_private cairo_font_options_t *
 _cairo_xlib_screen_get_font_options (cairo_xlib_screen_t *info);
 
 cairo_private cairo_status_t
-_cairo_xlib_screen_get_visual_info (cairo_xlib_screen_t *info,
+_cairo_xlib_screen_get_visual_info (cairo_xlib_display_t *display,
+                                    cairo_xlib_screen_t *info,
 				    Visual *visual,
 				    cairo_xlib_visual_info_t **out);
 
diff --git a/src/cairo-xlib-screen.c b/src/cairo-xlib-screen.c
index 18f974b..2831aca 100644
--- a/src/cairo-xlib-screen.c
+++ b/src/cairo-xlib-screen.c
@@ -267,25 +267,18 @@ _cairo_xlib_screen_reference (cairo_xlib_screen_t *info)
 }
 
 void
-_cairo_xlib_screen_close_display (cairo_xlib_screen_t *info)
+_cairo_xlib_screen_close_display (cairo_xlib_display_t *display,
+                                  cairo_xlib_screen_t  *info)
 {
     cairo_xlib_visual_info_t **visuals;
     Display *dpy;
     cairo_atomic_int_t old;
     int i;
 
-    CAIRO_MUTEX_LOCK (info->mutex);
+    dpy = display->display;
 
-    dpy = _cairo_xlib_display_get_dpy (info->display);
-
-#if HAS_ATOMIC_OPS
-    do {
-	old = _cairo_atomic_int_get (&info->gc_depths);
-    } while (_cairo_atomic_int_cmpxchg (&info->gc_depths, old, 0) != old);
-#else
     old = info->gc_depths;
     info->gc_depths = 0;
-#endif
 
     for (i = 0; i < ARRAY_LENGTH (info->gc); i++) {
 	if ((old >> (8*i)) & 0xff)
@@ -296,28 +289,28 @@ _cairo_xlib_screen_close_display (cairo_xlib_screen_t *info)
     for (i = 0; i < _cairo_array_num_elements (&info->visuals); i++)
 	_cairo_xlib_visual_info_destroy (dpy, visuals[i]);
     _cairo_array_truncate (&info->visuals, 0);
-
-    CAIRO_MUTEX_UNLOCK (info->mutex);
 }
 
 void
 _cairo_xlib_screen_destroy (cairo_xlib_screen_t *info)
 {
+    cairo_xlib_display_t *display;
+
     assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&info->ref_count));
 
     if (! _cairo_reference_count_dec_and_test (&info->ref_count))
 	return;
 
-    _cairo_xlib_display_remove_screen (info->display, info);
+    if (! _cairo_xlib_display_acquire (info->device, &display)) {
+        _cairo_xlib_display_remove_screen (display, info);
+        _cairo_xlib_screen_close_display (display, info);
 
-    _cairo_xlib_screen_close_display (info);
-
-    _cairo_xlib_display_destroy (info->display);
+        cairo_device_release (&display->base);
+    }
+    cairo_device_destroy (info->device);
 
     _cairo_array_fini (&info->visuals);
 
-    CAIRO_MUTEX_FINI (info->mutex);
-
     free (info);
 }
 
@@ -348,8 +341,7 @@ _cairo_xlib_screen_get (Display *dpy,
     }
 
     CAIRO_REFERENCE_COUNT_INIT (&info->ref_count, 2); /* Add one for display cache */
-    CAIRO_MUTEX_INIT (info->mutex);
-    info->display = display;
+    info->device = &display->base;
     info->screen = screen;
     info->has_render = FALSE;
     info->has_font_options = FALSE;
@@ -377,103 +369,19 @@ _cairo_xlib_screen_get (Display *dpy,
     return CAIRO_STATUS_SUCCESS;
 
   CLEANUP_DISPLAY:
-    _cairo_xlib_display_destroy (display);
+    cairo_device_destroy ((cairo_device_t *) display);
     return status;
 }
 
-#if HAS_ATOMIC_OPS
-GC
-_cairo_xlib_screen_get_gc (cairo_xlib_screen_t *info,
-			   int depth,
-			   Drawable drawable)
-{
-    XGCValues gcv;
-    cairo_atomic_int_t old, new;
-    int i;
-    GC gc;
-
-    do {
-	gc = NULL;
-	old = info->gc_depths;
-	if (old == 0)
-	    break;
-
-	if (((old >> 0) & 0xff) == depth)
-	    i = 0;
-	else if (((old >> 8) & 0xff) == depth)
-	    i = 1;
-	else if (((old >> 16) & 0xff) == depth)
-	    i = 2;
-	else if (((old >> 24) & 0xff) == depth)
-	    i = 3;
-	else
-	    break;
-
-	gc = info->gc[i];
-	new = old & ~(0xff << (8*i));
-    } while (_cairo_atomic_int_cmpxchg (&info->gc_depths, old, new) != old);
-
-    if (likely (gc != NULL)) {
-	(void) _cairo_atomic_ptr_cmpxchg (&info->gc[i], gc, NULL);
-	return gc;
-    }
-
-    gcv.graphics_exposures = False;
-    gcv.fill_style = FillTiled;
-    return XCreateGC (_cairo_xlib_display_get_dpy (info->display),
-		      drawable,
-		      GCGraphicsExposures | GCFillStyle, &gcv);
-}
-
-void
-_cairo_xlib_screen_put_gc (cairo_xlib_screen_t *info,
-			   int depth,
-			   GC gc)
-{
-    int i, old, new;
-
-    do {
-	do {
-	    i = -1;
-	    old = info->gc_depths;
-
-	    if (((old >> 0) & 0xff) == 0)
-		i = 0;
-	    else if (((old >> 8) & 0xff) == 0)
-		i = 1;
-	    else if (((old >> 16) & 0xff) == 0)
-		i = 2;
-	    else if (((old >> 24) & 0xff) == 0)
-		i = 3;
-	    else
-		goto out;
-
-	    new = old | (depth << (8*i));
-	} while (_cairo_atomic_ptr_cmpxchg (&info->gc[i], NULL, gc) != NULL);
-    } while (_cairo_atomic_int_cmpxchg (&info->gc_depths, old, new) != old);
-
-    return;
-
-out:
-    if (unlikely (_cairo_xlib_display_queue_work (info->display,
-				(cairo_xlib_notify_func) XFreeGC,
-				gc,
-				NULL)))
-    {
-	/* leak the server side resource... */
-	XFree ((char *) gc);
-    }
-}
-#else
 GC
-_cairo_xlib_screen_get_gc (cairo_xlib_screen_t *info,
+_cairo_xlib_screen_get_gc (cairo_xlib_display_t *display,
+                           cairo_xlib_screen_t *info,
 			   int depth,
 			   Drawable drawable)
 {
     GC gc = NULL;
     int i;
 
-    CAIRO_MUTEX_LOCK (info->mutex);
     for (i = 0; i < ARRAY_LENGTH (info->gc); i++) {
 	if (((info->gc_depths >> (8*i)) & 0xff) == depth) {
 	    info->gc_depths &= ~(0xff << (8*i));
@@ -481,14 +389,13 @@ _cairo_xlib_screen_get_gc (cairo_xlib_screen_t *info,
 	    break;
 	}
     }
-    CAIRO_MUTEX_UNLOCK (info->mutex);
 
     if (gc == NULL) {
 	XGCValues gcv;
 
 	gcv.graphics_exposures = False;
 	gcv.fill_style = FillTiled;
-	gc = XCreateGC (_cairo_xlib_display_get_dpy (info->display),
+	gc = XCreateGC (display->display,
 			drawable,
 			GCGraphicsExposures | GCFillStyle, &gcv);
     }
@@ -497,13 +404,13 @@ _cairo_xlib_screen_get_gc (cairo_xlib_screen_t *info,
 }
 
 void
-_cairo_xlib_screen_put_gc (cairo_xlib_screen_t *info,
+_cairo_xlib_screen_put_gc (cairo_xlib_display_t *display,
+                           cairo_xlib_screen_t *info,
 			   int depth,
 			   GC gc)
 {
     int i;
 
-    CAIRO_MUTEX_LOCK (info->mutex);
     for (i = 0; i < ARRAY_LENGTH (info->gc); i++) {
 	if (((info->gc_depths >> (8*i)) & 0xff) == 0)
 	    break;
@@ -515,7 +422,7 @@ _cairo_xlib_screen_put_gc (cairo_xlib_screen_t *info,
 	/* perform random substitution to ensure fair caching over depths */
 	i = rand () % ARRAY_LENGTH (info->gc);
 	status =
-	    _cairo_xlib_display_queue_work (info->display,
+	    _cairo_xlib_display_queue_work (display,
 					    (cairo_xlib_notify_func) XFreeGC,
 					    info->gc[i],
 					    NULL);
@@ -528,21 +435,18 @@ _cairo_xlib_screen_put_gc (cairo_xlib_screen_t *info,
     info->gc[i] = gc;
     info->gc_depths &= ~(0xff << (8*i));
     info->gc_depths |= depth << (8*i);
-    CAIRO_MUTEX_UNLOCK (info->mutex);
 }
-#endif
 
 cairo_status_t
-_cairo_xlib_screen_get_visual_info (cairo_xlib_screen_t *info,
+_cairo_xlib_screen_get_visual_info (cairo_xlib_display_t *display,
+                                    cairo_xlib_screen_t *info,
 				    Visual *visual,
 				    cairo_xlib_visual_info_t **out)
 {
-    Display *dpy = _cairo_xlib_display_get_dpy (info->display);
     cairo_xlib_visual_info_t **visuals, *ret = NULL;
     cairo_status_t status;
     int i, n_visuals;
 
-    CAIRO_MUTEX_LOCK (info->mutex);
     visuals = _cairo_array_index (&info->visuals, 0);
     n_visuals = _cairo_array_num_elements (&info->visuals);
     for (i = 0; i < n_visuals; i++) {
@@ -551,28 +455,26 @@ _cairo_xlib_screen_get_visual_info (cairo_xlib_screen_t *info,
 	    break;
 	}
     }
-    CAIRO_MUTEX_UNLOCK (info->mutex);
 
     if (ret != NULL) {
 	*out = ret;
 	return CAIRO_STATUS_SUCCESS;
     }
 
-    status = _cairo_xlib_visual_info_create (dpy,
+    status = _cairo_xlib_visual_info_create (display->display,
 					     XScreenNumberOfScreen (info->screen),
 					     visual->visualid,
 					     &ret);
     if (unlikely (status))
 	return status;
 
-    CAIRO_MUTEX_LOCK (info->mutex);
     if (n_visuals != _cairo_array_num_elements (&info->visuals)) {
 	/* check that another thread has not added our visual */
 	int new_visuals = _cairo_array_num_elements (&info->visuals);
 	visuals = _cairo_array_index (&info->visuals, 0);
 	for (i = n_visuals; i < new_visuals; i++) {
 	    if (visuals[i]->visualid == visual->visualid) {
-		_cairo_xlib_visual_info_destroy (dpy, ret);
+		_cairo_xlib_visual_info_destroy (display->display, ret);
 		ret = visuals[i];
 		break;
 	    }
@@ -581,10 +483,9 @@ _cairo_xlib_screen_get_visual_info (cairo_xlib_screen_t *info,
 	    status = _cairo_array_append (&info->visuals, &ret);
     } else
 	status = _cairo_array_append (&info->visuals, &ret);
-    CAIRO_MUTEX_UNLOCK (info->mutex);
 
     if (unlikely (status)) {
-	_cairo_xlib_visual_info_destroy (dpy, ret);
+	_cairo_xlib_visual_info_destroy (display->display, ret);
 	return status;
     }
 
@@ -595,21 +496,21 @@ _cairo_xlib_screen_get_visual_info (cairo_xlib_screen_t *info,
 cairo_font_options_t *
 _cairo_xlib_screen_get_font_options (cairo_xlib_screen_t *info)
 {
-    if (info->has_font_options)
-	return &info->font_options;
-
-    CAIRO_MUTEX_LOCK (info->mutex);
     if (! info->has_font_options) {
 	_cairo_font_options_init_default (&info->font_options);
 
 	if (info->screen != NULL) {
-	    _cairo_xlib_init_screen_font_options (_cairo_xlib_display_get_dpy (info->display),
-						  info);
+            cairo_xlib_display_t *display;
+
+            if (! _cairo_xlib_display_acquire (info->device, &display)) {
+                _cairo_xlib_init_screen_font_options (display->display,
+                                                      info);
+                cairo_device_release (&display->base);
+            }
 	}
 
 	info->has_font_options = TRUE;
     }
-    CAIRO_MUTEX_UNLOCK (info->mutex);
 
     return &info->font_options;
 }
diff --git a/src/cairo-xlib-surface-private.h b/src/cairo-xlib-surface-private.h
index b30848d..8309246 100644
--- a/src/cairo-xlib-surface-private.h
+++ b/src/cairo-xlib-surface-private.h
@@ -44,8 +44,6 @@ typedef struct _cairo_xlib_surface cairo_xlib_surface_t;
 struct _cairo_xlib_surface {
     cairo_surface_t base;
 
-    Display *dpy;
-    cairo_xlib_display_t *display;
     cairo_xlib_screen_t *screen;
     cairo_xlib_hook_t close_display_hook;
 
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 51c0f83..f127a9c 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -118,18 +118,6 @@ _cairo_xlib_surface_create_internal (cairo_xlib_screen_t	*screen,
 				     int			height,
 				     int			depth);
 
-static cairo_status_t
-_cairo_xlib_surface_get_gc (cairo_xlib_surface_t *surface, GC *gc);
-
-static void
-_cairo_xlib_surface_put_gc (cairo_xlib_surface_t *surface, GC gc);
-
-static void
-_cairo_xlib_surface_ensure_src_picture (cairo_xlib_surface_t *surface);
-
-static void
-_cairo_xlib_surface_ensure_dst_picture (cairo_xlib_surface_t *surface);
-
 static cairo_bool_t
 _cairo_surface_is_xlib (cairo_surface_t *surface);
 
@@ -285,6 +273,7 @@ _cairo_xlib_surface_create_similar (void	       *abstract_src,
     cairo_xlib_surface_t *src = abstract_src;
     XRenderPictFormat *xrender_format;
     cairo_xlib_surface_t *surface;
+    cairo_xlib_display_t *display;
     Pixmap pix;
 
     if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX)
@@ -293,7 +282,8 @@ _cairo_xlib_surface_create_similar (void	       *abstract_src,
     if (! CAIRO_SURFACE_RENDER_HAS_CREATE_PICTURE (src))
 	return NULL;
 
-    _cairo_xlib_display_notify (src->display);
+    if (_cairo_xlib_display_acquire (src->base.device, &display))
+        return NULL;
 
     /* If we never found an XRenderFormat or if it isn't compatible
      * with the content being requested, then we fallback to just
@@ -304,7 +294,7 @@ _cairo_xlib_surface_create_similar (void	       *abstract_src,
     if ((xrender_format != NULL &&
 	_xrender_format_to_content (xrender_format) == content) ||
 	(xrender_format =
-	 _cairo_xlib_display_get_xrender_format (src->display,
+	 _cairo_xlib_display_get_xrender_format (display,
 						 _cairo_format_from_content (content))))
     {
 	Visual *visual;
@@ -312,7 +302,7 @@ _cairo_xlib_surface_create_similar (void	       *abstract_src,
 	/* We've got a compatible XRenderFormat now, which means the
 	 * similar surface will match the existing surface as closely in
 	 * visual/depth etc. as possible. */
-	pix = XCreatePixmap (src->dpy, src->drawable,
+	pix = XCreatePixmap (display->display, src->drawable,
 			     width <= 0 ? 1 : width, height <= 0 ? 1 : height,
 			     xrender_format->depth);
 
@@ -335,12 +325,14 @@ _cairo_xlib_surface_create_similar (void	       *abstract_src,
 
 	/* No compatabile XRenderFormat, see if we can make an ordinary pixmap,
 	 * so that we can still accelerate blits with XCopyArea(). */
-	if (content != CAIRO_CONTENT_COLOR)
+	if (content != CAIRO_CONTENT_COLOR) {
+            cairo_device_release (&display->base);
 	    return NULL;
+        }
 
 	depth = DefaultDepthOfScreen (screen);
 
-	pix = XCreatePixmap (src->dpy, RootWindowOfScreen (screen),
+	pix = XCreatePixmap (display->display, RootWindowOfScreen (screen),
 			     width <= 0 ? 1 : width, height <= 0 ? 1 : height,
 			     depth);
 
@@ -351,17 +343,21 @@ _cairo_xlib_surface_create_similar (void	       *abstract_src,
 						       width, height, depth);
 #else
 	/* No compatabile XRenderFormat, just say no. */
+        cairo_device_release (&display->base);
 	return NULL;
 #endif
     }
 
     if (unlikely (surface->base.status)) {
-	XFreePixmap (src->dpy, pix);
+	XFreePixmap (display->display, pix);
+        cairo_device_release (&display->base);
 	return &surface->base;
     }
 
     surface->owns_pixmap = TRUE;
 
+    cairo_device_release (&display->base);
+
     return &surface->base;
 }
 
@@ -369,10 +365,14 @@ static cairo_status_t
 _cairo_xlib_surface_finish (void *abstract_surface)
 {
     cairo_xlib_surface_t *surface = abstract_surface;
-    cairo_xlib_display_t *display = surface->display;
-    cairo_status_t        status  = CAIRO_STATUS_SUCCESS;
+    cairo_status_t        status;
+    cairo_xlib_display_t *display;
+
+    X_DEBUG ((display->display, "finish (drawable=%x)", (unsigned int) surface->drawable));
 
-    X_DEBUG ((surface->dpy, "finish (drawable=%x)", (unsigned int) surface->drawable));
+    status = _cairo_xlib_display_acquire (surface->base.device, &display);
+    if (unlikely (status))
+        return status;
 
     if (surface->owns_pixmap) {
 	cairo_status_t status2;
@@ -400,20 +400,20 @@ _cairo_xlib_surface_finish (void *abstract_surface)
 	    status = status2;
     } else {
 	if (surface->dst_picture != None)
-	    XRenderFreePicture (surface->dpy, surface->dst_picture);
+	    XRenderFreePicture (display->display, surface->dst_picture);
 
 	if (surface->src_picture != None)
-	    XRenderFreePicture (surface->dpy, surface->src_picture);
+	    XRenderFreePicture (display->display, surface->src_picture);
     }
 
     if (surface->clip_rects != surface->embedded_clip_rects)
 	free (surface->clip_rects);
 
-    if (surface->dpy != NULL) {
-	_cairo_xlib_remove_close_display_hook (surface->display,
+    if (display->display != NULL)
+	_cairo_xlib_remove_close_display_hook (display,
 					       &surface->close_display_hook);
-	surface->dpy = NULL;
-    }
+
+    cairo_device_release (&display->base);
 
     _cairo_xlib_screen_destroy (surface->screen);
 
@@ -422,6 +422,32 @@ _cairo_xlib_surface_finish (void *abstract_surface)
     return status;
 }
 
+static cairo_status_t
+_cairo_xlib_surface_get_gc (cairo_xlib_display_t *display,
+                            cairo_xlib_surface_t *surface,
+                            GC                   *gc)
+{
+    *gc = _cairo_xlib_screen_get_gc (display,
+                                     surface->screen,
+				     surface->depth,
+				     surface->drawable);
+    if (unlikely (*gc == NULL))
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static void
+_cairo_xlib_surface_put_gc (cairo_xlib_display_t *display,
+                            cairo_xlib_surface_t *surface,
+                            GC                    gc)
+{
+    _cairo_xlib_screen_put_gc (display,
+                               surface->screen,
+			       surface->depth,
+			       gc);
+}
+
 static int
 _noop_error_handler (Display     *display,
 		     XErrorEvent *event)
@@ -708,6 +734,7 @@ _get_image_surface (cairo_xlib_surface_t    *surface,
     cairo_rectangle_int_t extents;
     pixman_format_code_t pixman_format;
     cairo_format_masks_t xlib_masks;
+    cairo_xlib_display_t *display;
 
     extents.x = 0;
     extents.y = 0;
@@ -721,6 +748,10 @@ _get_image_surface (cairo_xlib_surface_t    *surface,
 	}
     }
 
+    status = _cairo_xlib_display_acquire (surface->base.device, &display);
+    if (status)
+        return status;
+
     if (image_rect)
 	*image_rect = extents;
 
@@ -732,7 +763,7 @@ _get_image_surface (cairo_xlib_surface_t    *surface,
 
 	old_handler = XSetErrorHandler (_noop_error_handler);
 
-	ximage = XGetImage (surface->dpy,
+	ximage = XGetImage (display->display,
 			    surface->drawable,
 			    extents.x, extents.y,
 			    extents.width, extents.height,
@@ -762,33 +793,35 @@ _get_image_surface (cairo_xlib_surface_t    *surface,
 	Pixmap pixmap;
 	GC gc;
 
-	status = _cairo_xlib_surface_get_gc (surface, &gc);
+	status = _cairo_xlib_surface_get_gc (display, surface, &gc);
 	if (unlikely (status))
-	    return status;
+            goto BAIL;
 
-	pixmap = XCreatePixmap (surface->dpy,
+	pixmap = XCreatePixmap (display->display,
 				surface->drawable,
 				extents.width, extents.height,
 				surface->depth);
 	if (pixmap) {
-	    XCopyArea (surface->dpy, surface->drawable, pixmap, gc,
+	    XCopyArea (display->display, surface->drawable, pixmap, gc,
 		       extents.x, extents.y,
 		       extents.width, extents.height,
 		       0, 0);
 
-	    ximage = XGetImage (surface->dpy,
+	    ximage = XGetImage (display->display,
 				pixmap,
 				0, 0,
 				extents.width, extents.height,
 				AllPlanes, ZPixmap);
 
-	    XFreePixmap (surface->dpy, pixmap);
+	    XFreePixmap (display->display, pixmap);
 	}
 
-	_cairo_xlib_surface_put_gc (surface, gc);
+	_cairo_xlib_surface_put_gc (display, surface, gc);
 
-	if (ximage == NULL)
-	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	if (ximage == NULL) {
+	    status =  _cairo_error (CAIRO_STATUS_NO_MEMORY);
+            goto BAIL;
+        }
     }
 
     _swap_ximage_to_native (ximage);
@@ -873,7 +906,8 @@ _get_image_surface (cairo_xlib_surface_t    *surface,
 	} else {
 	    format = CAIRO_FORMAT_RGB24;
 
-	    status = _cairo_xlib_screen_get_visual_info (surface->screen,
+	    status = _cairo_xlib_screen_get_visual_info (display,
+                                                         surface->screen,
 							 surface->visual,
 							 &visual_info);
 	    if (unlikely (status))
@@ -919,7 +953,10 @@ _get_image_surface (cairo_xlib_surface_t    *surface,
     }
 
  BAIL:
-    XDestroyImage (ximage);
+    if (ximage)
+        XDestroyImage (ximage);
+
+    cairo_device_release (&display->base);
 
     if (unlikely (status)) {
 	if (image) {
@@ -932,7 +969,8 @@ _get_image_surface (cairo_xlib_surface_t    *surface,
 }
 
 static void
-_cairo_xlib_surface_ensure_src_picture (cairo_xlib_surface_t    *surface)
+_cairo_xlib_surface_ensure_src_picture (cairo_xlib_display_t *display,
+                                        cairo_xlib_surface_t *surface)
 {
     if (!surface->src_picture) {
 	XRenderPictureAttributes pa;
@@ -941,7 +979,7 @@ _cairo_xlib_surface_ensure_src_picture (cairo_xlib_surface_t    *surface)
 	pa.subwindow_mode = IncludeInferiors;
 	mask |= CPSubwindowMode;
 
-	surface->src_picture = XRenderCreatePicture (surface->dpy,
+	surface->src_picture = XRenderCreatePicture (display->display,
 						     surface->drawable,
 						     surface->xrender_format,
 						     mask, &pa);
@@ -949,17 +987,18 @@ _cairo_xlib_surface_ensure_src_picture (cairo_xlib_surface_t    *surface)
 }
 
 static void
-_cairo_xlib_surface_set_picture_clip_rects (cairo_xlib_surface_t *surface)
+_cairo_xlib_surface_set_picture_clip_rects (cairo_xlib_display_t *display,
+                                            cairo_xlib_surface_t *surface)
 {
     if (surface->clip_region != NULL) {
-	XRenderSetPictureClipRectangles (surface->dpy, surface->dst_picture,
+	XRenderSetPictureClipRectangles (display->display, surface->dst_picture,
 					 0, 0,
 					 surface->clip_rects,
 					 surface->num_clip_rects);
     } else {
 	XRenderPictureAttributes pa;
 	pa.clip_mask = None;
-	XRenderChangePicture (surface->dpy, surface->dst_picture,
+	XRenderChangePicture (display->display, surface->dst_picture,
 			      CPClipMask, &pa);
     }
 
@@ -967,37 +1006,18 @@ _cairo_xlib_surface_set_picture_clip_rects (cairo_xlib_surface_t *surface)
 }
 
 static void
-_cairo_xlib_surface_ensure_dst_picture (cairo_xlib_surface_t    *surface)
+_cairo_xlib_surface_ensure_dst_picture (cairo_xlib_display_t    *display,
+                                        cairo_xlib_surface_t    *surface)
 {
     if (!surface->dst_picture) {
-	surface->dst_picture = XRenderCreatePicture (surface->dpy,
+	surface->dst_picture = XRenderCreatePicture (display->display,
 						     surface->drawable,
 						     surface->xrender_format,
 						     0, NULL);
     }
 
     if (surface->clip_dirty & CAIRO_XLIB_SURFACE_CLIP_DIRTY_PICTURE)
-	_cairo_xlib_surface_set_picture_clip_rects (surface);
-}
-
-static cairo_status_t
-_cairo_xlib_surface_get_gc (cairo_xlib_surface_t *surface, GC *gc)
-{
-    *gc = _cairo_xlib_screen_get_gc (surface->screen,
-				     surface->depth,
-				     surface->drawable);
-    if (unlikely (*gc == NULL))
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static void
-_cairo_xlib_surface_put_gc (cairo_xlib_surface_t *surface, GC gc)
-{
-    _cairo_xlib_screen_put_gc (surface->screen,
-			       surface->depth,
-			       gc);
+	_cairo_xlib_surface_set_picture_clip_rects (display, surface);
 }
 
 static cairo_status_t
@@ -1010,6 +1030,7 @@ _draw_image_surface (cairo_xlib_surface_t   *surface,
 		     int                    dst_x,
 		     int                    dst_y)
 {
+    cairo_xlib_display_t *display;
     XImage ximage;
     cairo_format_masks_t image_masks;
     int native_byte_order = _native_byte_order_lsb () ? LSBFirst : MSBFirst;
@@ -1031,6 +1052,10 @@ _draw_image_surface (cairo_xlib_surface_t   *surface,
     ximage.blue_mask = surface->b_mask;
     ximage.xoffset = 0;
 
+    status = _cairo_xlib_display_acquire (surface->base.device, &display);
+    if (unlikely (status))
+        return status;
+
     if (!_pixman_format_to_masks (image->pixman_format, &image_masks))
     {
         pixman_format_code_t intermediate_format;
@@ -1049,8 +1074,10 @@ _draw_image_surface (cairo_xlib_surface_t   *surface,
                                                  image->height,
                                                  NULL,
                                                  0);
-        if (pixman_image == NULL)
-	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+        if (pixman_image == NULL) {
+	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+            goto BAIL;
+        }
 
         pixman_image_composite32 (PIXMAN_OP_SRC,
                                   image->pixman_image,
@@ -1109,8 +1136,10 @@ _draw_image_surface (cairo_xlib_surface_t   *surface,
 					     ximage.bits_per_pixel);
 	ximage.bytes_per_line = stride;
 	ximage.data = _cairo_malloc_ab (stride, ximage.height);
-	if (unlikely (ximage.data == NULL))
-	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	if (unlikely (ximage.data == NULL)) {
+	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+            goto BAIL;
+        }
 
 	own_data = TRUE;
 
@@ -1130,7 +1159,8 @@ _draw_image_surface (cairo_xlib_surface_t   *surface,
 	    _characterize_field (surface->g_mask, &o_g_width, &o_g_shift);
 	    _characterize_field (surface->b_mask, &o_b_width, &o_b_shift);
 	} else {
-	    status = _cairo_xlib_screen_get_visual_info (surface->screen,
+	    status = _cairo_xlib_screen_get_visual_info (display,
+                                                         surface->screen,
 							 surface->visual,
 							 &visual_info);
 	    if (unlikely (status))
@@ -1201,17 +1231,20 @@ _draw_image_surface (cairo_xlib_surface_t   *surface,
 	}
     }
 
-    status = _cairo_xlib_surface_get_gc (surface, &gc);
+    status = _cairo_xlib_surface_get_gc (display, surface, &gc);
     if (unlikely (status))
 	goto BAIL;
 
-    XPutImage (surface->dpy, surface->drawable, gc,
+    XPutImage (display->display, surface->drawable, gc,
 	       &ximage, src_x, src_y, dst_x, dst_y,
 	       width, height);
 
-    _cairo_xlib_surface_put_gc (surface, gc);
+    _cairo_xlib_surface_put_gc (display, surface, gc);
 
   BAIL:
+
+    cairo_device_release (&display->base);
+
     if (own_data)
 	free (ximage.data);
     if (pixman_image)
@@ -1229,8 +1262,6 @@ _cairo_xlib_surface_acquire_source_image (void                    *abstract_surf
     cairo_image_surface_t *image;
     cairo_status_t status;
 
-    _cairo_xlib_display_notify (surface->display);
-
     status = _get_image_surface (surface, NULL, &image, NULL);
     if (unlikely (status))
 	return status;
@@ -1248,8 +1279,6 @@ _cairo_xlib_surface_snapshot (void *abstract_surface)
     cairo_image_surface_t *image;
     cairo_status_t status;
 
-    _cairo_xlib_display_notify (surface->display);
-
     status = _get_image_surface (surface, NULL, &image, NULL);
     if (unlikely (status))
 	return _cairo_surface_create_in_error (status);
@@ -1276,8 +1305,6 @@ _cairo_xlib_surface_acquire_dest_image (void                    *abstract_surfac
     cairo_image_surface_t *image;
     cairo_status_t status;
 
-    _cairo_xlib_display_notify (surface->display);
-
     status = _get_image_surface (surface, interest_rect, &image, image_rect_out);
     if (unlikely (status))
 	return status;
@@ -1333,8 +1360,6 @@ _cairo_xlib_surface_clone_similar (void			*abstract_surface,
     cairo_xlib_surface_t *clone;
     cairo_status_t status;
 
-    _cairo_xlib_display_notify (surface->display);
-
     if (src->backend == surface->base.backend ) {
 	cairo_xlib_surface_t *xlib_src = (cairo_xlib_surface_t *)src;
 
@@ -1396,6 +1421,7 @@ _cairo_xlib_surface_create_solid_pattern_surface (void                  *abstrac
     cairo_image_surface_t *image;
     cairo_xlib_surface_t *surface = NULL;
     cairo_status_t status = CAIRO_STATUS_SUCCESS;
+    cairo_xlib_display_t *display;
 
     int width = ARRAY_LENGTH (dither_pattern[0]);
     int height = ARRAY_LENGTH (dither_pattern);
@@ -1412,10 +1438,15 @@ _cairo_xlib_surface_create_solid_pattern_surface (void                  *abstrac
     if (unlikely (status))
 	goto BAIL;
 
-    pixmap = XCreatePixmap (other->dpy,
+    status = _cairo_xlib_display_acquire (other->base.device, &display);
+    if (unlikely (status))
+        goto BAIL;
+
+    pixmap = XCreatePixmap (display->display,
 			    other->drawable,
 			    width, height,
 			    other->depth);
+    cairo_device_release (&display->base);
 
     surface = (cairo_xlib_surface_t *)
 	      _cairo_xlib_surface_create_internal (other->screen,
@@ -1445,12 +1476,16 @@ _cairo_xlib_surface_create_solid_pattern_surface (void                  *abstrac
   BAIL:
     cairo_surface_destroy (&image->base);
 
-    if (unlikely (status)) {
-	if (pixmap != None)
-	    XFreePixmap (other->dpy, pixmap);
-	cairo_surface_destroy (&surface->base);
+    if (status) {
+        if (pixmap != None) {
+            if (!_cairo_xlib_display_acquire (other->base.device, &display)) {
+              XFreePixmap (display->display, pixmap);
+              cairo_device_release (&display->base);
+            }
+        }
+        cairo_surface_destroy (&surface->base);
 
-	return _cairo_surface_create_in_error (status);
+        return _cairo_surface_create_in_error (status);
     }
 
     surface->owns_pixmap = TRUE;
@@ -1466,7 +1501,8 @@ _cairo_xlib_surface_can_repaint_solid_pattern_surface (void *abstract_surface,
 }
 
 static cairo_status_t
-_cairo_xlib_surface_set_matrix (cairo_xlib_surface_t *surface,
+_cairo_xlib_surface_set_matrix (cairo_xlib_display_t *display,
+                                cairo_xlib_surface_t *surface,
 				cairo_matrix_t	     *matrix,
 				double                xc,
 				double                yc)
@@ -1486,14 +1522,15 @@ _cairo_xlib_surface_set_matrix (cairo_xlib_surface_t *surface,
     if (! CAIRO_SURFACE_RENDER_HAS_PICTURE_TRANSFORM (surface))
 	return UNSUPPORTED ("XRender does not support picture transforms");
 
-    XRenderSetPictureTransform (surface->dpy, surface->src_picture, &xtransform);
+    XRenderSetPictureTransform (display->display, surface->src_picture, &xtransform);
     surface->xtransform = xtransform;
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
-_cairo_xlib_surface_set_filter (cairo_xlib_surface_t *surface,
+_cairo_xlib_surface_set_filter (cairo_xlib_display_t *display,
+                                cairo_xlib_surface_t *surface,
 				cairo_filter_t	     filter)
 {
     const char *render_filter;
@@ -1535,7 +1572,7 @@ _cairo_xlib_surface_set_filter (cairo_xlib_surface_t *surface,
 	break;
     }
 
-    XRenderSetPictureFilter (surface->dpy, surface->src_picture,
+    XRenderSetPictureFilter (display->display, surface->src_picture,
 			     (char *) render_filter, NULL, 0);
     surface->filter = filter;
 
@@ -1601,7 +1638,8 @@ _cairo_xlib_surface_set_component_alpha (cairo_xlib_surface_t *surface,
 }
 
 static cairo_int_status_t
-_cairo_xlib_surface_set_attributes (cairo_xlib_surface_t	    *surface,
+_cairo_xlib_surface_set_attributes (cairo_xlib_display_t            *display,
+                                    cairo_xlib_surface_t	    *surface,
 				    cairo_surface_attributes_t	    *attributes,
 				    double			     xc,
 				    double			     yc)
@@ -1610,10 +1648,10 @@ _cairo_xlib_surface_set_attributes (cairo_xlib_surface_t	    *surface,
     XRenderPictureAttributes pa;
     unsigned long mask = 0;
 
-    _cairo_xlib_surface_ensure_src_picture (surface);
+    _cairo_xlib_surface_ensure_src_picture (display, surface);
 
-    status = _cairo_xlib_surface_set_matrix (surface, &attributes->matrix,
-					     xc, yc);
+    status = _cairo_xlib_surface_set_matrix (display, surface,
+                                             &attributes->matrix, xc, yc);
     if (unlikely (status))
 	return status;
 
@@ -1628,12 +1666,12 @@ _cairo_xlib_surface_set_attributes (cairo_xlib_surface_t	    *surface,
     if (unlikely (status))
 	return status;
 
-    status = _cairo_xlib_surface_set_filter (surface, attributes->filter);
+    status = _cairo_xlib_surface_set_filter (display, surface, attributes->filter);
     if (unlikely (status))
 	return status;
 
     if (mask)
-	XRenderChangePicture (surface->dpy, surface->src_picture, mask, &pa);
+	XRenderChangePicture (display->display, surface->src_picture, mask, &pa);
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -1905,7 +1943,8 @@ _render_operator (cairo_operator_t op)
 }
 
 static cairo_int_status_t
-_cairo_xlib_surface_acquire_pattern_surface (cairo_xlib_surface_t *dst,
+_cairo_xlib_surface_acquire_pattern_surface (cairo_xlib_display_t *display,
+                                             cairo_xlib_surface_t *dst,
 					     const cairo_pattern_t *pattern,
 					     int x, int y,
 					     int width, int height,
@@ -1967,7 +2006,7 @@ _cairo_xlib_surface_acquire_pattern_surface (cairo_xlib_surface_t *dst,
 	     * XSync call here seems to avoid the issue so I'll keep it here
 	     * until it's solved.
 	     */
-	    XSync (dst->dpy, False);
+	    XSync (display->display, False);
 #endif
 
 	    if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR) {
@@ -2015,7 +2054,7 @@ _cairo_xlib_surface_acquire_pattern_surface (cairo_xlib_surface_t *dst,
 		    grad.p2.y = _cairo_fixed_to_16_16 (linear->p2.y);
 		}
 
-		picture = XRenderCreateLinearGradient (dst->dpy, &grad,
+		picture = XRenderCreateLinearGradient (display->display, &grad,
 						       stops, colors,
 						       gradient->n_stops);
 	    } else {
@@ -2030,7 +2069,7 @@ _cairo_xlib_surface_acquire_pattern_surface (cairo_xlib_surface_t *dst,
 		grad.outer.y = _cairo_fixed_to_16_16 (radial->c2.y);
 		grad.outer.radius = _cairo_fixed_to_16_16 (radial->r2);
 
-		picture = XRenderCreateRadialGradient (dst->dpy, &grad,
+		picture = XRenderCreateRadialGradient (display->display, &grad,
 						       stops, colors,
 						       gradient->n_stops);
 
@@ -2043,7 +2082,7 @@ _cairo_xlib_surface_acquire_pattern_surface (cairo_xlib_surface_t *dst,
 		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
 	    /* Wrap the remote Picture in an xlib surface. */
-	    format = _cairo_xlib_display_get_xrender_format (dst->display,
+	    format = _cairo_xlib_display_get_xrender_format (display,
 							     CAIRO_FORMAT_ARGB32);
 
 	    surface = (cairo_xlib_surface_t *)
@@ -2051,7 +2090,7 @@ _cairo_xlib_surface_acquire_pattern_surface (cairo_xlib_surface_t *dst,
 						     NULL, format,
 						     0, 0, 32);
 	    if (unlikely (surface->base.status)) {
-		XRenderFreePicture (dst->dpy, picture);
+		XRenderFreePicture (display->display, picture);
 		return surface->base.status;
 	    }
 
@@ -2084,9 +2123,10 @@ _cairo_xlib_surface_acquire_pattern_surface (cairo_xlib_surface_t *dst,
 }
 
 static cairo_int_status_t
-_cairo_xlib_surface_acquire_pattern_surfaces (cairo_xlib_surface_t	 *dst,
-					      const cairo_pattern_t	         *src,
-					      const cairo_pattern_t	         *mask,
+_cairo_xlib_surface_acquire_pattern_surfaces (cairo_xlib_display_t       *display,
+                                              cairo_xlib_surface_t	 *dst,
+					      const cairo_pattern_t	 *src,
+					      const cairo_pattern_t	 *mask,
 					      int			 src_x,
 					      int			 src_y,
 					      int			 mask_x,
@@ -2106,7 +2146,8 @@ _cairo_xlib_surface_acquire_pattern_surfaces (cairo_xlib_surface_t	 *dst,
     {
 	cairo_int_status_t status;
 
-	status = _cairo_xlib_surface_acquire_pattern_surface (dst, src,
+	status = _cairo_xlib_surface_acquire_pattern_surface (display,
+                                                              dst, src,
 							      src_x, src_y,
 							      width, height,
 							      src_out,
@@ -2115,7 +2156,8 @@ _cairo_xlib_surface_acquire_pattern_surfaces (cairo_xlib_surface_t	 *dst,
 	    return status;
 
 	if (mask) {
-	    status = _cairo_xlib_surface_acquire_pattern_surface (dst, mask,
+	    status = _cairo_xlib_surface_acquire_pattern_surface (display,
+                                                                  dst, mask,
 								  mask_x,
 								  mask_y,
 								  width,
@@ -2166,6 +2208,7 @@ _cairo_xlib_surface_composite (cairo_operator_t		op,
     cairo_xlib_surface_t	*dst = abstract_dst;
     cairo_xlib_surface_t	*src;
     cairo_xlib_surface_t	*mask;
+    cairo_xlib_display_t        *display;
     cairo_int_status_t		status;
     cairo_rectangle_int_t	src_extents;
     composite_operation_t       operation;
@@ -2182,7 +2225,7 @@ _cairo_xlib_surface_composite (cairo_operator_t		op,
     if (operation == DO_UNSUPPORTED)
 	return UNSUPPORTED ("unsupported operation");
 
-    X_DEBUG ((dst->dpy, "composite (dst=%x)", (unsigned int) dst->drawable));
+    X_DEBUG ((display->display, "composite (dst=%x)", (unsigned int) dst->drawable));
 
     src_extents.x = src_x;
     src_extents.y = src_y;
@@ -2194,10 +2237,12 @@ _cairo_xlib_surface_composite (cairo_operator_t		op,
 					 ! _cairo_pattern_is_opaque (src_pattern,
 								     &src_extents));
 
-    _cairo_xlib_display_notify (dst->display);
+    status = _cairo_xlib_display_acquire (dst-> base.device, &display);
+    if (unlikely (status))
+        return status;
 
     status =
-	_cairo_xlib_surface_acquire_pattern_surfaces (dst,
+	_cairo_xlib_surface_acquire_pattern_surfaces (display, dst,
 						      src_pattern, mask_pattern,
 						      src_x, src_y,
 						      mask_x, mask_y,
@@ -2205,7 +2250,7 @@ _cairo_xlib_surface_composite (cairo_operator_t		op,
 						      &src, &mask,
 						      &src_attr, &mask_attr);
     if (unlikely (status))
-	return status;
+        goto BAIL0;
 
     /* check for fallback surfaces that we cannot handle ... */
     assert (_cairo_surface_is_xlib (&src->base));
@@ -2226,7 +2271,8 @@ _cairo_xlib_surface_composite (cairo_operator_t		op,
     switch (operation)
     {
     case DO_RENDER:
-	status = _cairo_xlib_surface_set_attributes (src, &src_attr,
+	status = _cairo_xlib_surface_set_attributes (display,
+                                                     src, &src_attr,
 						     dst_x + width / 2.,
 						     dst_y + height / 2.);
 	if (unlikely (status))
@@ -2236,15 +2282,16 @@ _cairo_xlib_surface_composite (cairo_operator_t		op,
 	if (unlikely (status))
 	    goto BAIL;
 
-	_cairo_xlib_surface_ensure_dst_picture (dst);
+	_cairo_xlib_surface_ensure_dst_picture (display, dst);
 	if (mask) {
-	    status = _cairo_xlib_surface_set_attributes (mask, &mask_attr,
+	    status = _cairo_xlib_surface_set_attributes (display,
+                                                         mask, &mask_attr,
 							 dst_x + width / 2.,
 							 dst_y + height/ 2.);
 	    if (unlikely (status))
 		goto BAIL;
 
-	    XRenderComposite (dst->dpy,
+	    XRenderComposite (display->display,
 			      _render_operator (op),
 			      src->src_picture,
 			      mask->src_picture,
@@ -2256,7 +2303,7 @@ _cairo_xlib_surface_composite (cairo_operator_t		op,
 			      dst_x, dst_y,
 			      width, height);
 	} else {
-	    XRenderComposite (dst->dpy,
+	    XRenderComposite (display->display,
 			      _render_operator (op),
 			      src->src_picture,
 			      0,
@@ -2271,7 +2318,7 @@ _cairo_xlib_surface_composite (cairo_operator_t		op,
 	break;
 
     case DO_XCOPYAREA:
-	status = _cairo_xlib_surface_get_gc (dst, &gc);
+	status = _cairo_xlib_surface_get_gc (display, dst, &gc);
 	if (unlikely (status))
 	    goto BAIL;
 
@@ -2281,7 +2328,7 @@ _cairo_xlib_surface_composite (cairo_operator_t		op,
 	assert (is_integer_translation);
 
 	if (clip_region == NULL) {
-	    XCopyArea (dst->dpy, src->drawable, dst->drawable, gc,
+	    XCopyArea (display->display, src->drawable, dst->drawable, gc,
 		       src_x + src_attr.x_offset + itx,
 		       src_y + src_attr.y_offset + ity,
 		       width, height,
@@ -2297,14 +2344,14 @@ _cairo_xlib_surface_composite (cairo_operator_t		op,
 		cairo_rectangle_int_t rect;
 
 		cairo_region_get_rectangle (clip_region, n, &rect);
-		XCopyArea (dst->dpy, src->drawable, dst->drawable, gc,
+		XCopyArea (display->display, src->drawable, dst->drawable, gc,
 			   rect.x + src_x, rect.y + src_y,
 			   rect.width, rect.height,
 			   rect.x, rect.y);
 	    }
 	}
 
-	_cairo_xlib_surface_put_gc (dst, gc);
+	_cairo_xlib_surface_put_gc (display, dst, gc);
 	break;
 
     case DO_XTILE:
@@ -2316,7 +2363,7 @@ _cairo_xlib_surface_composite (cairo_operator_t		op,
 	 * _recategorize_composite_operation.
 	 */
 
-	status = _cairo_xlib_surface_get_gc (dst, &gc);
+	status = _cairo_xlib_surface_get_gc (display, dst, &gc);
 	if (unlikely (status))
 	    goto BAIL;
 
@@ -2325,12 +2372,12 @@ _cairo_xlib_surface_composite (cairo_operator_t		op,
 	/* This is a pre-condition for DO_XTILE. */
 	assert (is_integer_translation);
 
-	XSetTSOrigin (dst->dpy, gc,
+	XSetTSOrigin (display->display, gc,
 		      - (itx + src_attr.x_offset), - (ity + src_attr.y_offset));
-	XSetTile (dst->dpy, gc, src->drawable);
+	XSetTile (display->display, gc, src->drawable);
 
 	if (clip_region == NULL) {
-	    XFillRectangle (dst->dpy, dst->drawable, gc,
+	    XFillRectangle (display->display, dst->drawable, gc,
 			    dst_x, dst_y, width, height);
 	} else {
 	    int n, num_rects;
@@ -2340,12 +2387,12 @@ _cairo_xlib_surface_composite (cairo_operator_t		op,
 		cairo_rectangle_int_t rect;
 
 		cairo_region_get_rectangle (clip_region, n, &rect);
-		XFillRectangle (dst->dpy, dst->drawable, gc,
+		XFillRectangle (display->display, dst->drawable, gc,
 				rect.x, rect.y, rect.width, rect.height);
 	    }
 	}
 
-	_cairo_xlib_surface_put_gc (dst, gc);
+	_cairo_xlib_surface_put_gc (display, dst, gc);
 	break;
 
     case DO_UNSUPPORTED:
@@ -2370,6 +2417,9 @@ _cairo_xlib_surface_composite (cairo_operator_t		op,
 
     _cairo_pattern_release_surface (src_pattern, &src->base, &src_attr);
 
+ BAIL0:
+    cairo_device_release (&display->base);
+
     return status;
 }
 
@@ -2384,16 +2434,21 @@ _cairo_xlib_surface_solid_fill_rectangles (cairo_xlib_surface_t    *surface,
     cairo_solid_pattern_t solid;
     cairo_surface_t *solid_surface = NULL;
     cairo_surface_attributes_t attrs;
+    cairo_xlib_display_t *display;
     GC gc;
     int i;
 
     _cairo_pattern_init_solid (&solid, color, CAIRO_CONTENT_COLOR);
 
-    status = _cairo_xlib_surface_get_gc (surface, &gc);
+    status = _cairo_xlib_display_acquire (surface->base.device, &display);
+    if (unlikely (status))
+        return status;
+
+    status = _cairo_xlib_surface_get_gc (display, surface, &gc);
     if (unlikely (status))
         return status;
 
-    X_DEBUG ((surface->dpy, "solid_fill_rectangles (dst=%x)", (unsigned int) surface->drawable));
+    X_DEBUG ((display->display, "solid_fill_rectangles (dst=%x)", (unsigned int) surface->drawable));
 
     status = _cairo_pattern_acquire_surface (&solid.base, &surface->base,
 					     0, 0,
@@ -2403,27 +2458,30 @@ _cairo_xlib_surface_solid_fill_rectangles (cairo_xlib_surface_t    *surface,
 					     &solid_surface,
 					     &attrs);
     if (unlikely (status)) {
-	_cairo_xlib_surface_put_gc (surface, gc);
+	_cairo_xlib_surface_put_gc (display, surface, gc);
+        cairo_device_release (&display->base);
 	return status;
     }
 
     assert (_cairo_surface_is_xlib (solid_surface));
 
-    XSetTSOrigin (surface->dpy, gc,
+    XSetTSOrigin (display->display, gc,
 		  - (surface->base.device_transform.x0 + attrs.x_offset),
 		  - (surface->base.device_transform.y0 + attrs.y_offset));
-    XSetTile (surface->dpy, gc,
+    XSetTile (display->display, gc,
 	      ((cairo_xlib_surface_t *) solid_surface)->drawable);
 
     for (i = 0; i < num_rects; i++) {
-	XFillRectangle (surface->dpy, surface->drawable, gc,
+	XFillRectangle (display->display, surface->drawable, gc,
 			rects[i].x, rects[i].y,
 			rects[i].width, rects[i].height);
     }
 
-    _cairo_xlib_surface_put_gc (surface, gc);
+    _cairo_xlib_surface_put_gc (display, surface, gc);
 
     _cairo_pattern_release_surface (&solid.base, solid_surface, &attrs);
+    
+    cairo_device_release (&display->base);
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -2436,12 +2494,11 @@ _cairo_xlib_surface_fill_rectangles (void		     *abstract_surface,
 				     int		      num_rects)
 {
     cairo_xlib_surface_t *surface = abstract_surface;
+    cairo_xlib_display_t *display;
     XRenderColor render_color;
     cairo_status_t status;
     int i;
 
-    _cairo_xlib_display_notify (surface->display);
-
     if (!CAIRO_SURFACE_RENDER_SUPPORTS_OPERATOR (surface, op))
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
@@ -2457,7 +2514,11 @@ _cairo_xlib_surface_fill_rectangles (void		     *abstract_surface,
 	return UNSUPPORTED ("no support for FillRectangles with this op");
     }
 
-    X_DEBUG ((surface->dpy, "fill_rectangles (dst=%x)", (unsigned int) surface->drawable));
+    status = _cairo_xlib_display_acquire (surface->base.device, &display);
+    if (unlikely (status))
+        return status;
+
+    X_DEBUG ((display->display, "fill_rectangles (dst=%x)", (unsigned int) surface->drawable));
 
     render_color.red   = color->red_short;
     render_color.green = color->green_short;
@@ -2467,12 +2528,12 @@ _cairo_xlib_surface_fill_rectangles (void		     *abstract_surface,
     status = _cairo_xlib_surface_set_clip_region (surface, NULL);
     assert (status == CAIRO_STATUS_SUCCESS);
 
-    _cairo_xlib_surface_ensure_dst_picture (surface);
+    _cairo_xlib_surface_ensure_dst_picture (display, surface);
     if (num_rects == 1) {
 	/* Take advantage of the protocol compaction that libXrender performs
 	 * to amalgamate sequences of XRenderFillRectangle().
 	 */
-	XRenderFillRectangle (surface->dpy,
+	XRenderFillRectangle (display->display,
 			      _render_operator (op),
 			      surface->dst_picture,
 			      &render_color,
@@ -2486,8 +2547,10 @@ _cairo_xlib_surface_fill_rectangles (void		     *abstract_surface,
 
 	if (num_rects > ARRAY_LENGTH (static_xrects)) {
 	    xrects = _cairo_malloc_ab (num_rects, sizeof (XRectangle));
-	    if (unlikely (xrects == NULL))
-		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    if (unlikely (xrects == NULL)) {
+		status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+                goto BAIL;
+            }
 	}
 
 	for (i = 0; i < num_rects; i++) {
@@ -2497,7 +2560,7 @@ _cairo_xlib_surface_fill_rectangles (void		     *abstract_surface,
 	    xrects[i].height = rects[i].height;
 	}
 
-	XRenderFillRectangles (surface->dpy,
+	XRenderFillRectangles (display->display,
 			       _render_operator (op),
 			       surface->dst_picture,
 			       &render_color, xrects, num_rects);
@@ -2506,7 +2569,9 @@ _cairo_xlib_surface_fill_rectangles (void		     *abstract_surface,
 	    free (xrects);
     }
 
-    return CAIRO_STATUS_SUCCESS;
+BAIL:
+    cairo_device_release (&display->base);
+    return status;
 }
 
 #define CAIRO_FIXED_16_16_MIN -32768
@@ -2564,6 +2629,7 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t	op,
     cairo_surface_attributes_t	attributes;
     cairo_xlib_surface_t	*dst = abstract_dst;
     cairo_xlib_surface_t	*src;
+    cairo_xlib_display_t        *display;
     cairo_int_status_t		status;
     composite_operation_t       operation;
     int				render_reference_x, render_reference_y;
@@ -2573,8 +2639,6 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t	op,
     XTrapezoid *xtraps = xtraps_stack;
     int i;
 
-    _cairo_xlib_display_notify (dst->display);
-
     if (! CAIRO_SURFACE_RENDER_HAS_TRAPEZOIDS (dst))
 	return UNSUPPORTED ("XRender does not support CompositeTrapezoids");
 
@@ -2582,15 +2646,20 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t	op,
     if (operation == DO_UNSUPPORTED)
 	return UNSUPPORTED ("unsupported operation");
 
-    X_DEBUG ((dst->dpy, "composite_trapezoids (dst=%x)", (unsigned int) dst->drawable));
+    status = _cairo_xlib_display_acquire (dst->base.device, &display);
+    if (unlikely (status))
+        return status;
+
+    X_DEBUG ((display->display, "composite_trapezoids (dst=%x)", (unsigned int) dst->drawable));
 
-    status = _cairo_xlib_surface_acquire_pattern_surface (dst,
+    status = _cairo_xlib_surface_acquire_pattern_surface (display,
+                                                          dst,
 							  pattern,
 							  src_x, src_y,
 							  width, height,
 							  &src, &attributes);
     if (unlikely (status))
-	return status;
+	goto BAIL0;
 
     operation = _recategorize_composite_operation (dst, op, src,
 						   &attributes, TRUE);
@@ -2602,7 +2671,7 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t	op,
     switch (antialias) {
     case CAIRO_ANTIALIAS_NONE:
 	pict_format =
-	    _cairo_xlib_display_get_xrender_format (dst->display,
+	    _cairo_xlib_display_get_xrender_format (display,
 						    CAIRO_FORMAT_A1);
 	break;
     case CAIRO_ANTIALIAS_GRAY:
@@ -2610,7 +2679,7 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t	op,
     case CAIRO_ANTIALIAS_DEFAULT:
     default:
 	pict_format =
-	    _cairo_xlib_display_get_xrender_format (dst->display,
+	    _cairo_xlib_display_get_xrender_format (display,
 						    CAIRO_FORMAT_A8);
 	break;
     }
@@ -2619,9 +2688,10 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t	op,
     if (unlikely (status))
 	goto BAIL;
 
-    _cairo_xlib_surface_ensure_dst_picture (dst);
+    _cairo_xlib_surface_ensure_dst_picture (display, dst);
 
-    status = _cairo_xlib_surface_set_attributes (src, &attributes,
+    status = _cairo_xlib_surface_set_attributes (display,
+                                                 src, &attributes,
 						 dst_x + width / 2.,
 						 dst_y + height / 2.);
     if (unlikely (status))
@@ -2684,7 +2754,7 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t	op,
     render_src_x = src_x + render_reference_x - dst_x;
     render_src_y = src_y + render_reference_y - dst_y;
 
-    XRenderCompositeTrapezoids (dst->dpy,
+    XRenderCompositeTrapezoids (display->display,
 				_render_operator (op),
 				src->src_picture, dst->dst_picture,
 				pict_format,
@@ -2723,6 +2793,8 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t	op,
 
  BAIL:
     _cairo_pattern_release_surface (pattern, &src->base, &attributes);
+ BAIL0:
+    cairo_device_release (&display->base);
 
     return status;
 }
@@ -2766,22 +2838,27 @@ _cairo_xlib_surface_is_similar (void		*surface_a,
     cairo_xlib_surface_t *a = surface_a;
     cairo_xlib_surface_t *b = surface_b;
     XRenderPictFormat *xrender_format = b->xrender_format;
+    cairo_xlib_display_t *display;
 
     if (! _cairo_xlib_surface_same_screen (a, b))
 	return FALSE;
 
+    if (_cairo_xlib_display_acquire (b->base.device, &display))
+        return FALSE;
+
     /* now inspect the content to check that a is similar to b */
     if (xrender_format == NULL && b->visual != NULL)
-        xrender_format = XRenderFindVisualFormat (b->dpy, b->visual);
+        xrender_format = XRenderFindVisualFormat (display->display, b->visual);
 
     if (xrender_format == NULL ||
 	_xrender_format_to_content (xrender_format) != content)
     {
 	xrender_format = _cairo_xlib_display_get_xrender_format (
-					  b->display,
+					  display,
 					  _cairo_format_from_content (content));
     }
 
+    cairo_device_release (&display->base);
 
     return a->xrender_format == xrender_format;
 }
@@ -2848,8 +2925,7 @@ _cairo_xlib_surface_detach_display (cairo_xlib_display_t *display, void *data)
 							close_display_hook);
     Display *dpy;
 
-    dpy = surface->dpy;
-    surface->dpy = NULL;
+    dpy = display->display;
 
     X_DEBUG ((dpy, "detach (drawable=%x)", (unsigned int) surface->drawable));
 
@@ -2880,7 +2956,9 @@ _cairo_xlib_surface_create_internal (cairo_xlib_screen_t	*screen,
 				     int			 depth)
 {
     cairo_xlib_surface_t *surface;
-
+    cairo_xlib_display_t *display;
+    cairo_status_t status;
+      
     CAIRO_MUTEX_INITIALIZE ();
 
     if (depth == 0) {
@@ -2923,23 +3001,22 @@ found:
     if (unlikely (surface == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
-    surface->dpy = _cairo_xlib_display_get_dpy (screen->display);
-
-    /* initialize and hook into the CloseDisplay callback */
-    surface->close_display_hook.func = _cairo_xlib_surface_detach_display;
-    _cairo_xlib_add_close_display_hook (screen->display,
-					&surface->close_display_hook);
+    status = _cairo_xlib_display_acquire (screen->device, &display);
+    if (unlikely (status)) {
+        free (surface);
+        return _cairo_surface_create_in_error (_cairo_error (status));
+    }
 
-    _cairo_xlib_display_get_xrender_version (screen->display,
+    _cairo_xlib_display_get_xrender_version (display,
 					     &surface->render_major,
 					     &surface->render_minor);
     if (CAIRO_SURFACE_RENDER_HAS_CREATE_PICTURE (surface)) {
 	if (!xrender_format) {
 	    if (visual) {
-		xrender_format = XRenderFindVisualFormat (surface->dpy, visual);
+		xrender_format = XRenderFindVisualFormat (display->display, visual);
 	    } else if (depth == 1) {
 		xrender_format =
-		    _cairo_xlib_display_get_xrender_format (screen->display,
+		    _cairo_xlib_display_get_xrender_format (display,
 							    CAIRO_FORMAT_A1);
 	    }
 	}
@@ -2949,13 +3026,19 @@ found:
 	surface->render_minor = -1;
     }
 
+    /* initialize and hook into the CloseDisplay callback */
+    surface->close_display_hook.func = _cairo_xlib_surface_detach_display;
+    _cairo_xlib_add_close_display_hook (display,
+					&surface->close_display_hook);
+    
+    cairo_device_release (&display->base);
+
     _cairo_surface_init (&surface->base,
 			 &cairo_xlib_surface_backend,
-			 NULL, /* device */
+			 screen->device,
 			 _xrender_format_to_content (xrender_format));
 
     surface->screen = _cairo_xlib_screen_reference (screen);
-    surface->display = screen->display;
 
     surface->drawable = drawable;
     surface->owns_pixmap = FALSE;
@@ -2963,17 +3046,17 @@ found:
     surface->width = width;
     surface->height = height;
 
-    surface->buggy_repeat = ! _cairo_xlib_display_has_repeat (surface->display);
+    surface->buggy_repeat = ! _cairo_xlib_display_has_repeat (screen->device);
     if (! CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLES (surface)) {
 	/* so we can use the XTile fallback */
 	surface->buggy_repeat = TRUE;
     }
 
-    surface->buggy_pad_reflect = ! _cairo_xlib_display_has_reflect (surface->display);
+    surface->buggy_pad_reflect = ! _cairo_xlib_display_has_reflect (screen->device);
     if (! CAIRO_SURFACE_RENDER_HAS_EXTENDED_REPEAT (surface))
 	surface->buggy_pad_reflect = TRUE;
 
-    surface->buggy_gradients = ! _cairo_xlib_display_has_gradients (surface->display);
+    surface->buggy_gradients = ! _cairo_xlib_display_has_gradients (screen->device);
     if (! CAIRO_SURFACE_RENDER_HAS_GRADIENTS (surface))
 	surface->buggy_gradients = TRUE;
 
@@ -3323,11 +3406,17 @@ cairo_xlib_surface_set_drawable (cairo_surface_t   *abstract_surface,
 	return;
 
     if (surface->drawable != drawable) {
-	X_DEBUG ((surface->dpy, "set_drawable (drawable=%x)", (unsigned int) drawable));
+        cairo_xlib_display_t *display;
+
+        status = _cairo_xlib_display_acquire (surface->base.device, &display);
+        if (unlikely (status))
+            return;
+
+	X_DEBUG ((display->display, "set_drawable (drawable=%x)", (unsigned int) drawable));
 
 	if (surface->dst_picture != None) {
 	    status = _cairo_xlib_display_queue_resource (
-		                                  surface->display,
+		                                  display,
 						  XRenderFreePicture,
 						  surface->dst_picture);
 	    if (unlikely (status)) {
@@ -3340,7 +3429,7 @@ cairo_xlib_surface_set_drawable (cairo_surface_t   *abstract_surface,
 
 	if (surface->src_picture != None) {
 	    status = _cairo_xlib_display_queue_resource (
-		                                  surface->display,
+		                                  display,
 						  XRenderFreePicture,
 						  surface->src_picture);
 	    if (unlikely (status)) {
@@ -3351,6 +3440,8 @@ cairo_xlib_surface_set_drawable (cairo_surface_t   *abstract_surface,
 	    surface->src_picture = None;
 	}
 
+        cairo_device_release (&display->base);
+
 	surface->drawable = drawable;
     }
     surface->width = width;
@@ -3370,14 +3461,12 @@ cairo_xlib_surface_set_drawable (cairo_surface_t   *abstract_surface,
 Display *
 cairo_xlib_surface_get_display (cairo_surface_t *abstract_surface)
 {
-    cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
-
     if (! _cairo_surface_is_xlib (abstract_surface)) {
 	_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 	return NULL;
     }
 
-    return surface->dpy;
+    return ((cairo_xlib_display_t *) abstract_surface->device)->display;
 }
 
 /**
@@ -3541,7 +3630,7 @@ typedef struct _cairo_xlib_font_glyphset_info {
 typedef struct _cairo_xlib_surface_font_private {
     cairo_scaled_font_t		    *scaled_font;
     cairo_xlib_hook_t                close_display_hook;
-    cairo_xlib_display_t	    *display;
+    cairo_device_t                  *device;
     cairo_xlib_font_glyphset_info_t  glyphset_info[NUM_GLYPHSETS];
 } cairo_xlib_surface_font_private_t;
 
@@ -3566,32 +3655,29 @@ _cairo_xlib_surface_remove_scaled_font (cairo_xlib_display_t	*display,
     CAIRO_MUTEX_UNLOCK (scaled_font->mutex);
 
     if (font_private != NULL) {
-	Display *dpy;
 	int i;
 
-	dpy = _cairo_xlib_display_get_dpy (display);
 	for (i = 0; i < NUM_GLYPHSETS; i++) {
 	    cairo_xlib_font_glyphset_info_t *glyphset_info;
 
 	    glyphset_info = &font_private->glyphset_info[i];
 	    if (glyphset_info->glyphset)
-		XRenderFreeGlyphSet (dpy, glyphset_info->glyphset);
+		XRenderFreeGlyphSet (display->display, glyphset_info->glyphset);
 
 	    if (glyphset_info->pending_free_glyphs != NULL)
 		free (glyphset_info->pending_free_glyphs);
 	}
 
-	_cairo_xlib_display_destroy (font_private->display);
+	cairo_device_destroy (font_private->device);
 	free (font_private);
     }
 }
 
 static cairo_status_t
-_cairo_xlib_surface_font_init (Display		    *dpy,
+_cairo_xlib_surface_font_init (cairo_xlib_display_t *display,
 			       cairo_scaled_font_t  *scaled_font)
 {
     cairo_xlib_surface_font_private_t	*font_private;
-    cairo_status_t status;
     int i;
 
     font_private = malloc (sizeof (cairo_xlib_surface_font_private_t));
@@ -3599,16 +3685,12 @@ _cairo_xlib_surface_font_init (Display		    *dpy,
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     font_private->scaled_font = scaled_font;
-    status = _cairo_xlib_display_get (dpy, &font_private->display);
-    if (unlikely (status)) {
-	free (font_private);
-	return status;
-    }
+    font_private->device = cairo_device_reference (&display->base);
 
     /* 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,
+    _cairo_xlib_add_close_display_hook (display,
 					&font_private->close_display_hook);
 
 
@@ -3635,13 +3717,17 @@ static void
 _cairo_xlib_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font)
 {
     cairo_xlib_surface_font_private_t *font_private;
+    cairo_status_t status;
 
     font_private = scaled_font->surface_private;
     if (font_private != NULL) {
 	cairo_xlib_display_t *display;
 	int i;
 
-	display = font_private->display;
+        status = _cairo_xlib_display_acquire (font_private->device, &display);
+        if (status)
+            goto BAIL;
+
 	_cairo_xlib_remove_close_display_hook (display,
 					       &font_private->close_display_hook);
 
@@ -3654,8 +3740,6 @@ _cairo_xlib_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font)
 		free (glyphset_info->pending_free_glyphs);
 
 	    if (glyphset_info->glyphset) {
-		cairo_status_t status;
-
 		status = _cairo_xlib_display_queue_resource (display,
 							     XRenderFreeGlyphSet,
 							     glyphset_info->glyphset);
@@ -3663,7 +3747,9 @@ _cairo_xlib_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font)
 	    }
 	}
 
-	_cairo_xlib_display_destroy (display);
+	cairo_device_release (&display->base);
+BAIL:
+	cairo_device_destroy (&display->base);
 	free (font_private);
     }
 }
@@ -3711,10 +3797,16 @@ _cairo_xlib_surface_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph,
 	if (to_free != NULL &&
 	    to_free->glyph_count == ARRAY_LENGTH (to_free->glyph_indices))
 	{
-	    status = _cairo_xlib_display_queue_work (font_private->display,
-		    (cairo_xlib_notify_func) _cairo_xlib_render_free_glyphs,
-		    to_free,
-		    free);
+            cairo_xlib_display_t *display;
+
+            status = _cairo_xlib_display_acquire (font_private->device, &display);
+            if (status == CAIRO_STATUS_SUCCESS) {
+                status = _cairo_xlib_display_queue_work (display,
+                        (cairo_xlib_notify_func) _cairo_xlib_render_free_glyphs,
+                        to_free,
+                        free);
+                cairo_device_release (&display->base);
+            }
 	    /* XXX cannot propagate failure */
 	    if (unlikely (status))
 		free (to_free);
@@ -3771,13 +3863,18 @@ _cairo_xlib_scaled_font_get_glyphset_info_for_format (cairo_scaled_font_t *scale
     font_private = scaled_font->surface_private;
     glyphset_info = &font_private->glyphset_info[glyphset_index];
     if (glyphset_info->glyphset == None) {
-	cairo_xlib_display_t *display = font_private->display;
+	cairo_xlib_display_t *display;
+        
+        if (_cairo_xlib_display_acquire (font_private->device, &display))
+            return NULL;
 
 	glyphset_info->xrender_format =
 	    _cairo_xlib_display_get_xrender_format (display,
 		                                    glyphset_info->format);
-	glyphset_info->glyphset = XRenderCreateGlyphSet (_cairo_xlib_display_get_dpy (display),
+	glyphset_info->glyphset = XRenderCreateGlyphSet (display->display,
 							 glyphset_info->xrender_format);
+
+        cairo_device_release (&display->base);
     }
 
     return glyphset_info;
@@ -3843,7 +3940,7 @@ _cairo_xlib_scaled_font_get_glyphset_info_for_pending_free_glyph (
 }
 
 static cairo_status_t
-_cairo_xlib_surface_add_glyph (Display *dpy,
+_cairo_xlib_surface_add_glyph (cairo_xlib_display_t *display,
 			       cairo_scaled_font_t   *scaled_font,
 			       cairo_scaled_glyph_t **pscaled_glyph)
 {
@@ -3882,7 +3979,7 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
     }
 
     if (scaled_font->surface_private == NULL) {
-	status = _cairo_xlib_surface_font_init (dpy, scaled_font);
+	status = _cairo_xlib_surface_font_init (display, scaled_font);
 	if (unlikely (status))
 	    return status;
     }
@@ -3893,7 +3990,8 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
     /* XRenderAddGlyph does not handle a glyph surface larger than the extended maximum XRequest size.  */
     {
 	int len = cairo_format_stride_for_width (glyphset_info->format, glyph_surface->width) * glyph_surface->height;
-	int max_request_size = (XExtendedMaxRequestSize (dpy) ? XExtendedMaxRequestSize (dpy) : XMaxRequestSize (dpy)) * 4 -
+	int max_request_size = (XExtendedMaxRequestSize (display->display) ? XExtendedMaxRequestSize (display->display)
+                                                                           : XMaxRequestSize (display->display)) * 4 -
 	                       sz_xRenderAddGlyphsReq -
 	                       sz_xGlyphInfo          -
 			       8;
@@ -3962,7 +4060,7 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
     switch (_cairo_xlib_get_glyphset_index_for_format (scaled_glyph->surface->format)) {
     case GLYPHSET_INDEX_A1:
 	/* local bitmaps are always stored with bit == byte */
-	if (_native_byte_order_lsb() != (BitmapBitOrder (dpy) == LSBFirst)) {
+	if (_native_byte_order_lsb() != (BitmapBitOrder (display->display) == LSBFirst)) {
 	    int		    c = glyph_surface->stride * glyph_surface->height;
 	    unsigned char   *d;
 	    unsigned char   *new, *n;
@@ -3987,7 +4085,7 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
     case GLYPHSET_INDEX_A8:
 	break;
     case GLYPHSET_INDEX_ARGB32:
-	if (_native_byte_order_lsb() != (ImageByteOrder (dpy) == LSBFirst)) {
+	if (_native_byte_order_lsb() != (ImageByteOrder (display->display) == LSBFirst)) {
 	    unsigned int c = glyph_surface->stride * glyph_surface->height / 4;
 	    const uint32_t *d;
 	    uint32_t *new, *n;
@@ -4012,7 +4110,7 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
     }
     /* XXX assume X server wants pixman padding. Xft assumes this as well */
 
-    XRenderAddGlyphs (dpy, glyphset_info->glyphset,
+    XRenderAddGlyphs (display->display, glyphset_info->glyphset,
 		      &glyph_index, &glyph_info, 1,
 		      (char *) data,
 		      glyph_surface->stride * glyph_surface->height);
@@ -4079,7 +4177,8 @@ COMPILE_TIME_ASSERT (sizeof (cairo_xlib_glyph_t) == sizeof (cairo_glyph_t));
     (((count) & 127) == 0 || (glyph)->i.x || (glyph)->i.y)
 
 static cairo_status_t
-_emit_glyphs_chunk (cairo_xlib_surface_t *dst,
+_emit_glyphs_chunk (cairo_xlib_display_t *display,
+                    cairo_xlib_surface_t *dst,
 		    cairo_xlib_glyph_t *glyphs,
 		    int num_glyphs,
 		    cairo_scaled_font_t *scaled_font,
@@ -4178,7 +4277,7 @@ _emit_glyphs_chunk (cairo_xlib_surface_t *dst,
      * expected number of xGlyphElts.  */
     assert (nelt == num_elts);
 
-    composite_text_func (dst->dpy,
+    composite_text_func (display->display,
 			 _render_operator (op),
 			 src->src_picture,
 			 dst->dst_picture,
@@ -4200,7 +4299,8 @@ _emit_glyphs_chunk (cairo_xlib_surface_t *dst,
 #define _cairo_sz_xGlyphElt (sz_xGlyphElt + 4)
 
 static cairo_status_t
-_cairo_xlib_surface_emit_glyphs (cairo_xlib_surface_t *dst,
+_cairo_xlib_surface_emit_glyphs (cairo_xlib_display_t *display,
+                                 cairo_xlib_surface_t *dst,
 				 cairo_xlib_glyph_t *glyphs,
 				 int num_glyphs,
 				 cairo_scaled_font_t *scaled_font,
@@ -4220,14 +4320,13 @@ _cairo_xlib_surface_emit_glyphs (cairo_xlib_surface_t *dst,
     int num_elts = 0;
     int num_out_glyphs = 0;
 
-    int max_request_size = XMaxRequestSize (dst->dpy) * 4
+    int max_request_size = XMaxRequestSize (display->display) * 4
 			 - MAX (sz_xRenderCompositeGlyphs8Req,
 				MAX(sz_xRenderCompositeGlyphs16Req,
 				    sz_xRenderCompositeGlyphs32Req));
     int request_size = 0;
 
-    _cairo_xlib_surface_ensure_dst_picture (dst);
-    _cairo_xlib_display_notify (dst->display);
+    _cairo_xlib_surface_ensure_dst_picture (display, dst);
 
     for (i = 0; i < num_glyphs; i++) {
 	int this_x, this_y;
@@ -4267,7 +4366,7 @@ _cairo_xlib_surface_emit_glyphs (cairo_xlib_surface_t *dst,
 
 	/* Send unsent glyphs to the server */
 	if (_cairo_xlib_scaled_glyph_get_glyphset_info (scaled_glyph) == NULL) {
-	    status = _cairo_xlib_surface_add_glyph (dst->dpy,
+	    status = _cairo_xlib_surface_add_glyph (display,
 		                                    scaled_font,
 						    &scaled_glyph);
 	    if (unlikely (status)) {
@@ -4314,7 +4413,7 @@ _cairo_xlib_surface_emit_glyphs (cairo_xlib_surface_t *dst,
 	 */
 	if (request_size + width > max_request_size - _cairo_sz_xGlyphElt ||
 	    (this_glyphset_info != glyphset_info)) {
-	    status = _emit_glyphs_chunk (dst, glyphs, i,
+	    status = _emit_glyphs_chunk (display, dst, glyphs, i,
 					 scaled_font, op, src, attributes,
 					 num_elts, old_width, glyphset_info);
 	    if (unlikely (status))
@@ -4357,7 +4456,7 @@ _cairo_xlib_surface_emit_glyphs (cairo_xlib_surface_t *dst,
     }
 
     if (num_elts) {
-	status = _emit_glyphs_chunk (dst, glyphs, i,
+	status = _emit_glyphs_chunk (display, dst, glyphs, i,
 				     scaled_font, op, src, attributes,
 				     num_elts, width, glyphset_info);
     }
@@ -4378,7 +4477,7 @@ _cairo_xlib_surface_owns_font (cairo_xlib_surface_t *dst,
     font_private = scaled_font->surface_private;
     if ((scaled_font->surface_backend != NULL &&
 	 scaled_font->surface_backend != &cairo_xlib_surface_backend) ||
-	(font_private != NULL && font_private->display != dst->display))
+	(font_private != NULL && font_private->device != dst->base.device))
     {
 	return FALSE;
     }
@@ -4398,11 +4497,11 @@ _cairo_xlib_surface_show_glyphs (void                *abstract_dst,
 {
     cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
     cairo_xlib_surface_t *dst = (cairo_xlib_surface_t*) abstract_dst;
-
     composite_operation_t operation;
     cairo_surface_attributes_t attributes;
     cairo_xlib_surface_t *src = NULL;
     cairo_region_t *clip_region = NULL;
+    cairo_xlib_display_t *display;
 
     if (! CAIRO_SURFACE_RENDER_HAS_COMPOSITE_TEXT (dst))
 	return UNSUPPORTED ("XRender does not support CompositeText");
@@ -4442,7 +4541,11 @@ _cairo_xlib_surface_show_glyphs (void                *abstract_dst,
     if (! _cairo_xlib_surface_owns_font (dst, scaled_font))
 	return UNSUPPORTED ("unowned font");
 
-    X_DEBUG ((dst->dpy, "show_glyphs (dst=%x)", (unsigned int) dst->drawable));
+    status = _cairo_xlib_display_acquire (dst->base.device, &display);
+    if (unlikely (status))
+        return status;
+
+    X_DEBUG ((display->display, "show_glyphs (dst=%x)", (unsigned int) dst->drawable));
 
     if (clip_region != NULL &&
 	cairo_region_num_rectangles (clip_region) == 1)
@@ -4469,7 +4572,7 @@ _cairo_xlib_surface_show_glyphs (void                *abstract_dst,
 
     status = _cairo_xlib_surface_set_clip_region (dst, clip_region);
     if (unlikely (status))
-	return status;
+        goto BAIL0;
 
     /* After passing all those tests, we're now committed to rendering
      * these glyphs or to fail trying. We first upload any glyphs to
@@ -4514,7 +4617,8 @@ _cairo_xlib_surface_show_glyphs (void                *abstract_dst,
 	    }
 	}
 
-        status = _cairo_xlib_surface_acquire_pattern_surface (dst, src_pattern,
+        status = _cairo_xlib_surface_acquire_pattern_surface (display,
+                                                              dst, src_pattern,
 							      glyph_extents.x,
 							      glyph_extents.y,
 							      glyph_extents.width,
@@ -4531,13 +4635,14 @@ _cairo_xlib_surface_show_glyphs (void                *abstract_dst,
 	goto BAIL1;
     }
 
-    status = _cairo_xlib_surface_set_attributes (src, &attributes, 0, 0);
+    status = _cairo_xlib_surface_set_attributes (display, src, &attributes, 0, 0);
     if (unlikely (status))
         goto BAIL1;
 
     _cairo_scaled_font_freeze_cache (scaled_font);
     if (_cairo_xlib_surface_owns_font (dst, scaled_font)) {
-	status = _cairo_xlib_surface_emit_glyphs (dst,
+	status = _cairo_xlib_surface_emit_glyphs (display,
+                                                  dst,
 						  (cairo_xlib_glyph_t *) glyphs,
 						  num_glyphs,
 						  scaled_font,
@@ -4554,7 +4659,7 @@ _cairo_xlib_surface_show_glyphs (void                *abstract_dst,
     if (src)
         _cairo_pattern_release_surface (src_pattern, &src->base, &attributes);
   BAIL0:
-    _cairo_xlib_display_notify (dst->display);
+    cairo_device_release (&display->base);
 
     return status;
 }


More information about the cairo-commit mailing list