[cairo-commit] 3 commits - src/cairo-clip.c src/cairo-surface-fallback.c src/cairo-xcb-surface-render.c

Chris Wilson ickle at kemper.freedesktop.org
Fri Jul 29 04:36:42 PDT 2011


 src/cairo-clip.c               |   10 +++
 src/cairo-surface-fallback.c   |  129 ++++++++++++++++++++++++++++++++++-------
 src/cairo-xcb-surface-render.c |    3 
 3 files changed, 122 insertions(+), 20 deletions(-)

New commits:
commit fb9ed9bb0d3a4d4ac71f5d472f63a04ffbc4c110
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Jul 29 12:35:36 2011 +0100

    clip: Fix clip-equal to handle one or the other being NULL/all-clipped
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index b01093e..4058879 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -346,6 +346,16 @@ _cairo_clip_equal (const cairo_clip_t *clip_a,
     if (clip_a == clip_b)
 	return TRUE;
 
+    /* or just one of them? */
+    if (clip_a == NULL || clip_b == NULL ||
+	_cairo_clip_is_all_clipped (clip_a) ||
+	_cairo_clip_is_all_clipped (clip_b))
+    {
+	return FALSE;
+    }
+
+    /* We have a pair of normal clips, check their contents */
+
     if (clip_a->num_boxes != clip_b->num_boxes)
 	return FALSE;
 
commit 7c6e1b8db89420fa69ebd8d2ba12dde1aeb47ea8
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Jul 29 12:33:07 2011 +0100

    xcb: Short-circuit multiplying the alpha mask by 1.0
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c
index 586b9fe..9830617 100644
--- a/src/cairo-xcb-surface-render.c
+++ b/src/cairo-xcb-surface-render.c
@@ -1666,6 +1666,9 @@ static void blt_in(void *closure,
     xcb_render_color_t color;
     xcb_rectangle_t rect;
 
+    if (coverage == 0xffff)
+	return;
+
     color.red = color.green = color.blue = 0;
     color.alpha = coverage;
 
commit 4032c86127a5f1658c2bddbf1c642fb62e21a208
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Jul 29 12:31:14 2011 +0100

    fallback: Prevent recursion when combining with the clip
    
    We need to special case the handling of unaligned clip regions in order
    to prevent the treatment of those as a general path requiring a
    clip+mask...
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index bd03274..95d3c17 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -119,6 +119,84 @@ typedef cairo_status_t
 		      const cairo_rectangle_int_t   *extents,
 		      cairo_region_t		    *clip_region);
 
+static void do_unaligned_row(void (*blt)(void *closure,
+					 int16_t x, int16_t y,
+					 int16_t w, int16_t h,
+					 uint16_t coverage),
+			     void *closure,
+			     const cairo_box_t *b,
+			     int tx, int y, int h,
+			     uint16_t coverage)
+{
+    int x1 = _cairo_fixed_integer_part (b->p1.x) - tx;
+    int x2 = _cairo_fixed_integer_part (b->p2.x) - tx;
+    if (x2 > x1) {
+	if (! _cairo_fixed_is_integer (b->p1.x)) {
+	    blt(closure, x1, y, 1, h,
+		coverage * (256 - _cairo_fixed_fractional_part (b->p1.x)));
+	    x1++;
+	}
+
+	if (x2 > x1)
+	    blt(closure, x1, y, x2-x1, h, (coverage << 8) - (coverage >> 8));
+
+	if (! _cairo_fixed_is_integer (b->p2.x))
+	    blt(closure, x2, y, 1, h,
+		coverage * _cairo_fixed_fractional_part (b->p2.x));
+    } else
+	blt(closure, x1, y, 1, h,
+	    coverage * (b->p2.x - b->p1.x));
+}
+
+static void do_unaligned_box(void (*blt)(void *closure,
+					 int16_t x, int16_t y,
+					 int16_t w, int16_t h,
+					 uint16_t coverage),
+			     void *closure,
+			     const cairo_box_t *b, int tx, int ty)
+{
+    int y1 = _cairo_fixed_integer_part (b->p1.y) - ty;
+    int y2 = _cairo_fixed_integer_part (b->p2.y) - ty;
+    if (y2 > y1) {
+	if (! _cairo_fixed_is_integer (b->p1.y)) {
+	    do_unaligned_row(blt, closure, b, tx, y1, 1,
+			     256 - _cairo_fixed_fractional_part (b->p1.y));
+	    y1++;
+	}
+
+	if (y2 > y1)
+	    do_unaligned_row(blt, closure, b, tx, y1, y2-y1, 256);
+
+	if (! _cairo_fixed_is_integer (b->p2.y))
+	    do_unaligned_row(blt, closure, b, tx, y2, 1,
+			     _cairo_fixed_fractional_part (b->p2.y));
+    } else
+	do_unaligned_row(blt, closure, b, tx, y1, 1,
+			 b->p2.y - b->p1.y);
+}
+
+static void blt_in(void *closure,
+		   int16_t x, int16_t y,
+		   int16_t w, int16_t h,
+		   uint16_t coverage)
+{
+    cairo_color_t color;
+    cairo_rectangle_int_t rect;
+
+    if (coverage == 0xffff)
+	return;
+
+    _cairo_color_init_rgba (&color, 0, 0, 0, coverage / (double) 0xffff);
+
+    rect.x = x;
+    rect.y = y;
+    rect.width  = w;
+    rect.height = h;
+
+    _cairo_surface_fill_rectangles (closure, CAIRO_OPERATOR_IN,
+				    &color, &rect, 1);
+}
+
 static cairo_status_t
 _create_composite_mask_pattern (cairo_surface_pattern_t       *mask_pattern,
 				cairo_clip_t                  *clip,
@@ -129,9 +207,8 @@ _create_composite_mask_pattern (cairo_surface_pattern_t       *mask_pattern,
 {
     cairo_surface_t *mask;
     cairo_status_t status;
-    cairo_region_t *clip_region = _cairo_clip_get_region (clip);
-    cairo_bool_t clip_surface = ! _cairo_clip_is_region (clip);
-    cairo_region_t *fallback_region = NULL;
+    cairo_region_t *clip_region;
+    int i;
 
     /* We need to use solid here, because to use CAIRO_OPERATOR_SOURCE with
      * a mask (as called via _cairo_surface_mask) triggers assertion failures.
@@ -145,34 +222,46 @@ _create_composite_mask_pattern (cairo_surface_pattern_t       *mask_pattern,
     if (unlikely (mask->status))
 	return mask->status;
 
-    if (clip_region && (extents->x || extents->y)) {
-	fallback_region = cairo_region_copy (clip_region);
-	status = fallback_region->status;
-	if (unlikely (status))
-	    goto CLEANUP_SURFACE;
-
-	cairo_region_translate (fallback_region,
-				-extents->x,
-				-extents->y);
-	clip_region = fallback_region;
-    }
+    clip_region = _cairo_clip_get_region (clip);
+    if (clip_region && (extents->x | extents->y))
+	cairo_region_translate (clip_region, -extents->x, -extents->y);
 
     status = draw_func (draw_closure, CAIRO_OPERATOR_ADD,
 			&_cairo_pattern_white.base, mask,
 			extents->x, extents->y,
 			extents,
 			clip_region);
+
+    if (clip_region && (extents->x | extents->y))
+	cairo_region_translate (clip_region, extents->x, extents->y);
+
     if (unlikely (status))
-	goto CLEANUP_SURFACE;
+	goto CLEANUP;
+
+    if (clip) {
+	for (i = 0; i < clip->num_boxes; i++) {
+	    cairo_box_t *b = &clip->boxes[i];
+
+	    if (! _cairo_fixed_is_integer (b->p1.x) ||
+		! _cairo_fixed_is_integer (b->p1.y) ||
+		! _cairo_fixed_is_integer (b->p2.x) ||
+		! _cairo_fixed_is_integer (b->p2.y))
+	    {
+		do_unaligned_box(blt_in, mask, b, extents->x, extents->y);
+	    }
+	}
 
-    if (clip_surface)
-	status = _cairo_clip_combine_with_surface (clip, mask, extents->x, extents->y);
+	if (clip->path != NULL) {
+	    status = _cairo_clip_combine_with_surface (clip, mask,
+						       extents->x, extents->y);
+	    if (unlikely (status))
+		goto CLEANUP;
+	}
+    }
 
     _cairo_pattern_init_for_surface (mask_pattern, mask);
 
- CLEANUP_SURFACE:
-    if (fallback_region)
-        cairo_region_destroy (fallback_region);
+ CLEANUP:
     cairo_surface_destroy (mask);
 
     return status;


More information about the cairo-commit mailing list