[cairo] [PATCH 4/5] surface: Make backend-specific map/unmap functions symmetric

Andrea Canciani ranma42 at gmail.com
Sun Jan 15 05:59:07 PST 2012


Map allocates a surface. Symmetrically, unmap should destroy it.
---
 src/cairo-gl-surface.c           |   17 ++++++++++++-----
 src/cairo-image-surface.c        |    3 +++
 src/cairo-os2-surface.c          |    1 +
 src/cairo-quartz-image-surface.c |    7 ++-----
 src/cairo-quartz-surface.c       |    1 +
 src/cairo-surface-observer.c     |   12 ++----------
 src/cairo-surface-subsurface.c   |   12 ++----------
 src/cairo-surface.c              |    2 ++
 src/cairo-win32-surface.c        |    1 +
 src/cairo-xcb-surface.c          |   13 ++++++++++---
 src/cairo-xlib-surface.c         |   17 ++++++++++++-----
 src/cairo-xlib-xcb-surface.c     |   10 ++--------
 12 files changed, 50 insertions(+), 46 deletions(-)

diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index 7601b6a..4a51c72 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -1109,11 +1109,18 @@ static cairo_int_status_t
 _cairo_gl_surface_unmap_image (void		      *abstract_surface,
 			       cairo_image_surface_t *image)
 {
-    return _cairo_gl_surface_draw_image (abstract_surface, image,
-					 0, 0,
-					 image->width, image->height,
-					 image->base.device_transform_inverse.x0,
-					 image->base.device_transform_inverse.y0);
+    cairo_int_status_t status;
+
+    status = _cairo_gl_surface_draw_image (abstract_surface, image,
+					   0, 0,
+					   image->width, image->height,
+					   image->base.device_transform_inverse.x0,
+					   image->base.device_transform_inverse.y0);
+
+    cairo_surface_finish (image);
+    cairo_surface_destroy (image);
+
+    return status;
 }
 
 static cairo_bool_t
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 6adbdd6..d9702cd 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -792,6 +792,9 @@ cairo_int_status_t
 _cairo_image_surface_unmap_image (void *abstract_surface,
 				  cairo_image_surface_t *image)
 {
+    cairo_surface_finish (&image->base);
+    cairo_surface_destroy (&image->base);
+
     return CAIRO_INT_STATUS_SUCCESS;
 }
 
diff --git a/src/cairo-os2-surface.c b/src/cairo-os2-surface.c
index 51171fa..749c0c2 100644
--- a/src/cairo-os2-surface.c
+++ b/src/cairo-os2-surface.c
@@ -596,6 +596,7 @@ _cairo_os2_surface_map_to_image (void *abstract_surface,
     surface->pixel_array_lend_count++;
     DosReleaseMutexSem (local_os2_surface->hmtx_use_private_fields);
 
+    /* XXX: BROKEN! */
     *image_out = _cairo_surface_create_for_rectangle_int (surface->image_surface,
 							  extents);
 
diff --git a/src/cairo-quartz-image-surface.c b/src/cairo-quartz-image-surface.c
index b5f8612..334680b 100644
--- a/src/cairo-quartz-image-surface.c
+++ b/src/cairo-quartz-image-surface.c
@@ -112,8 +112,7 @@ _cairo_quartz_image_surface_map_to_image (void *asurface,
 					  const cairo_rectangle_int_t *extents)
 {
     cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) asurface;
-
-    return cairo_surface_map_to_image (&surface->imageSurface->base, extents);
+    return _cairo_surface_map_to_image (&surface->imageSurface->base, extents);
 }
 
 static cairo_int_status_t
@@ -121,9 +120,7 @@ _cairo_quartz_image_surface_unmap_image (void *asurface,
 					 cairo_image_surface_t *image)
 {
     cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) asurface;
