summaryrefslogtreecommitdiff
path: root/src/cairo-image-compositor.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-10-02 09:16:04 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2014-10-02 09:16:04 +0100
commit7f7ed4c04e49b64c15d60889a8cdc4075efd8236 (patch)
tree9128ed6a36c47f23c001008ce071f1020b84b940 /src/cairo-image-compositor.c
parent7aacd81befc5ad1aec26bcf7e65fa5bd36c6a9b4 (diff)
downloadcairo-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/cairo-image-compositor.c')
-rw-r--r--src/cairo-image-compositor.c32
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 ||