summaryrefslogtreecommitdiff
path: root/src/cairo-image-surface.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-07-29 23:06:48 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2011-07-31 08:12:54 +0100
commit5e223c1c73a7c3af550987a30246e7f1761808f5 (patch)
tree312be95dc0242b6dedf7412657d0bce366282fa8 /src/cairo-image-surface.c
parent7ca1d87645930a2f5e4be36819859928f4e6e601 (diff)
downloadcairo-5e223c1c73a7c3af550987a30246e7f1761808f5.tar.gz
image: Reduce compositing bounded boxes with a clip-mask to a polygon
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/cairo-image-surface.c')
-rw-r--r--src/cairo-image-surface.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index dc0320aba..fd2ec824e 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -3163,6 +3163,15 @@ _composite_boxes (cairo_image_surface_t *dst,
}
static cairo_status_t
+_clip_and_composite_polygon (cairo_image_surface_t *dst,
+ cairo_operator_t op,
+ const cairo_pattern_t *src,
+ cairo_polygon_t *polygon,
+ cairo_fill_rule_t fill_rule,
+ cairo_antialias_t antialias,
+ cairo_composite_rectangles_t *extents);
+
+static cairo_status_t
_clip_and_composite_boxes (cairo_image_surface_t *dst,
cairo_operator_t op,
const cairo_pattern_t *src,
@@ -3176,6 +3185,39 @@ _clip_and_composite_boxes (cairo_image_surface_t *dst,
if (boxes->num_boxes == 0 && extents->is_bounded)
return CAIRO_STATUS_SUCCESS;
+ /* Can we reduce drawing through a clip-mask to simply drawing the clip? */
+ if (extents->clip->path != NULL && extents->is_bounded) {
+ cairo_polygon_t polygon;
+ cairo_fill_rule_t fill_rule;
+ cairo_antialias_t antialias;
+ cairo_clip_t *clip;
+
+ clip = _cairo_clip_copy (extents->clip);
+ clip = _cairo_clip_intersect_boxes (clip, boxes);
+ status = _cairo_clip_get_polygon (clip, &polygon,
+ &fill_rule, &antialias);
+ _cairo_clip_path_destroy (clip->path);
+ clip->path = NULL;
+ if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
+ cairo_clip_t *saved_clip = extents->clip;
+ extents->clip = clip;
+ status = _clip_and_composite_polygon (dst, op, src,
+ &polygon,
+ fill_rule,
+ antialias,
+ extents);
+ if (extents->clip != clip)
+ clip = NULL;
+ extents->clip = saved_clip;
+ _cairo_polygon_fini (&polygon);
+ }
+ if (clip)
+ _cairo_clip_destroy (clip);
+
+ if (status != CAIRO_INT_STATUS_UNSUPPORTED)
+ return status;
+ }
+
/* Use a fast path if the boxes are pixel aligned */
status = _composite_boxes (dst, op, src, boxes, extents);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)