[cairo-commit] 2 commits - src/cairo-composite-rectangles.c src/cairo-gl-spans-compositor.c src/cairo-image-compositor.c src/cairo-spans-compositor.c src/cairo-spans-compositor-private.h src/test-null-compositor-surface.c

Chris Wilson ickle at kemper.freedesktop.org
Sun Mar 4 07:40:03 PST 2012


 src/cairo-composite-rectangles.c     |    1 
 src/cairo-gl-spans-compositor.c      |    1 
 src/cairo-image-compositor.c         |  210 ++++++++++++++++++++++++++++++++++-
 src/cairo-spans-compositor-private.h |    1 
 src/cairo-spans-compositor.c         |    6 -
 src/test-null-compositor-surface.c   |    3 
 6 files changed, 216 insertions(+), 6 deletions(-)

New commits:
commit 61cb5539fa81bc543781b8a3a8f1b7a2d5df9f35
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Mar 4 15:07:24 2012 +0000

    image: Add a fast path for solid-filled polygons
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-composite-rectangles.c b/src/cairo-composite-rectangles.c
index 7fc0f5f..106571e 100644
--- a/src/cairo-composite-rectangles.c
+++ b/src/cairo-composite-rectangles.c
@@ -105,6 +105,7 @@ _cairo_composite_rectangles_init (cairo_composite_rectangles_t *extents,
     extents->original_mask_pattern = NULL;
     extents->mask_pattern.base.type = CAIRO_PATTERN_TYPE_SOLID;
     extents->mask_pattern.solid.color.alpha = 1.; /* XXX full initialisation? */
+    extents->mask_pattern.solid.color.alpha_short = 0xffff;
 
     return TRUE;
 }
diff --git a/src/cairo-image-compositor.c b/src/cairo-image-compositor.c
index 40f9def..4507597 100644
--- a/src/cairo-image-compositor.c
+++ b/src/cairo-image-compositor.c
@@ -1335,11 +1335,13 @@ typedef struct _cairo_image_span_renderer {
 
     float opacity;
     int stride;
+    int bpp;
     uint8_t *data;
 
     const cairo_composite_rectangles_t *composite;
     pixman_image_t *src, *mask;
     int src_x, src_y;
+    uint32_t pixel;
 
     uint8_t op;
 
@@ -1451,6 +1453,198 @@ _cairo_image_finish_spans_and_zero (void *abstract_renderer)
     return CAIRO_STATUS_SUCCESS;
 }
 
