summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2010-04-18 23:20:02 +0200
committerBenjamin Otte <otte@redhat.com>2010-04-18 23:20:02 +0200
commitf74ad37e66bbdcc4d727ed6d931dde870d84c2f4 (patch)
tree0d98ce93eb5e38dcf55e230e40d877c7fe3fbd03
parent2bffa2467ed67517419e425fc34fb5b8294a9e96 (diff)
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.
-rw-r--r--src/cairo-xlib-display.c234
-rw-r--r--src/cairo-xlib-private.h66
-rw-r--r--src/cairo-xlib-screen.c161
-rw-r--r--src/cairo-xlib-surface-private.h2
-rw-r--r--src/cairo-xlib-surface.c557
5 files changed, 494 insertions, 526 deletions
diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c
index 69b7c66b..be65c227 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 afdf6a6b..550520da 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 18f974b3..2831acac 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 b30848d5..8309246f 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 51c0f836..f127a9c3 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;
}