-
-    cairo_surface_unmap_image (&surface->imageSurface->base, &image->base);
-    return cairo_surface_status (&surface->imageSurface->base);
+    return _cairo_surface_unmap_image (&surface->imageSurface->base, image);
 }
 
 static cairo_bool_t
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index e18461b..d89245a 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -1565,6 +1565,7 @@ _cairo_quartz_surface_map_to_image (void *abstract_surface,
 	return _cairo_surface_create_in_error (status);
 
     /* Is this legitimate? shouldn't it return an image surface? */
+    /* XXX: BROKEN! */
 
     subsurface = _cairo_surface_create_for_rectangle_int (&image->base, extents);
     cairo_surface_destroy (&image->base);
diff --git a/src/cairo-surface-observer.c b/src/cairo-surface-observer.c
index c70c0cc..dd25125 100644
--- a/src/cairo-surface-observer.c
+++ b/src/cairo-surface-observer.c
@@ -473,11 +473,7 @@ _cairo_surface_observer_map_to_image (void *abstract_surface,
 				      const cairo_rectangle_int_t *extents)
 {
     cairo_surface_observer_t *surface = abstract_surface;
-
-    if (surface->target->backend->map_to_image == NULL)
-	return NULL;
-
-    return surface->target->backend->map_to_image (surface->target, extents);
+    return _cairo_surface_map_to_image (surface->target, extents);
 }
 
 static cairo_int_status_t
@@ -485,11 +481,7 @@ _cairo_surface_observer_unmap_image (void *abstract_surface,
 				     cairo_image_surface_t *image)
 {
     cairo_surface_observer_t *surface = abstract_surface;
-
-    if (surface->target->backend->unmap_image == NULL)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    return surface->target->backend->unmap_image (surface->target, image);
+    return _cairo_surface_unmap_image (surface->target, image);
 }
 
 static void
diff --git a/src/cairo-surface-subsurface.c b/src/cairo-surface-subsurface.c
index b2f7e0a..6e69378 100644
--- a/src/cairo-surface-subsurface.c
+++ b/src/cairo-surface-subsurface.c
@@ -90,16 +90,12 @@ _cairo_surface_subsurface_map_to_image (void *abstract_surface,
     cairo_surface_subsurface_t *surface = abstract_surface;
     cairo_rectangle_int_t target_extents;
 
-    if (surface->target->backend->map_to_image == NULL)
-	return NULL;
-
     target_extents.x = extents->x + surface->extents.x;
     target_extents.y = extents->y + surface->extents.y;
     target_extents.width  = extents->width;
     target_extents.height = extents->height;
 
-    return surface->target->backend->map_to_image (surface->target,
-						   &target_extents);
+    return _cairo_surface_map_to_image (surface->target, &target_extents);
 }
 
 static cairo_int_status_t
@@ -107,11 +103,7 @@ _cairo_surface_subsurface_unmap_image (void *abstract_surface,
 				       cairo_image_surface_t *image)
 {
     cairo_surface_subsurface_t *surface = abstract_surface;
-
-    if (surface->target->backend->unmap_image == NULL)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    return surface->target->backend->unmap_image (surface->target, image);
+    return _cairo_surface_unmap_image (surface->target, image);
 }
 
 static cairo_int_status_t
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index d470596..d22728c 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -770,6 +770,8 @@ _cairo_surface_unmap_image (cairo_surface_t  *surface,
 	_cairo_clip_destroy (clip);
 
 	goto destroy;
+    } else {
+	return status;
     }
 
 destroy:
diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c
index c7d3216..d7de969 100644
--- a/src/cairo-win32-surface.c
+++ b/src/cairo-win32-surface.c
@@ -561,6 +561,7 @@ _cairo_win32_surface_map_to_image (void                    *abstract_surface,
 
     if (surface->image) {
 	GdiFlush();
+	/* XXX: BROKEN! */
 	return _cairo_surface_create_for_rectangle_int (surface->image,
 							extents);
     }
diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index aa2bbbf..7c4eec3 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -745,7 +745,7 @@ _cairo_xcb_surface_map_to_image (void *abstract_surface,
     cairo_surface_t *image;
 
     if (surface->fallback)
-	return surface->fallback->base.backend->map_to_image (&surface->fallback->base, extents);
+	return _cairo_surface_map_to_image (&surface->fallback->base, extents);
 
     image = _get_image (surface, TRUE,
 			extents->x, extents->y,
@@ -777,10 +777,17 @@ _cairo_xcb_surface_unmap (void *abstract_surface,
 			  cairo_image_surface_t *image)
 {
     cairo_xcb_surface_t *surface = abstract_surface;
+    cairo_int_status_t status;
 
     if (surface->fallback)
-	return surface->fallback->base.backend->unmap_image (&surface->fallback->base, image);
-    return _put_image (abstract_surface, image);
+	return _cairo_surface_unmap_image (&surface->fallback->base, image);
+
+    status = _put_image (abstract_surface, image);
+
+    cairo_surface_finish (image);
+    cairo_surface_destroy (image);
+
+    return status;
 }
 
 static cairo_surface_t *
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 0ec1264..bef6b02 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -1264,11 +1264,18 @@ static cairo_int_status_t
 _cairo_xlib_surface_unmap_image (void *abstract_surface,
 				 cairo_image_surface_t *image)
 {
-    return _cairo_xlib_surface_draw_image (abstract_surface, image,
-					   0, 0,
-					   image->width, image->height,
-					   image->base.device_transform_inverse.x0,
-					   image->base.device_transform_inverse.y0);
+    cairo_int_status_t status;
+
+    status = _cairo_xlib_surface_draw_image (abstract_surface, image,
+					     0, 0,
+					     image->width, image->height,
+					     image->base.device_transform_inverse.x0,
+					     image->base.device_transform_inverse.y0);
+
+    cairo_surface_finish (image);
+    cairo_surface_destroy (image);
+
+    return status;
 }
 
 static cairo_bool_t
diff --git a/src/cairo-xlib-xcb-surface.c b/src/cairo-xlib-xcb-surface.c
index 5021cfc..70cc4d8 100644
--- a/src/cairo-xlib-xcb-surface.c
+++ b/src/cairo-xlib-xcb-surface.c
@@ -120,7 +120,7 @@ _cairo_xlib_xcb_surface_map_to_image (void *abstract_surface,
 				      const cairo_rectangle_int_t *extents)
 {
     cairo_xlib_xcb_surface_t *surface = abstract_surface;
-    return cairo_surface_map_to_image (&surface->xcb->base, extents);
+    return _cairo_surface_map_to_image (&surface->xcb->base, extents);
 }
 
 static cairo_int_status_t
@@ -128,13 +128,7 @@ _cairo_xlib_xcb_surface_unmap (void *abstract_surface,
 			       cairo_image_surface_t *image)
 {
     cairo_xlib_xcb_surface_t *surface = abstract_surface;
-
-    /* cairo_surface_unmap_image destroys the surface, so get a new reference
-     * for it to destroy.
-     */
-    cairo_surface_reference (&image->base);
-    cairo_surface_unmap_image (&surface->xcb->base, &image->base);
-    return cairo_surface_status (&surface->xcb->base);
+    return _cairo_surface_unmap_image (&surface->xcb->base, image);
 }
 
 static cairo_status_t
-- 
1.7.5.4



More information about the cairo mailing list