+static cairo_status_t
+_fill8_spans (void *abstract_renderer, int y, int h,
+	       const cairo_half_open_span_t *spans, unsigned num_spans)
+{
+    cairo_image_span_renderer_t *r = abstract_renderer;
+
+    if (num_spans == 0)
+	return CAIRO_STATUS_SUCCESS;
+
+    if (likely(h == 1)) {
+	do {
+	    if (spans[0].coverage) {
+		int len = spans[1].x - spans[0].x;
+		uint8_t *d = r->data + r->stride*y + spans[0].x;
+		while (len--)
+		    *d++ = r->pixel;
+	    }
+	    spans++;
+	} while (--num_spans > 1);
+    } else {
+	do {
+	    if (spans[0].coverage) {
+		int yy = y, hh = h;
+		do {
+		    int len = spans[1].x - spans[0].x;
+		    uint8_t *d = r->data + r->stride*yy + spans[0].x;
+		    while (len--)
+			*d++ = r->pixel;
+		    yy++;
+		} while (--hh);
+	    }
+	    spans++;
+	} while (--num_spans > 1);
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+_fill16_spans (void *abstract_renderer, int y, int h,
+	       const cairo_half_open_span_t *spans, unsigned num_spans)
+{
+    cairo_image_span_renderer_t *r = abstract_renderer;
+
+    if (num_spans == 0)
+	return CAIRO_STATUS_SUCCESS;
+
+    if (likely(h == 1)) {
+	do {
+	    if (spans[0].coverage) {
+		int len = spans[1].x - spans[0].x;
+		uint16_t *d = (uint16_t*)(r->data + r->stride*y + spans[0].x*2);
+		while (len--)
+		    *d++ = r->pixel;
+	    }
+	    spans++;
+	} while (--num_spans > 1);
+    } else {
+	do {
+	    if (spans[0].coverage) {
+		int yy = y, hh = h;
+		do {
+		    int len = spans[1].x - spans[0].x;
+		    uint16_t *d = (uint16_t*)(r->data + r->stride*yy + spans[0].x*2);
+		    while (len--)
+			*d++ = r->pixel;
+		    yy++;
+		} while (--hh);
+	    }
+	    spans++;
+	} while (--num_spans > 1);
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+_fill32_spans (void *abstract_renderer, int y, int h,
+	       const cairo_half_open_span_t *spans, unsigned num_spans)
+{
+    cairo_image_span_renderer_t *r = abstract_renderer;
+
+    if (num_spans == 0)
+	return CAIRO_STATUS_SUCCESS;
+
+    if (likely(h == 1)) {
+	do {
+	    if (spans[0].coverage) {
+		int len = spans[1].x - spans[0].x;
+		if (len > 32) {
+		    pixman_fill ((uint32_t *) r->data, r->stride / sizeof(uint32_t), r->bpp,
+				 spans[0].x, y, len, 1, r->pixel);
+		} else {
+		    uint32_t *d = (uint32_t*)(r->data + r->stride*y + spans[0].x*4);
+		    while (len--)
+			*d++ = r->pixel;
+		}
+	    }
+	    spans++;
+	} while (--num_spans > 1);
+    } else {
+	do {
+	    if (spans[0].coverage) {
+		if (spans[1].x - spans[0].x > 16) {
+		    pixman_fill ((uint32_t *) r->data, r->stride / sizeof(uint32_t), r->bpp,
+				 spans[0].x, y, spans[1].x - spans[0].x, h,
+				 r->pixel);
+		} else {
+		    int yy = y, hh = h;
+		    do {
+			int len = spans[1].x - spans[0].x;
+			uint32_t *d = (uint32_t*)(r->data + r->stride*yy + spans[0].x*4);
+			while (len--)
+			    *d++ = r->pixel;
+			yy++;
+		    } while (--hh);
+		}
+	    }
+	    spans++;
+	} while (--num_spans > 1);
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+#if 0
+static cairo_status_t
+_fill_spans (void *abstract_renderer, int y, int h,
+	     const cairo_half_open_span_t *spans, unsigned num_spans)
+{
+    cairo_image_span_renderer_t *r = abstract_renderer;
+
+    if (num_spans == 0)
+	return CAIRO_STATUS_SUCCESS;
+
+    do {
+	if (spans[0].coverage) {
+		pixman_fill ((uint32_t *) r->data, r->stride, r->bpp,
+			     spans[0].x, y,
+			     spans[1].x - spans[0].x, h,
+			     r->pixel);
+	}
+	spans++;
+    } while (--num_spans > 1);
+
+    return CAIRO_STATUS_SUCCESS;
+}
+#endif
+
+static cairo_int_status_t
+mono_renderer_init (cairo_image_span_renderer_t	*r,
+		    const cairo_composite_rectangles_t *composite,
+		    cairo_antialias_t			 antialias,
+		    cairo_bool_t			 needs_clip)
+{
+    cairo_image_surface_t *dst = (cairo_image_surface_t *)composite->surface;
+    const cairo_color_t	*color;
+
+    if (antialias != CAIRO_ANTIALIAS_NONE)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    if (composite->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    if (!_cairo_pattern_is_opaque_solid (&composite->mask_pattern.base))
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    color = &composite->source_pattern.solid.color;
+    if (!fill_reduces_to_source (composite->op, color, dst))
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    if (!color_to_pixel (color, dst->pixman_format, &r->pixel))
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    r->data = dst->data;
+    r->stride = dst->stride;
+    r->bpp = PIXMAN_FORMAT_BPP(dst->pixman_format);
+
+    /* Use plain C for the fill operations as the span length is typically
+     * small, too small to payback the startup overheads of using SSE2 etc.
+     */
+    switch (r->bpp) {
+    case 8: r->base.render_rows = _fill8_spans; break;
+    case 16: r->base.render_rows = _fill16_spans; break;
+    case 32: r->base.render_rows = _fill32_spans; break;
+    default: return CAIRO_INT_STATUS_UNSUPPORTED;
+    }
+    r->base.finish = NULL;
+
+    return CAIRO_INT_STATUS_SUCCESS;
+}
+
 static cairo_int_status_t
 span_renderer_init (cairo_abstract_span_renderer_t	*_r,
 		    const cairo_composite_rectangles_t *composite,
@@ -1461,15 +1655,21 @@ span_renderer_init (cairo_abstract_span_renderer_t	*_r,
     cairo_image_surface_t *dst = (cairo_image_surface_t *)composite->surface;
     const cairo_pattern_t *source = &composite->source_pattern.base;
     cairo_operator_t op = composite->op;
+    cairo_int_status_t status;
 
     TRACE ((stderr, "%s\n", __FUNCTION__));
 
+    if (needs_clip)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    status = mono_renderer_init (r, composite, antialias, needs_clip);
+    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
+	return status;
+
     r->composite = composite;
     r->mask = NULL;
     r->src = NULL;
-
-    if (needs_clip)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
+    r->bpp = 0;
 
     if (op == CAIRO_OPERATOR_CLEAR) {
 #if PIXMAN_HAS_OP_LERP
@@ -1571,6 +1771,9 @@ span_renderer_fini (cairo_abstract_span_renderer_t *_r,
 
     TRACE ((stderr, "%s\n", __FUNCTION__));
 
+    if (r->bpp)
+	return;
+
     if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
 	const cairo_composite_rectangles_t *composite = r->composite;
 
commit b55e7c776fadb3e730b2a5970736a2f84a1fefdc
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Mar 4 14:15:22 2012 +0000

    spans: Pass antialiasing hint down to the backends
    
    The actual span rasterisers may be able to specialise if they know that
    the spans will be pixel aligned.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-gl-spans-compositor.c b/src/cairo-gl-spans-compositor.c
index 0e31ea9..81de3c4 100644
--- a/src/cairo-gl-spans-compositor.c
+++ b/src/cairo-gl-spans-compositor.c
@@ -328,6 +328,7 @@ FAIL:
 static cairo_int_status_t
 _cairo_gl_span_renderer_init (cairo_abstract_span_renderer_t	*_r,
 			      const cairo_composite_rectangles_t *composite,
+			      cairo_antialias_t			 antialias,
 			      cairo_bool_t			 needs_clip)
 {
     cairo_gl_span_renderer_t *r = (cairo_gl_span_renderer_t *)_r;
diff --git a/src/cairo-image-compositor.c b/src/cairo-image-compositor.c
index 83b0cf3..40f9def 100644
--- a/src/cairo-image-compositor.c
+++ b/src/cairo-image-compositor.c
@@ -1454,6 +1454,7 @@ _cairo_image_finish_spans_and_zero (void *abstract_renderer)
 static cairo_int_status_t
 span_renderer_init (cairo_abstract_span_renderer_t	*_r,
 		    const cairo_composite_rectangles_t *composite,
+		    cairo_antialias_t			 antialias,
 		    cairo_bool_t			 needs_clip)
 {
     cairo_image_span_renderer_t *r = (cairo_image_span_renderer_t *)_r;
diff --git a/src/cairo-spans-compositor-private.h b/src/cairo-spans-compositor-private.h
index cab09f6..74a412d 100644
--- a/src/cairo-spans-compositor-private.h
+++ b/src/cairo-spans-compositor-private.h
@@ -84,6 +84,7 @@ struct cairo_spans_compositor {
     /* general shape masks using a span renderer */
     cairo_int_status_t (*renderer_init) (cairo_abstract_span_renderer_t *renderer,
 					 const cairo_composite_rectangles_t *extents,
+					 cairo_antialias_t antialias,
 					 cairo_bool_t	 needs_clip);
 
     void (*renderer_fini) (cairo_abstract_span_renderer_t *renderer,
diff --git a/src/cairo-spans-compositor.c b/src/cairo-spans-compositor.c
index 3b5604e..d55827b 100644
--- a/src/cairo-spans-compositor.c
+++ b/src/cairo-spans-compositor.c
@@ -605,7 +605,8 @@ composite_boxes (const cairo_spans_compositor_t *compositor,
 	}
     }
 
-    status = compositor->renderer_init (&renderer, extents, FALSE);
+    status = compositor->renderer_init (&renderer, extents,
+					CAIRO_ANTIALIAS_DEFAULT, FALSE);
     if (likely (status == CAIRO_INT_STATUS_SUCCESS))
 	status = converter.base.generate (&converter.base, &renderer.base);
     compositor->renderer_fini (&renderer, status);
@@ -660,7 +661,8 @@ composite_polygon (const cairo_spans_compositor_t	*compositor,
     if (unlikely (status))
 	goto cleanup_converter;
 
-    status = compositor->renderer_init (&renderer, extents, needs_clip);
+    status = compositor->renderer_init (&renderer, extents,
+					antialias, needs_clip);
     if (likely (status == CAIRO_INT_STATUS_SUCCESS))
 	status = converter->generate (converter, &renderer.base);
     compositor->renderer_fini (&renderer, status);
diff --git a/src/test-null-compositor-surface.c b/src/test-null-compositor-surface.c
index 9516155..2301055 100644
--- a/src/test-null-compositor-surface.c
+++ b/src/test-null-compositor-surface.c
@@ -373,7 +373,8 @@ finish_spans (void *abstract_renderer)
 static cairo_int_status_t
 span_renderer_init (cairo_abstract_span_renderer_t	*_r,
 		    const cairo_composite_rectangles_t *composite,
-		    cairo_bool_t			 needs_clip)
+		    cairo_antialias_t			antialias,
+		    cairo_bool_t			needs_clip)
 {
     cairo_span_renderer_t *r = (cairo_span_renderer_t *)_r;
     r->render_rows = spans;


More information about the cairo-commit mailing list