[cairo-commit] 3 commits - src/cairo-image-source.c src/cairo-surface-subsurface.c

Chris Wilson ickle at kemper.freedesktop.org
Wed Nov 23 06:26:24 PST 2011


 src/cairo-image-source.c       |   59 ++++-------------
 src/cairo-surface-subsurface.c |  136 ++++++-----------------------------------
 2 files changed, 37 insertions(+), 158 deletions(-)

New commits:
commit 1fe16f75b1c7707949eaa9f5c34f908784990b60
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 23 14:12:50 2011 +0000

    image: Remove dubious "optimisations" for acquired source images
    
    By this point we have already paid the penalty for acquiring the source
    image, so kiss.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-image-source.c b/src/cairo-image-source.c
index 646c20a..cdf9a7f 100644
--- a/src/cairo-image-source.c
+++ b/src/cairo-image-source.c
@@ -855,35 +855,6 @@ _pixman_image_for_surface (cairo_image_surface_t *dst,
 	if (unlikely (status))
 	    return NULL;
 
-	if (sample->x >= 0 && sample->y >= 0 &&
-	    sample->x + sample->width  <= image->width &&
-	    sample->y + sample->height <= image->height)
-	{
-	    extend = CAIRO_EXTEND_NONE;
-	}
-
-	if (sample->width == 1 && sample->height == 1) {
-	    if (sample->x < 0 ||
-		sample->y < 0 ||
-		sample->x >= image->width ||
-		sample->y >= image->height)
-	    {
-		if (extend == CAIRO_EXTEND_NONE) {
-		    pixman_image = _pixman_transparent_image ();
-		    _cairo_surface_release_source_image (pattern->surface, image, extra);
-		    return pixman_image;
-		}
-	    }
-	    else
-	    {
-		pixman_image = _pixel_to_solid (image, sample->x, sample->y);
-                if (pixman_image) {
-                    _cairo_surface_release_source_image (pattern->surface, image, extra);
-                    return pixman_image;
-                }
-	    }
-	}
-
 	pixman_image = pixman_image_create_bits (image->pixman_format,
 						 image->width,
 						 image->height,
commit c52129feb429863f820928434185b6605dd4f1a6
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 23 12:25:59 2011 +0000

    subsurface: Simplify acquire_source_image
    
    Remove all of the special casing and simply extract the source. The time
    for special casing is to avoid calling the generic acquire in the first
    place, so kiss.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-surface-subsurface.c b/src/cairo-surface-subsurface.c
index b93604f..3459c53 100644
--- a/src/cairo-surface-subsurface.c
+++ b/src/cairo-surface-subsurface.c
@@ -294,128 +294,34 @@ _cairo_surface_subsurface_acquire_source_image (void                    *abstrac
 						cairo_image_surface_t  **image_out,
 						void                   **extra_out)
 {
-    cairo_rectangle_int_t target_extents;
     cairo_surface_subsurface_t *surface = abstract_surface;
-    cairo_image_surface_t *image;
+    cairo_surface_pattern_t pattern;
+    cairo_surface_t *image;
     cairo_status_t status;
-    struct extra *extra;
-    uint8_t *data;
-    cairo_bool_t ret;
-
-    if (surface->target->type == CAIRO_SURFACE_TYPE_RECORDING) {
-	cairo_surface_t *meta, *snapshot;
-
-	snapshot = _cairo_surface_has_snapshot (&surface->base,
-						&_cairo_image_surface_backend);
-	if (snapshot != NULL) {
-	    *image_out = (cairo_image_surface_t *) cairo_surface_reference (snapshot);
-	    *extra_out = NULL;
-	    return CAIRO_STATUS_SUCCESS;
-	}
 
-	meta = surface->target;
-	if (_cairo_surface_is_snapshot (meta))
-	    meta = _cairo_surface_snapshot_get_target (meta);
-
-	if (! _cairo_surface_has_snapshot (meta, &_cairo_image_surface_backend)) {
-	    cairo_surface_pattern_t pattern;
-
-	    image = (cairo_image_surface_t *)
-		_cairo_image_surface_create_with_content (meta->content,
-							  surface->extents.width,
-							  surface->extents.height);
-	    if (unlikely (image->base.status))
-		return image->base.status;
-
-	    _cairo_pattern_init_for_surface (&pattern, &image->base);
-	    cairo_matrix_init_translate (&pattern.base.matrix,
-					 -surface->extents.x, -surface->extents.y);
-	    pattern.base.filter = CAIRO_FILTER_NEAREST;
-	    status = _cairo_surface_paint (&image->base,
-					   CAIRO_OPERATOR_SOURCE,
-					   &pattern.base, NULL);
-	    _cairo_pattern_fini (&pattern.base);
-	    if (unlikely (status)) {
-		cairo_surface_destroy (&image->base);
-		return status;
-	    }
-
-	    _cairo_surface_attach_snapshot (&surface->base, &image->base, NULL);
-
-	    *image_out = image;
-	    *extra_out = NULL;
-	    return CAIRO_STATUS_SUCCESS;
-	}
-    }
+    image = _cairo_image_surface_create_with_content (surface->base.content,
+						      surface->extents.width,
+						      surface->extents.height);
+    if (unlikely (image->status))
+	return image->status;
 
-    extra = malloc (sizeof (struct extra));
-    if (unlikely (extra == NULL))
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
-    status = _cairo_surface_acquire_source_image (surface->target, &extra->image, &extra->image_extra);
-    if (unlikely (status))
-	goto CLEANUP;
-
-    ret = _cairo_surface_get_extents (&extra->image->base, &target_extents);
-    assert (ret);
-
-    /* only copy if we need to perform sub-byte manipulation */
-    if (PIXMAN_FORMAT_BPP (extra->image->pixman_format) >= 8 &&
-	target_extents.x <= surface->extents.x &&
-	target_extents.y <= surface->extents.y &&
-	surface->extents.x + surface->extents.width <= target_extents.x + target_extents.width &&
-	surface->extents.y + surface->extents.height <= target_extents.y + target_extents.height) {
-
-	assert ((PIXMAN_FORMAT_BPP (extra->image->pixman_format) % 8) == 0);
-
-	data = extra->image->data + surface->extents.y * extra->image->stride;
-	data += PIXMAN_FORMAT_BPP (extra->image->pixman_format) / 8 * surface->extents.x;
-
-	image = (cairo_image_surface_t *)
-	    _cairo_image_surface_create_with_pixman_format (data,
-							    extra->image->pixman_format,
-							    surface->extents.width,
-							    surface->extents.height,
-							    extra->image->stride);
-	if (unlikely ((status = image->base.status)))
-	    goto CLEANUP_IMAGE;
-
-        image->base.is_clear = FALSE;
-    } else {
-	cairo_surface_pattern_t pattern;
-
-	image = (cairo_image_surface_t *)
-	    _cairo_image_surface_create_with_pixman_format (NULL,
-							    extra->image->pixman_format,
-							    surface->extents.width,
-							    surface->extents.height,
-							    0);
-	if (unlikely ((status = image->base.status)))
-	    goto CLEANUP_IMAGE;
-
-	_cairo_pattern_init_for_surface (&pattern, &image->base);
-	cairo_matrix_init_translate (&pattern.base.matrix,
-				     -surface->extents.x, -surface->extents.y);
-	pattern.base.filter = CAIRO_FILTER_NEAREST;
-	status = _cairo_surface_paint (&image->base,
-				       CAIRO_OPERATOR_SOURCE,
-				       &pattern.base, NULL);
-	_cairo_pattern_fini (&pattern.base);
-	if (unlikely (status)) {
-	    cairo_surface_destroy (&image->base);
-	    return status;
-	}
+    _cairo_pattern_init_for_surface (&pattern, surface->target);
+    cairo_matrix_init_translate (&pattern.base.matrix,
+				 surface->extents.x,
+				 surface->extents.y);
+    pattern.base.filter = CAIRO_FILTER_NEAREST;
+    status = _cairo_surface_paint (image,
+				   CAIRO_OPERATOR_SOURCE,
+				   &pattern.base, NULL);
+    _cairo_pattern_fini (&pattern.base);
+    if (unlikely (status)) {
+	cairo_surface_destroy (image);
+	return status;
     }
 
-    *image_out = image;
-    *extra_out = extra;
+    *image_out = (cairo_image_surface_t *)image;
+    *extra_out = NULL;
     return CAIRO_STATUS_SUCCESS;
-
-CLEANUP_IMAGE:
-    _cairo_surface_release_source_image (surface->target, extra->image, extra->image_extra);
-CLEANUP:
-    free (extra);
-    return status;
 }
 
 static void
commit 73dc2c4e272f52dfffb2c268f4e8ee5ff0d57639
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 23 12:05:43 2011 +0000

    image: Only unwrap a subsurface if the sample is fully contained
    
    In order to handle out-of-bounds sampling of a subsurface target we need
    to first avoid incorrectly unwrapping it.
    
    Fixes crash in subsurface-outside-target
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-image-source.c b/src/cairo-image-source.c
index fde4475..646c20a 100644
--- a/src/cairo-image-source.c
+++ b/src/cairo-image-source.c
@@ -767,7 +767,6 @@ _pixman_image_for_surface (cairo_image_surface_t *dst,
 
 #if PIXMAN_HAS_ATOMIC_OPS
 	    /* avoid allocating a 'pattern' image if we can reuse the original */
-	    *ix = *iy = 0;
 	    if (extend == CAIRO_EXTEND_NONE &&
 		_cairo_matrix_is_pixman_translation (&pattern->base.matrix,
 						     pattern->base.filter,
@@ -826,23 +825,26 @@ _pixman_image_for_surface (cairo_image_surface_t *dst,
 
 	    /* Avoid sub-byte offsets, force a copy in that case. */
 	    if (PIXMAN_FORMAT_BPP (source->pixman_format) >= 8) {
-		void *data = source->data
-		    + sub->extents.x * PIXMAN_FORMAT_BPP(source->pixman_format)/8
-		    + sub->extents.y * source->stride;
-		pixman_image = pixman_image_create_bits (source->pixman_format,
-							 sub->extents.width,
-							 sub->extents.height,
-							 data,
-							 source->stride);
-		if (unlikely (pixman_image == NULL))
-		    return NULL;
+		if (is_contained) {
+		    void *data = source->data
+			+ sub->extents.x * PIXMAN_FORMAT_BPP(source->pixman_format)/8
+			+ sub->extents.y * source->stride;
+		    pixman_image = pixman_image_create_bits (source->pixman_format,
+							     sub->extents.width,
+							     sub->extents.height,
+							     data,
+							     source->stride);
+		    if (unlikely (pixman_image == NULL))
+			return NULL;
+		} else {
+		    /* XXX for a simple translation and EXTEND_NONE we can
+		     * fix up the pattern matrix instead.
+		     */
+		}
 	    }
 	}
     }
 
-#if PIXMAN_HAS_ATOMIC_OPS
-    *ix = *iy = 0;
-#endif
     if (pixman_image == NULL) {
 	struct acquire_source_cleanup *cleanup;
 	cairo_image_surface_t *image;


More information about the cairo-commit mailing list