diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2014-10-02 09:16:04 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2014-10-02 09:16:04 +0100 |
commit | 7f7ed4c04e49b64c15d60889a8cdc4075efd8236 (patch) | |
tree | 9128ed6a36c47f23c001008ce071f1020b84b940 /src | |
parent | 7aacd81befc5ad1aec26bcf7e65fa5bd36c6a9b4 (diff) | |
download | cairo-7f7ed4c04e49b64c15d60889a8cdc4075efd8236.tar.gz |
image: Eliminate self-intersections for the pixman traps compositor
As pixman uses an accumulation mask, it oversamples neighbouring edges
within a cell. We can reduce the impact of this by eliminating
overlapping triangles/trapezoids from being passed into pixman.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src')
-rw-r--r-- | src/cairo-image-compositor.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/src/cairo-image-compositor.c b/src/cairo-image-compositor.c index 51ffc34bb..6ff0f09c0 100644 --- a/src/cairo-image-compositor.c +++ b/src/cairo-image-compositor.c @@ -649,11 +649,18 @@ composite_traps (void *_dst, { cairo_image_surface_t *dst = (cairo_image_surface_t *) _dst; cairo_image_source_t *src = (cairo_image_source_t *) abstract_src; + cairo_int_status_t status; pixman_image_t *mask; pixman_format_code_t format; TRACE ((stderr, "%s\n", __FUNCTION__)); + /* pixman doesn't eliminate self-intersecting trapezoids/edges */ + status = _cairo_bentley_ottmann_tessellate_traps (traps, + CAIRO_FILL_RULE_WINDING); + if (status != CAIRO_INT_STATUS_SUCCESS) + return status; + /* Special case adding trapezoids onto a mask surface; we want to avoid * creating an intermediate temporary mask unnecessarily. * @@ -738,6 +745,31 @@ composite_tristrip (void *_dst, if (strip->num_points < 3) return CAIRO_STATUS_SUCCESS; + if (1) { /* pixman doesn't eliminate self-intersecting triangles/edges */ + cairo_int_status_t status; + cairo_traps_t traps; + int n; + + _cairo_traps_init (&traps); + for (n = 0; n < strip->num_points; n++) { + cairo_point_t p[4]; + + p[0] = strip->points[0]; + p[1] = strip->points[1]; + p[2] = strip->points[2]; + p[3] = strip->points[0]; + + _cairo_traps_tessellate_convex_quad (&traps, p); + } + status = composite_traps (_dst, op, abstract_src, + src_x, src_y, + dst_x, dst_y, + extents, antialias, &traps); + _cairo_traps_fini (&traps); + + return status; + } + format = antialias == CAIRO_ANTIALIAS_NONE ? PIXMAN_a1 : PIXMAN_a8; if (dst->pixman_format == format && (abstract_src == NULL || |