[cairo-commit] src/cairo-surface-snapshot.c 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
Chris Wilson
ickle at kemper.freedesktop.org
Sun Aug 14 05:49:29 PDT 2011
src/cairo-surface-snapshot.c | 5 +
src/cairo-xlib-display.c | 107 ++++++++++++++++++++-------------------
src/cairo-xlib-private.h | 2
src/cairo-xlib-screen.c | 10 +++
src/cairo-xlib-surface-private.h | 1
src/cairo-xlib-surface.c | 4 +
6 files changed, 76 insertions(+), 53 deletions(-)
New commits:
commit 84a3b6e2d0b8103cdc17558b502ecfc4c99b98a3
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sun Aug 14 13:47:14 2011 +0100
xlib: Mark surfaces as finished when the Display is finished/destroyed/closed.
Fixes xlib-surface-source with the recording-surface
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/cairo-surface-snapshot.c b/src/cairo-surface-snapshot.c
index c499e0b..16153e2 100644
--- a/src/cairo-surface-snapshot.c
+++ b/src/cairo-surface-snapshot.c
@@ -145,7 +145,10 @@ _cairo_surface_snapshot_copy_on_write (cairo_surface_t *surface)
goto done;
}
- /* XXX copy to a similar surface, leave acquisition till later? */
+ /* XXX copy to a similar surface, leave acquisition till later?
+ * We should probably leave such decisions to the backend in case we
+ * rely upon devices/connections like Xlib.
+ */
status = _cairo_surface_acquire_source_image (snapshot->target, &image, &extra);
if (unlikely (status)) {
snapshot->target = _cairo_surface_create_in_error (status);
diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c
index fe93e1c..59e602d 100644
--- a/src/cairo-xlib-display.c
+++ b/src/cairo-xlib-display.c
@@ -93,40 +93,6 @@ _cairo_xlib_call_close_display_hooks (cairo_xlib_display_t *display)
display->closed = TRUE;
}
-static void
-_cairo_xlib_display_finish (void *abstract_display)
-{
- cairo_xlib_display_t *display = abstract_display;
-
- display->display = NULL;
-}
-
-static void
-_cairo_xlib_display_destroy (void *abstract_display)
-{
- cairo_xlib_display_t *display = abstract_display;
-
- /* destroy all outstanding notifies */
- while (display->workqueue != NULL) {
- cairo_xlib_job_t *job = display->workqueue;
- display->workqueue = job->next;
-
- if (job->type == WORK && job->func.work.destroy != NULL)
- job->func.work.destroy (job->func.work.data);
-
- _cairo_freelist_free (&display->wq_freelist, job);
- }
- _cairo_freelist_fini (&display->wq_freelist);
-
- while (! cairo_list_is_empty (&display->screens)) {
- _cairo_xlib_screen_destroy (cairo_list_first_entry (&display->screens,
- cairo_xlib_screen_t,
- link));
- }
-
- free (display);
-}
-
static int
_noop_error_handler (Display *display,
XErrorEvent *event)
@@ -187,11 +153,64 @@ _cairo_xlib_display_notify (cairo_xlib_display_t *display)
}
}
+static void
+_cairo_xlib_display_finish (void *abstract_display)
+{
+ cairo_xlib_display_t *display = abstract_display;
+ Display *dpy = display->display;
+
+ if (! cairo_device_acquire (&display->base)) {
+ cairo_xlib_error_func_t old_handler;
+
+ /* protect the notifies from triggering XErrors */
+ XSync (dpy, False);
+ old_handler = XSetErrorHandler (_noop_error_handler);
+
+ _cairo_xlib_display_notify (display);
+ _cairo_xlib_call_close_display_hooks (display);
+
+ /* catch any that arrived before marking the display as closed */
+ _cairo_xlib_display_notify (display);
+
+ XSync (dpy, False);
+ XSetErrorHandler (old_handler);
+
+ cairo_device_release (&display->base);
+ }
+
+ display->display = NULL;
+}
+
+static void
+_cairo_xlib_display_destroy (void *abstract_display)
+{
+ cairo_xlib_display_t *display = abstract_display;
+
+ /* destroy all outstanding notifies */
+ while (display->workqueue != NULL) {
+ cairo_xlib_job_t *job = display->workqueue;
+ display->workqueue = job->next;
+
+ if (job->type == WORK && job->func.work.destroy != NULL)
+ job->func.work.destroy (job->func.work.data);
+
+ _cairo_freelist_free (&display->wq_freelist, job);
+ }
+ _cairo_freelist_fini (&display->wq_freelist);
+
+ while (! cairo_list_is_empty (&display->screens)) {
+ _cairo_xlib_screen_destroy (cairo_list_first_entry (&display->screens,
+ cairo_xlib_screen_t,
+ link));
+ }
+
+ free (display);
+}
+
static int
_cairo_xlib_close_display (Display *dpy, XExtCodes *codes)
{
cairo_xlib_display_t *display, **prev, *next;
- cairo_xlib_error_func_t old_handler;
CAIRO_MUTEX_LOCK (_cairo_xlib_display_mutex);
for (display = _cairo_xlib_display_list; display; display = display->next)
@@ -201,22 +220,7 @@ _cairo_xlib_close_display (Display *dpy, XExtCodes *codes)
if (display == NULL)
return 0;
- if (! cairo_device_acquire (&display->base)) {
- /* protect the notifies from triggering XErrors */
- XSync (dpy, False);
- old_handler = XSetErrorHandler (_noop_error_handler);
-
- _cairo_xlib_display_notify (display);
- _cairo_xlib_call_close_display_hooks (display);
-
- /* catch any that arrived before marking the display as closed */
- _cairo_xlib_display_notify (display);
-
- XSync (dpy, False);
- XSetErrorHandler (old_handler);
-
- cairo_device_release (&display->base);
- }
+ cairo_device_finish (&display->base);
/*
* Unhook from the global list
@@ -235,7 +239,6 @@ _cairo_xlib_close_display (Display *dpy, XExtCodes *codes)
assert (display != NULL);
- cairo_device_finish (&display->base);
cairo_device_destroy (&display->base);
/* Return value in accordance with requirements of
diff --git a/src/cairo-xlib-private.h b/src/cairo-xlib-private.h
index d10e986..3a32eff 100644
--- a/src/cairo-xlib-private.h
+++ b/src/cairo-xlib-private.h
@@ -109,6 +109,8 @@ struct _cairo_xlib_screen {
cairo_device_t *device;
Screen *screen;
+ cairo_list_t surfaces;
+
cairo_bool_t has_font_options;
cairo_font_options_t font_options;
diff --git a/src/cairo-xlib-screen.c b/src/cairo-xlib-screen.c
index dc060c2..356131f 100644
--- a/src/cairo-xlib-screen.c
+++ b/src/cairo-xlib-screen.c
@@ -277,6 +277,15 @@ _cairo_xlib_screen_close_display (cairo_xlib_display_t *display,
dpy = display->display;
+ while (! cairo_list_is_empty (&info->surfaces)) {
+ cairo_xlib_surface_t *surface;
+
+ surface = cairo_list_first_entry (&info->surfaces,
+ cairo_xlib_surface_t,
+ link);
+ cairo_surface_finish (&surface->base);
+ }
+
for (i = 0; i < ARRAY_LENGTH (info->gc); i++) {
if (info->gc_depths[i] != 0) {
XFreeGC (dpy, info->gc[i]);
@@ -336,6 +345,7 @@ _cairo_xlib_screen_get (Display *dpy,
memset (info->gc_depths, 0, sizeof (info->gc_depths));
memset (info->gc, 0, sizeof (info->gc));
+ cairo_list_init (&info->surfaces);
cairo_list_init (&info->visuals);
cairo_list_add (&info->link, &display->screens);
diff --git a/src/cairo-xlib-surface-private.h b/src/cairo-xlib-surface-private.h
index 34732b4..b56b245 100644
--- a/src/cairo-xlib-surface-private.h
+++ b/src/cairo-xlib-surface-private.h
@@ -46,6 +46,7 @@ struct _cairo_xlib_surface {
cairo_xlib_screen_t *screen;
cairo_xlib_hook_t close_display_hook;
+ cairo_list_t link;
Drawable drawable;
cairo_bool_t owns_pixmap;
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 885dc59..6cc215b 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -466,6 +466,8 @@ _cairo_xlib_surface_finish (void *abstract_surface)
X_DEBUG ((display->display, "finish (drawable=%x)", (unsigned int) surface->drawable));
+ cairo_list_del (&surface->link);
+
status = _cairo_xlib_display_acquire (surface->base.device, &display);
if (unlikely (status))
return status;
@@ -3388,6 +3390,8 @@ found:
surface->b_mask = 0;
}
+ cairo_list_add (&surface->link, &screen->surfaces);
+
return &surface->base;
}
More information about the cairo-commit
mailing list