[cairo-commit] 4 commits - src/cairo-spans-compositor.c src/cairo-traps-compositor.c test/reference
Chris Wilson
ickle at kemper.freedesktop.org
Fri May 11 13:33:38 PDT 2012
src/cairo-spans-compositor.c | 113 +++++++++++++++++----
src/cairo-traps-compositor.c | 2
test/reference/tighten-bounds.argb32.ref.png |binary
test/reference/tighten-bounds.rgb24.ref.png |binary
test/reference/tighten-bounds.traps.argb32.ref.png |binary
test/reference/tighten-bounds.traps.rgb24.ref.png |binary
6 files changed, 95 insertions(+), 20 deletions(-)
New commits:
commit cd1004ce19c7ea28c7fedb6464562a08416586c0
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri May 11 21:20:35 2012 +0100
traps,spans-compositor: Avoid mistreating unaligned clips as aligned
An unaligned clip requires careful handling, and so exclude processing
along the fast paths.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/cairo-spans-compositor.c b/src/cairo-spans-compositor.c
index 2e2f4f4..a60cff4 100644
--- a/src/cairo-spans-compositor.c
+++ b/src/cairo-spans-compositor.c
@@ -519,6 +519,26 @@ upload_boxes (const cairo_spans_compositor_t *compositor,
return status;
}
+static cairo_bool_t
+_clip_is_region (const cairo_clip_t *clip)
+{
+ int i;
+
+ if (clip->is_region)
+ return TRUE;
+
+ if (clip->path)
+ return FALSE;
+
+ for (i = 0; i < clip->num_boxes; i++) {
+ const cairo_box_t *b = &clip->boxes[i];
+ if (!_cairo_fixed_is_integer (b->p1.x | b->p1.y | b->p2.x | b->p2.y))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
static cairo_int_status_t
composite_aligned_boxes (const cairo_spans_compositor_t *compositor,
const cairo_composite_rectangles_t *extents,
@@ -528,7 +548,7 @@ composite_aligned_boxes (const cairo_spans_compositor_t *compositor,
cairo_operator_t op = extents->op;
const cairo_pattern_t *source = &extents->source_pattern.base;
cairo_int_status_t status;
- cairo_bool_t need_clip_mask = extents->clip->path != NULL;
+ cairo_bool_t need_clip_mask = ! _clip_is_region (extents->clip);
cairo_bool_t op_is_source;
cairo_bool_t no_mask;
cairo_bool_t inplace;
@@ -716,7 +736,7 @@ composite_polygon (const cairo_spans_compositor_t *compositor,
cairo_bool_t needs_clip;
cairo_int_status_t status;
- needs_clip = extents->clip->path != NULL || extents->clip->num_boxes > 1;
+ needs_clip = extents->clip->num_boxes > 1 || ! _clip_is_region (extents->clip);
TRACE ((stderr, "%s - needs_clip=%d\n", __FUNCTION__, needs_clip));
if (needs_clip) {
return CAIRO_INT_STATUS_UNSUPPORTED;
diff --git a/src/cairo-traps-compositor.c b/src/cairo-traps-compositor.c
index f8308ad..eeee20c 100644
--- a/src/cairo-traps-compositor.c
+++ b/src/cairo-traps-compositor.c
@@ -1178,7 +1178,7 @@ composite_aligned_boxes (const cairo_traps_compositor_t *compositor,
{
cairo_surface_t *dst = extents->surface;
cairo_operator_t op = extents->op;
- cairo_bool_t need_clip_mask = extents->clip->path != NULL;
+ cairo_bool_t need_clip_mask = ! _cairo_clip_is_region (extents->clip);
cairo_bool_t op_is_source;
cairo_status_t status;
commit de1150cc0e1cb11710b196806335817255cb4abe
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri May 11 20:51:58 2012 +0100
spans-compositor: Add tracepoints for debugging
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/cairo-spans-compositor.c b/src/cairo-spans-compositor.c
index 38a2d97..2e2f4f4 100644
--- a/src/cairo-spans-compositor.c
+++ b/src/cairo-spans-compositor.c
@@ -245,6 +245,8 @@ fixup_unbounded_mask (const cairo_spans_compositor_t *compositor,
cairo_surface_t *clip;
cairo_int_status_t status;
+ TRACE((stderr, "%s\n", __FUNCTION__));
+
clip = get_clip_surface (compositor, extents->surface, extents->clip,
&extents->unbounded);
if (unlikely (clip->status)) {
@@ -288,6 +290,8 @@ fixup_unbounded_polygon (const cairo_spans_compositor_t *compositor,
cairo_antialias_t antialias;
cairo_int_status_t status;
+ TRACE((stderr, "%s\n", __FUNCTION__));
+
/* Can we treat the clip as a regular clear-polygon and use it to fill? */
status = _cairo_clip_get_polygon (extents->clip, &polygon,
&fill_rule, &antialias);
@@ -712,8 +716,8 @@ composite_polygon (const cairo_spans_compositor_t *compositor,
cairo_bool_t needs_clip;
cairo_int_status_t status;
- TRACE ((stderr, "%s\n", __FUNCTION__));
needs_clip = extents->clip->path != NULL || extents->clip->num_boxes > 1;
+ TRACE ((stderr, "%s - needs_clip=%d\n", __FUNCTION__, needs_clip));
if (needs_clip) {
return CAIRO_INT_STATUS_UNSUPPORTED;
converter = _cairo_clip_tor_scan_converter_create (extents->clip,
@@ -882,6 +886,9 @@ clip_and_composite_polygon (const cairo_spans_compositor_t *compositor,
cairo_antialias_t clip_antialias;
cairo_fill_rule_t clip_fill_rule;
+ TRACE((stderr, "%s - combining shape with clip polygon\n",
+ __FUNCTION__));
+
status = _cairo_clip_get_polygon (extents->clip,
&clipper,
&clip_fill_rule,
@@ -1042,10 +1049,14 @@ _cairo_spans_compositor_fill (const cairo_compositor_t *_compositor,
const cairo_spans_compositor_t *compositor = (cairo_spans_compositor_t*)_compositor;
cairo_int_status_t status;
+ TRACE((stderr, "%s op=%d, antialias=%d\n", __FUNCTION__, extents->op, antialias));
+
status = CAIRO_INT_STATUS_UNSUPPORTED;
if (_cairo_path_fixed_fill_is_rectilinear (path)) {
cairo_boxes_t boxes;
+ TRACE((stderr, "%s - rectilinear\n", __FUNCTION__));
+
_cairo_boxes_init (&boxes);
if (! _cairo_clip_contains_rectangle (extents->clip, &extents->mask))
_cairo_boxes_limit (&boxes,
@@ -1062,10 +1073,13 @@ _cairo_spans_compositor_fill (const cairo_compositor_t *_compositor,
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
cairo_polygon_t polygon;
+ TRACE((stderr, "%s - polygon\n", __FUNCTION__));
+
if (extents->mask.width > extents->unbounded.width ||
extents->mask.height > extents->unbounded.height)
{
cairo_box_t limits;
+ TRACE((stderr, "%s - clipping to bounds\n", __FUNCTION__));
_cairo_box_from_rectangle (&limits, &extents->unbounded);
_cairo_polygon_init (&polygon, &limits, 1);
}
@@ -1076,6 +1090,8 @@ _cairo_spans_compositor_fill (const cairo_compositor_t *_compositor,
status = _cairo_path_fixed_fill_to_polygon (path, tolerance, &polygon);
if (status == CAIRO_INT_STATUS_SUCCESS && extents->clip->num_boxes > 1) {
+ TRACE((stderr, "%s - polygon intersect with %d clip boxes\n",
+ __FUNCTION__, extents->clip->num_boxes));
status = _cairo_polygon_intersect_with_boxes (&polygon, &fill_rule,
extents->clip->boxes,
extents->clip->num_boxes);
@@ -1084,6 +1100,8 @@ _cairo_spans_compositor_fill (const cairo_compositor_t *_compositor,
cairo_clip_t *saved_clip = extents->clip;
if (extents->is_bounded) {
+ TRACE((stderr, "%s - polygon discard clip boxes\n",
+ __FUNCTION__));
extents->clip = _cairo_clip_copy_path (extents->clip);
extents->clip = _cairo_clip_intersect_box(extents->clip,
&polygon.extents);
@@ -1098,6 +1116,8 @@ _cairo_spans_compositor_fill (const cairo_compositor_t *_compositor,
}
}
_cairo_polygon_fini (&polygon);
+
+ TRACE((stderr, "%s - polygon status=%d\n", __FUNCTION__, status));
}
return status;
commit 197e5b7324c569d3e8cd652dbf5a281a57317cbe
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri May 11 20:25:29 2012 +0100
spans-compositor: Handle unaligned unbounded boxes
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/cairo-spans-compositor.c b/src/cairo-spans-compositor.c
index 357c0ea..38a2d97 100644
--- a/src/cairo-spans-compositor.c
+++ b/src/cairo-spans-compositor.c
@@ -111,11 +111,31 @@ get_clip_surface (const cairo_spans_compositor_t *compositor,
if (unlikely (status))
goto cleanup_polygon;
+ antialias = clip_path->antialias;
+ fill_rule = clip_path->fill_rule;
+
+ if (clip->boxes) {
+ cairo_polygon_t intersect;
+ cairo_boxes_t tmp;
+
+ _cairo_boxes_init_for_array (&tmp, clip->boxes, clip->num_boxes);
+ status= _cairo_polygon_init_boxes (&intersect, &tmp);
+ if (unlikely (status))
+ goto cleanup_polygon;
+
+ status = _cairo_polygon_intersect (&polygon, fill_rule,
+ &intersect, CAIRO_FILL_RULE_WINDING);
+ _cairo_polygon_fini (&intersect);
+
+ if (unlikely (status))
+ goto cleanup_polygon;
+
+ fill_rule = CAIRO_FILL_RULE_WINDING;
+ }
+
polygon.limits = NULL;
polygon.num_limits = 0;
- antialias = clip_path->antialias;
- fill_rule = clip_path->fill_rule;
clip_path = clip_path->prev;
while (clip_path) {
if (clip_path->antialias == antialias) {
@@ -353,26 +373,41 @@ fixup_unbounded_boxes (const cairo_spans_compositor_t *compositor,
assert (status == CAIRO_INT_STATUS_SUCCESS);
}
- /* Now intersect with the clip boxes */
- if (extents->clip->num_boxes) {
- _cairo_boxes_init_for_array (&tmp,
- extents->clip->boxes,
- extents->clip->num_boxes);
- status = _cairo_boxes_intersect (&clear, &tmp, &clear);
- if (unlikely (status))
- goto error;
- }
-
/* If we have a clip polygon, we need to intersect with that as well */
if (extents->clip->path) {
status = fixup_unbounded_polygon (compositor, extents, &clear);
if (status == CAIRO_INT_STATUS_UNSUPPORTED)
status = fixup_unbounded_mask (compositor, extents, &clear);
} else {
- status = compositor->fill_boxes (extents->surface,
- CAIRO_OPERATOR_CLEAR,
- CAIRO_COLOR_TRANSPARENT,
- &clear);
+ /* Otherwise just intersect with the clip boxes */
+ if (extents->clip->num_boxes) {
+ _cairo_boxes_init_for_array (&tmp,
+ extents->clip->boxes,
+ extents->clip->num_boxes);
+ status = _cairo_boxes_intersect (&clear, &tmp, &clear);
+ if (unlikely (status))
+ goto error;
+ }
+
+ if (clear.is_pixel_aligned) {
+ status = compositor->fill_boxes (extents->surface,
+ CAIRO_OPERATOR_CLEAR,
+ CAIRO_COLOR_TRANSPARENT,
+ &clear);
+ } else {
+ cairo_composite_rectangles_t composite;
+
+ status = _cairo_composite_rectangles_init_for_boxes (&composite,
+ extents->surface,
+ CAIRO_OPERATOR_CLEAR,
+ &_cairo_pattern_clear.base,
+ &clear,
+ NULL);
+ if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
+ status = composite_boxes (compositor, &composite, &clear);
+ _cairo_composite_rectangles_fini (&composite);
+ }
+ }
}
error:
commit 2d26f7da777b7ac01e5c469e52a17fa7d0cf4a8d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri May 11 21:26:33 2012 +0100
test: Fix tighten-bounds reference images
Uli Schlachter spotted that I had inadvertently committed (606e9e1c9) a
broken set of test images for the tighten-bounds case and so masked a
nasty bug with the mishandling of unaligned clips.
Reported-by: Uli Schlachter <psychon at znc.in>
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/test/reference/tighten-bounds.argb32.ref.png b/test/reference/tighten-bounds.argb32.ref.png
index e348018..6634ed1 100644
Binary files a/test/reference/tighten-bounds.argb32.ref.png and b/test/reference/tighten-bounds.argb32.ref.png differ
diff --git a/test/reference/tighten-bounds.rgb24.ref.png b/test/reference/tighten-bounds.rgb24.ref.png
index 28e3c1b..d15bddd 100644
Binary files a/test/reference/tighten-bounds.rgb24.ref.png and b/test/reference/tighten-bounds.rgb24.ref.png differ
diff --git a/test/reference/tighten-bounds.traps.argb32.ref.png b/test/reference/tighten-bounds.traps.argb32.ref.png
index 9d22568..291a841 100644
Binary files a/test/reference/tighten-bounds.traps.argb32.ref.png and b/test/reference/tighten-bounds.traps.argb32.ref.png differ
diff --git a/test/reference/tighten-bounds.traps.rgb24.ref.png b/test/reference/tighten-bounds.traps.rgb24.ref.png
index 98fc412..f31c17c 100644
Binary files a/test/reference/tighten-bounds.traps.rgb24.ref.png and b/test/reference/tighten-bounds.traps.rgb24.ref.png differ
More information about the cairo-commit
mailing list