[cairo-commit] 3 commits - src/cairo-surface.c src/cairo-surface-fallback.c src/cairo-xlib-surface.c
Chris Wilson
ickle at kemper.freedesktop.org
Mon Sep 21 05:57:16 PDT 2009
src/cairo-surface-fallback.c | 42 ++++++++++++++++++++++++++++++++
src/cairo-surface.c | 23 +++++++----------
src/cairo-xlib-surface.c | 55 +++++++++++++++++++------------------------
3 files changed, 77 insertions(+), 43 deletions(-)
New commits:
commit e00d0627494a4b15ed3b74a704695ca8b81a350e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Sep 21 13:50:00 2009 +0100
[xlib] Fix recent bug in unbounded trapezoids
Gah! I had believed that the dst extents and the clip were correct to
enable unbounded fixup for the unbounded trapezoids. I was wrong, so I
need to requery the trapezoid extents. As this information is already
known, I should update the interface to pass along all relevant
information.
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 25ce0b9..d66e930 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -2631,7 +2631,7 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst,
/* Now compute the area that is in dst but not drawn */
status = cairo_region_subtract_rectangle (&clear_region, &dst_rectangle);
- if (unlikely (status))
+ if (unlikely (status) || cairo_region_is_empty (&clear_region))
goto CLEANUP_REGIONS;
EMPTY:
@@ -2767,9 +2767,8 @@ _cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t *dst,
unsigned int height,
cairo_region_t *clip_region)
{
- cairo_rectangle_int_t src_tmp, mask_tmp;
- cairo_rectangle_int_t *src_rectangle = NULL;
- cairo_rectangle_int_t *mask_rectangle = NULL;
+ cairo_rectangle_int_t src_tmp, *src= NULL;
+ cairo_rectangle_int_t mask;
if (dst->status)
return dst->status;
@@ -2784,20 +2783,18 @@ _cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t *dst,
{
src_tmp.x = (dst_x - (src_x + src_attr->x_offset));
src_tmp.y = (dst_y - (src_y + src_attr->y_offset));
- src_tmp.width = src_width;
+ src_tmp.width = src_width;
src_tmp.height = src_height;
- src_rectangle = &src_tmp;
+ src = &src_tmp;
}
- mask_tmp.x = dst_x - mask_x;
- mask_tmp.y = dst_y - mask_y;
- mask_tmp.width = mask_width;
- mask_tmp.height = mask_height;
+ mask.x = dst_x - mask_x;
+ mask.y = dst_y - mask_y;
+ mask.width = mask_width;
+ mask.height = mask_height;
- mask_rectangle = &mask_tmp;
-
- return _cairo_surface_composite_fixup_unbounded_internal (dst, src_rectangle, mask_rectangle,
+ return _cairo_surface_composite_fixup_unbounded_internal (dst, src, &mask,
dst_x, dst_y, width, height,
clip_region);
}
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 0352ed7..2b8d31a 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -2576,26 +2576,32 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t op,
xtraps, num_traps);
if (xtraps != xtraps_stack)
- free(xtraps);
+ free (xtraps);
+
+ if (! _cairo_operator_bounded_by_mask (op)) {
+ cairo_traps_t _traps;
+ cairo_box_t box;
+ cairo_rectangle_int_t extents;
- if (!_cairo_operator_bounded_by_mask (op)) {
/* XRenderCompositeTrapezoids() creates a mask only large enough for the
* trapezoids themselves, but if the operator is unbounded, then we need
- * to actually composite all the way out to the bounds, so we create
- * the mask and composite ourselves. There actually would
- * be benefit to doing this in all cases, since RENDER implementations
- * will frequently create a too temporary big mask, ignoring destination
- * bounds and clip. (XRenderAddTraps() could be used to make creating
- * the mask somewhat cheaper.)
+ * to actually composite all the way out to the bounds.
*/
+ /* XXX: update the interface to pass composite rects */
+ _traps.traps = traps;
+ _traps.num_traps = num_traps;
+ _cairo_traps_extents (&_traps, &box);
+ _cairo_box_round_to_rectangle (&box, &extents);
+
status = _cairo_surface_composite_shape_fixup_unbounded (&dst->base,
- &attributes, src->width, src->height,
- width, height,
+ &attributes,
+ src->width, src->height,
+ extents.width, extents.height,
src_x, src_y,
- 0, 0,
- dst_x, dst_y, width, height,
+ -extents.x + dst_x, -extents.y + dst_y,
+ dst_x, dst_y,
+ width, height,
clip_region);
-
}
BAIL:
commit 378b1e73d9f27e9b54ea01b10e588b361848d0cd
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Sep 21 03:10:53 2009 +0100
[fallback] Special case single composite rectangle
Avoid the overhead of region-from-traps extraction for the very frequent
case of using a single (possibly clipped) rectangle with a pattern source.
diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index 35befa5..77ae0ed 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -715,6 +715,44 @@ _fill_rectangles (cairo_surface_t *dst,
return status;
}
+/* fast-path for very common composite of a single rectangle */
+static cairo_status_t
+_composite_rectangle (cairo_surface_t *dst,
+ cairo_operator_t op,
+ const cairo_pattern_t *src,
+ cairo_traps_t *traps,
+ cairo_clip_t *clip)
+{
+ cairo_rectangle_int_t rect;
+
+ if (clip != NULL)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ if (traps->num_traps > 1 || ! traps->is_rectilinear || ! traps->maybe_region)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ if (! _cairo_fixed_is_integer (traps->traps[0].top) ||
+ ! _cairo_fixed_is_integer (traps->traps[0].bottom) ||
+ ! _cairo_fixed_is_integer (traps->traps[0].left.p1.x) ||
+ ! _cairo_fixed_is_integer (traps->traps[0].right.p1.x))
+ {
+ traps->maybe_region = FALSE;
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+ }
+
+ rect.x = _cairo_fixed_integer_part (traps->traps[0].left.p1.x);
+ rect.y = _cairo_fixed_integer_part (traps->traps[0].top);
+ rect.width = _cairo_fixed_integer_part (traps->traps[0].right.p1.x) - rect.x;
+ rect.height = _cairo_fixed_integer_part (traps->traps[0].bottom) - rect.y;
+
+ return _cairo_surface_composite (op, src, NULL, dst,
+ rect.x, rect.y,
+ 0, 0,
+ rect.x, rect.y,
+ rect.width, rect.height,
+ NULL);
+}
+
/* Warning: This call modifies the coordinates of traps */
static cairo_status_t
_clip_and_composite_trapezoids (const cairo_pattern_t *src,
@@ -756,6 +794,10 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src,
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
return status;
+ status = _composite_rectangle (dst, op, src, traps, clip);
+ if (status != CAIRO_INT_STATUS_UNSUPPORTED)
+ return status;
+
status = _cairo_traps_extract_region (traps, &trap_region);
if (unlikely (_cairo_status_is_error (status)))
return status;
commit 35daf95db8aa4f0c254891f180aa4996dd464a60
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Sep 21 03:31:22 2009 +0100
[xlib] Trim a few redundant steps when uploading glyphs
Cleanup the glyph coercion routines to avoid the temporary cairo_t (as
we can just cairo_surface_paint() directly).
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 88bad87..0352ed7 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -3764,7 +3764,6 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
* a clear 1x1 surface, to avoid various X server bugs.
*/
if (glyph_surface->width == 0 || glyph_surface->height == 0) {
- cairo_t *cr;
cairo_surface_t *tmp_surface;
tmp_surface = cairo_image_surface_create (glyphset_info->format, 1, 1);
@@ -3772,19 +3771,10 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
if (unlikely (status))
goto BAIL;
- cr = cairo_create (tmp_surface);
- cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
- cairo_paint (cr);
- status = cairo_status (cr);
- cairo_destroy (cr);
-
tmp_surface->device_transform = glyph_surface->base.device_transform;
tmp_surface->device_transform_inverse = glyph_surface->base.device_transform_inverse;
glyph_surface = (cairo_image_surface_t *) tmp_surface;
-
- if (unlikely (status))
- goto BAIL;
}
/* If the glyph format does not match the font format, then we
@@ -3792,7 +3782,7 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
* format.
*/
if (glyph_surface->format != glyphset_info->format) {
- cairo_t *cr;
+ cairo_surface_pattern_t pattern;
cairo_surface_t *tmp_surface;
tmp_surface = cairo_image_surface_create (glyphset_info->format,
@@ -3805,12 +3795,11 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
tmp_surface->device_transform = glyph_surface->base.device_transform;
tmp_surface->device_transform_inverse = glyph_surface->base.device_transform_inverse;
- cr = cairo_create (tmp_surface);
- cairo_set_source_surface (cr, &glyph_surface->base, 0, 0);
- cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
- cairo_paint (cr);
- status = cairo_status (cr);
- cairo_destroy (cr);
+ _cairo_pattern_init_for_surface (&pattern, &glyph_surface->base);
+ status = _cairo_surface_paint (tmp_surface,
+ CAIRO_OPERATOR_SOURCE, &pattern.base,
+ NULL);
+ _cairo_pattern_fini (&pattern.base);
glyph_surface = (cairo_image_surface_t *) tmp_surface;
More information about the cairo-commit
mailing list