[cairo-commit] src/cairo-quartz-surface.c

Vladimir Vukicevic vladimir at kemper.freedesktop.org
Wed Jul 9 13:23:36 PDT 2008


 src/cairo-quartz-surface.c |   30 +++++++++++++++++++++---------
 1 file changed, 21 insertions(+), 9 deletions(-)

New commits:
commit d61c7df1c0f9c69b0022c58efd001855551af7dd
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date:   Wed Jul 9 13:20:53 2008 -0700

    [quartz] Take snapshot instead of using CGImageCreateCopy
    
    CGImageCreateCopy doesn't copy the data provider, so it's possible to
    free the data underneath an image without snapshotting it first.

diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index 84d8702..5bdabb7 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -695,6 +695,13 @@ CreateRepeatingGradientFunction (cairo_quartz_surface_t *surface,
 
 /* Obtain a CGImageRef from a #cairo_surface_t * */
 
+static void
+DataProviderReleaseCallback (void *info, const void *data, size_t size)
+{
+    cairo_surface_t *surface = (cairo_surface_t *) info;
+    cairo_surface_destroy (surface);
+}
+
 static cairo_status_t
 _cairo_surface_to_cgimage (cairo_surface_t *target,
 			   cairo_surface_t *source,
@@ -737,17 +744,22 @@ _cairo_surface_to_cgimage (cairo_surface_t *target,
     if (isurf->width == 0 || isurf->height == 0) {
 	*image_out = NULL;
     } else {
-	image = _cairo_quartz_create_cgimage (isurf->format,
-					      isurf->width,
-					      isurf->height,
-					      isurf->stride,
-					      isurf->data,
+	cairo_image_surface_t *isurf_snap = NULL;
+	isurf_snap = _cairo_surface_snapshot (isurf);
+	if (isurf_snap == NULL)
+	    return CAIRO_STATUS_NO_MEMORY;
+
+	image = _cairo_quartz_create_cgimage (isurf_snap->format,
+					      isurf_snap->width,
+					      isurf_snap->height,
+					      isurf_snap->stride,
+					      isurf_snap->data,
 					      TRUE,
-					      NULL, NULL, NULL);
+					      NULL,
+					      DataProviderReleaseCallback,
+					      isurf_snap);
 
-	/* Create a copy to ensure that the CGImageRef doesn't depend on the image surface's backing store */
-	*image_out = CGImageCreateCopy (image);
-	CGImageRelease (image);
+	*image_out = image;
     }
 
     if ((cairo_surface_t*) isurf != source)


More information about the cairo-commit mailing list