diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-01-07 13:11:06 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-01-07 17:58:02 +0000 |
commit | 5f2e89660d5e38d8e2682945962521958f150825 (patch) | |
tree | 4408a8ebf1f54b879b29ff15d0de8df1365b769b | |
parent | a73e7ff0186176bc82cd3ae1432c054c1fd3aebd (diff) | |
download | cairo-5f2e89660d5e38d8e2682945962521958f150825.tar.gz |
image: Call pixman without a mask for opaque regions of inplace_spans
Speedups
========
firefox-paintball 59462.09 -> 40928.76: 1.45x speedup
firefox-fishtank 43687.33 -> 34627.78: 1.26x speedup
firefox-tron 52526.00 -> 45754.73: 1.15x speedup
However in order to avoid a regression with firefox-talos-svg we need to
prevent splitting up the scanline when using a gradient source.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/cairo-image-compositor.c | 57 |
1 files changed, 47 insertions, 10 deletions
diff --git a/src/cairo-image-compositor.c b/src/cairo-image-compositor.c index 728f4a13f..460c9b593 100644 --- a/src/cairo-image-compositor.c +++ b/src/cairo-image-compositor.c @@ -1538,6 +1538,7 @@ typedef struct _cairo_image_span_renderer { pixman_image_t *dst; int src_x, src_y; int mask_x, mask_y; + int run_length; } composite; struct finish { cairo_rectangle_int_t extents; @@ -2417,24 +2418,56 @@ _inplace_spans (void *abstract_renderer, } mask = (uint8_t *)pixman_image_get_data (r->mask); - x0 = spans[0].x; + x1 = x0 = spans[0].x; do { int len = spans[1].x - spans[0].x; *mask++ = spans[0].coverage; if (len > 1) { - memset (mask, spans[0].coverage, --len); - mask += len; + if (len >= r->u.composite.run_length && spans[0].coverage == 0xff) { + if (x1 != x0) { + pixman_image_composite32 (r->op, r->src, r->mask, r->u.composite.dst, + x0 + r->u.composite.src_x, + y + r->u.composite.src_y, + 0, 0, + x0, y, + x1 - x0, h); + } + pixman_image_composite32 (r->op, r->src, NULL, r->u.composite.dst, + spans[0].x + r->u.composite.src_x, + y + r->u.composite.src_y, + 0, 0, + spans[0].x, y, + len, h); + mask = (uint8_t *)pixman_image_get_data (r->mask); + x0 = spans[1].x; + } else if (spans[0].coverage == 0x0) { + if (x1 != x0) { + pixman_image_composite32 (r->op, r->src, r->mask, r->u.composite.dst, + x0 + r->u.composite.src_x, + y + r->u.composite.src_y, + 0, 0, + x0, y, + x1 - x0, h); + } + mask = (uint8_t *)pixman_image_get_data (r->mask); + x0 = spans[1].x; + }else { + memset (mask, spans[0].coverage, --len); + mask += len; + } } x1 = spans[1].x; spans++; } while (--num_spans > 1); - pixman_image_composite32 (r->op, r->src, r->mask, r->u.composite.dst, - x0 + r->u.composite.src_x, - y + r->u.composite.src_y, - 0, 0, - x0, y, - x1 - x0, h); + if (x1 != x0) { + pixman_image_composite32 (r->op, r->src, r->mask, r->u.composite.dst, + x0 + r->u.composite.src_x, + y + r->u.composite.src_y, + 0, 0, + x0, y, + x1 - x0, h); + } return CAIRO_STATUS_SUCCESS; } @@ -2456,7 +2489,7 @@ _inplace_src_spans (void *abstract_renderer, m = r->buf; do { int len = spans[1].x - spans[0].x; - if (spans[0].coverage == 0xff) { + if (len >= r->u.composite.run_length && spans[0].coverage == 0xff) { if (spans[0].x != x0) { #if PIXMAN_HAS_OP_LERP pixman_image_composite32 (PIXMAN_OP_LERP_SRC, @@ -2661,6 +2694,10 @@ inplace_renderer_init (cairo_image_span_renderer_t *r, width = (composite->bounded.width + 3) & ~3; r->base.render_rows = _inplace_spans; + r->u.composite.run_length = 8; + if (src->type == CAIRO_PATTERN_TYPE_LINEAR || + src->type == CAIRO_PATTERN_TYPE_RADIAL) + r->u.composite.run_length = 256; if (dst->base.is_clear && (composite->op == CAIRO_OPERATOR_SOURCE || composite->op == CAIRO_OPERATOR_OVER || |