[cairo-commit] src/cairo-image-compositor.c
Chris Wilson
ickle at kemper.freedesktop.org
Mon Jan 7 10:03:46 PST 2013
src/cairo-image-compositor.c | 57 +++++++++++++++++++++++++++++++++++--------
1 file changed, 47 insertions(+), 10 deletions(-)
New commits:
commit 5f2e89660d5e38d8e2682945962521958f150825
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Jan 7 13:11:06 2013 +0000
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 at chris-wilson.co.uk>
diff --git a/src/cairo-image-compositor.c b/src/cairo-image-compositor.c
index 728f4a1..460c9b5 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 ||
More information about the cairo-commit
mailing list