[cairo-commit] 4 commits - src/cairo-spans-compositor.c src/cairo-traps-compositor.c test/reference

Chris Wilson ickle at kemper.freedesktop.org
Fri May 11 13:33:38 PDT 2012


 src/cairo-spans-compositor.c                       |  113 +++++++++++++++++----
 src/cairo-traps-compositor.c                       |    2 
 test/reference/tighten-bounds.argb32.ref.png       |binary
 test/reference/tighten-bounds.rgb24.ref.png        |binary
 test/reference/tighten-bounds.traps.argb32.ref.png |binary
 test/reference/tighten-bounds.traps.rgb24.ref.png  |binary
 6 files changed, 95 insertions(+), 20 deletions(-)

New commits:
commit cd1004ce19c7ea28c7fedb6464562a08416586c0
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri May 11 21:20:35 2012 +0100

    traps,spans-compositor: Avoid mistreating unaligned clips as aligned
    
    An unaligned clip requires careful handling, and so exclude processing
    along the fast paths.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-spans-compositor.c b/src/cairo-spans-compositor.c
index 2e2f4f4..a60cff4 100644
--- a/src/cairo-spans-compositor.c
+++ b/src/cairo-spans-compositor.c
@@ -519,6 +519,26 @@ upload_boxes (const cairo_spans_compositor_t *compositor,
     return status;
 }
 
