[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