[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