+static cairo_bool_t
+_clip_is_region (const cairo_clip_t *clip)
+{
+    int i;
+
+    if (clip->is_region)
+	return TRUE;
+
+    if (clip->path)
+	return FALSE;
+
+    for (i = 0; i < clip->num_boxes; i++) {
+	const cairo_box_t *b = &clip->boxes[i];
+	if (!_cairo_fixed_is_integer (b->p1.x | b->p1.y |  b->p2.x | b->p2.y))
+	    return FALSE;
+    }
+
+    return TRUE;
+}
+
 static cairo_int_status_t
 composite_aligned_boxes (const cairo_spans_compositor_t		*compositor,
 			 const cairo_composite_rectangles_t	*extents,
@@ -528,7 +548,7 @@ composite_aligned_boxes (const cairo_spans_compositor_t		*compositor,
     cairo_operator_t op = extents->op;
     const cairo_pattern_t *source = &extents->source_pattern.base;
     cairo_int_status_t status;
-    cairo_bool_t need_clip_mask = extents->clip->path != NULL;
+    cairo_bool_t need_clip_mask = ! _clip_is_region (extents->clip);
     cairo_bool_t op_is_source;
     cairo_bool_t no_mask;
     cairo_bool_t inplace;
@@ -716,7 +736,7 @@ composite_polygon (const cairo_spans_compositor_t	*compositor,
     cairo_bool_t needs_clip;
     cairo_int_status_t status;
 
-    needs_clip = extents->clip->path != NULL || extents->clip->num_boxes > 1;
+    needs_clip = extents->clip->num_boxes > 1 || ! _clip_is_region (extents->clip);
     TRACE ((stderr, "%s - needs_clip=%d\n", __FUNCTION__, needs_clip));
     if (needs_clip) {
 	return CAIRO_INT_STATUS_UNSUPPORTED;
diff --git a/src/cairo-traps-compositor.c b/src/cairo-traps-compositor.c
index f8308ad..eeee20c 100644
--- a/src/cairo-traps-compositor.c
+++ b/src/cairo-traps-compositor.c
@@ -1178,7 +1178,7 @@ composite_aligned_boxes (const cairo_traps_compositor_t *compositor,
 {
     cairo_surface_t *dst = extents->surface;
     cairo_operator_t op = extents->op;
-    cairo_bool_t need_clip_mask = extents->clip->path != NULL;
+    cairo_bool_t need_clip_mask = ! _cairo_clip_is_region (extents->clip);
     cairo_bool_t op_is_source;
     cairo_status_t status;
 
commit de1150cc0e1cb11710b196806335817255cb4abe
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri May 11 20:51:58 2012 +0100

    spans-compositor: Add tracepoints for debugging
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-spans-compositor.c b/src/cairo-spans-compositor.c
index 38a2d97..2e2f4f4 100644
--- a/src/cairo-spans-compositor.c
+++ b/src/cairo-spans-compositor.c
@@ -245,6 +245,8 @@ fixup_unbounded_mask (const cairo_spans_compositor_t *compositor,
     cairo_surface_t *clip;
     cairo_int_status_t status;
 
+    TRACE((stderr, "%s\n", __FUNCTION__));
+
     clip = get_clip_surface (compositor, extents->surface, extents->clip,
 			     &extents->unbounded);
     if (unlikely (clip->status)) {
@@ -288,6 +290,8 @@ fixup_unbounded_polygon (const cairo_spans_compositor_t *compositor,
     cairo_antialias_t antialias;
     cairo_int_status_t status;
 
+    TRACE((stderr, "%s\n", __FUNCTION__));
+
     /* Can we treat the clip as a regular clear-polygon and use it to fill? */
     status = _cairo_clip_get_polygon (extents->clip, &polygon,
 				      &fill_rule, &antialias);
@@ -712,8 +716,8 @@ composite_polygon (const cairo_spans_compositor_t	*compositor,
     cairo_bool_t needs_clip;
     cairo_int_status_t status;
 
-    TRACE ((stderr, "%s\n", __FUNCTION__));
     needs_clip = extents->clip->path != NULL || extents->clip->num_boxes > 1;
+    TRACE ((stderr, "%s - needs_clip=%d\n", __FUNCTION__, needs_clip));
     if (needs_clip) {
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 	converter = _cairo_clip_tor_scan_converter_create (extents->clip,
@@ -882,6 +886,9 @@ clip_and_composite_polygon (const cairo_spans_compositor_t	*compositor,
 	cairo_antialias_t clip_antialias;
 	cairo_fill_rule_t clip_fill_rule;
 
+	TRACE((stderr, "%s - combining shape with clip polygon\n",
+	       __FUNCTION__));
+
 	status = _cairo_clip_get_polygon (extents->clip,
 					  &clipper,
 					  &clip_fill_rule,
@@ -1042,10 +1049,14 @@ _cairo_spans_compositor_fill (const cairo_compositor_t		*_compositor,
     const cairo_spans_compositor_t *compositor = (cairo_spans_compositor_t*)_compositor;
     cairo_int_status_t status;
 
+    TRACE((stderr, "%s op=%d, antialias=%d\n", __FUNCTION__, extents->op, antialias));
+
     status = CAIRO_INT_STATUS_UNSUPPORTED;
     if (_cairo_path_fixed_fill_is_rectilinear (path)) {
 	cairo_boxes_t boxes;
 
+	TRACE((stderr, "%s - rectilinear\n", __FUNCTION__));
+
 	_cairo_boxes_init (&boxes);
 	if (! _cairo_clip_contains_rectangle (extents->clip, &extents->mask))
 	    _cairo_boxes_limit (&boxes,
@@ -1062,10 +1073,13 @@ _cairo_spans_compositor_fill (const cairo_compositor_t		*_compositor,
     if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
 	cairo_polygon_t polygon;
 
+	TRACE((stderr, "%s - polygon\n", __FUNCTION__));
+
 	if (extents->mask.width  > extents->unbounded.width ||
 	    extents->mask.height > extents->unbounded.height)
 	{
 	    cairo_box_t limits;
+	    TRACE((stderr, "%s - clipping to bounds\n", __FUNCTION__));
 	    _cairo_box_from_rectangle (&limits, &extents->unbounded);
 	    _cairo_polygon_init (&polygon, &limits, 1);
 	}
@@ -1076,6 +1090,8 @@ _cairo_spans_compositor_fill (const cairo_compositor_t		*_compositor,
 
 	status = _cairo_path_fixed_fill_to_polygon (path, tolerance, &polygon);
 	if (status == CAIRO_INT_STATUS_SUCCESS && extents->clip->num_boxes > 1) {
+	    TRACE((stderr, "%s - polygon intersect with %d clip boxes\n",
+		   __FUNCTION__, extents->clip->num_boxes));
 	    status = _cairo_polygon_intersect_with_boxes (&polygon, &fill_rule,
 							  extents->clip->boxes,
 							  extents->clip->num_boxes);
@@ -1084,6 +1100,8 @@ _cairo_spans_compositor_fill (const cairo_compositor_t		*_compositor,
 	    cairo_clip_t *saved_clip = extents->clip;
 
 	    if (extents->is_bounded) {
+		TRACE((stderr, "%s - polygon discard clip boxes\n",
+		       __FUNCTION__));
 		extents->clip = _cairo_clip_copy_path (extents->clip);
 		extents->clip = _cairo_clip_intersect_box(extents->clip,
 							  &polygon.extents);
@@ -1098,6 +1116,8 @@ _cairo_spans_compositor_fill (const cairo_compositor_t		*_compositor,
 	    }
 	}
 	_cairo_polygon_fini (&polygon);
+
+	TRACE((stderr, "%s - polygon status=%d\n", __FUNCTION__, status));
     }
 
     return status;
commit 197e5b7324c569d3e8cd652dbf5a281a57317cbe
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri May 11 20:25:29 2012 +0100

    spans-compositor: Handle unaligned unbounded boxes
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-spans-compositor.c b/src/cairo-spans-compositor.c
index 357c0ea..38a2d97 100644
--- a/src/cairo-spans-compositor.c
+++ b/src/cairo-spans-compositor.c
@@ -111,11 +111,31 @@ get_clip_surface (const cairo_spans_compositor_t *compositor,
     if (unlikely (status))
 	goto cleanup_polygon;
 
+    antialias = clip_path->antialias;
+    fill_rule = clip_path->fill_rule;
+
+    if (clip->boxes) {
+	cairo_polygon_t intersect;
+	cairo_boxes_t tmp;
+
+	_cairo_boxes_init_for_array (&tmp, clip->boxes, clip->num_boxes);
+	status= _cairo_polygon_init_boxes (&intersect, &tmp);
+	if (unlikely (status))
+	    goto cleanup_polygon;
+
+	status = _cairo_polygon_intersect (&polygon, fill_rule,
+					   &intersect, CAIRO_FILL_RULE_WINDING);
+	_cairo_polygon_fini (&intersect);
+
+	if (unlikely (status))
+	    goto cleanup_polygon;
+
+	fill_rule = CAIRO_FILL_RULE_WINDING;
+    }
+
     polygon.limits = NULL;
     polygon.num_limits = 0;
 
-    antialias = clip_path->antialias;
-    fill_rule = clip_path->fill_rule;
     clip_path = clip_path->prev;
     while (clip_path) {
 	if (clip_path->antialias == antialias) {
@@ -353,26 +373,41 @@ fixup_unbounded_boxes (const cairo_spans_compositor_t *compositor,
 	assert (status == CAIRO_INT_STATUS_SUCCESS);
     }
 
-    /* Now intersect with the clip boxes */
-    if (extents->clip->num_boxes) {
-	_cairo_boxes_init_for_array (&tmp,
-				     extents->clip->boxes,
-				     extents->clip->num_boxes);
-	status = _cairo_boxes_intersect (&clear, &tmp, &clear);
-	if (unlikely (status))
-	    goto error;
-    }
-
     /* If we have a clip polygon, we need to intersect with that as well */
     if (extents->clip->path) {
 	status = fixup_unbounded_polygon (compositor, extents, &clear);
 	if (status == CAIRO_INT_STATUS_UNSUPPORTED)
 	    status = fixup_unbounded_mask (compositor, extents, &clear);
     } else {
-	status = compositor->fill_boxes (extents->surface,
-					 CAIRO_OPERATOR_CLEAR,
-					 CAIRO_COLOR_TRANSPARENT,
-					 &clear);
+	/* Otherwise just intersect with the clip boxes */
+	if (extents->clip->num_boxes) {
+	    _cairo_boxes_init_for_array (&tmp,
+					 extents->clip->boxes,
+					 extents->clip->num_boxes);
+	    status = _cairo_boxes_intersect (&clear, &tmp, &clear);
+	    if (unlikely (status))
+		goto error;
+	}
+
+	if (clear.is_pixel_aligned) {
+	    status = compositor->fill_boxes (extents->surface,
+					     CAIRO_OPERATOR_CLEAR,
+					     CAIRO_COLOR_TRANSPARENT,
+					     &clear);
+	} else {
+	    cairo_composite_rectangles_t composite;
+
+	    status = _cairo_composite_rectangles_init_for_boxes (&composite,
+								 extents->surface,
+								 CAIRO_OPERATOR_CLEAR,
+								 &_cairo_pattern_clear.base,
+								 &clear,
+								 NULL);
+	    if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
+		status = composite_boxes (compositor, &composite, &clear);
+		_cairo_composite_rectangles_fini (&composite);
+	    }
+	}
     }
 
 error:
commit 2d26f7da777b7ac01e5c469e52a17fa7d0cf4a8d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri May 11 21:26:33 2012 +0100

    test: Fix tighten-bounds reference images
    
    Uli Schlachter spotted that I had inadvertently committed (606e9e1c9) a
    broken set of test images for the tighten-bounds case and so masked a
    nasty bug with the mishandling of unaligned clips.
    
    Reported-by: Uli Schlachter <psychon at znc.in>
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/test/reference/tighten-bounds.argb32.ref.png b/test/reference/tighten-bounds.argb32.ref.png
index e348018..6634ed1 100644
Binary files a/test/reference/tighten-bounds.argb32.ref.png and b/test/reference/tighten-bounds.argb32.ref.png differ
diff --git a/test/reference/tighten-bounds.rgb24.ref.png b/test/reference/tighten-bounds.rgb24.ref.png
index 28e3c1b..d15bddd 100644
Binary files a/test/reference/tighten-bounds.rgb24.ref.png and b/test/reference/tighten-bounds.rgb24.ref.png differ
diff --git a/test/reference/tighten-bounds.traps.argb32.ref.png b/test/reference/tighten-bounds.traps.argb32.ref.png
index 9d22568..291a841 100644
Binary files a/test/reference/tighten-bounds.traps.argb32.ref.png and b/test/reference/tighten-bounds.traps.argb32.ref.png differ
diff --git a/test/reference/tighten-bounds.traps.rgb24.ref.png b/test/reference/tighten-bounds.traps.rgb24.ref.png
index 98fc412..f31c17c 100644
Binary files a/test/reference/tighten-bounds.traps.rgb24.ref.png and b/test/reference/tighten-bounds.traps.rgb24.ref.png differ


More information about the cairo-commit mailing list