summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-01-07 13:11:06 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2013-01-07 17:58:02 +0000
commit5f2e89660d5e38d8e2682945962521958f150825 (patch)
tree4408a8ebf1f54b879b29ff15d0de8df1365b769b
parenta73e7ff0186176bc82cd3ae1432c054c1fd3aebd (diff)
downloadcairo-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.c57
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 ||