summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-01-08 17:52:04 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2013-01-08 22:26:25 +0000
commit7401455cb4136473521b9f33b09944aa0bc66971 (patch)
treef4455d572de08223387dc71c060d0f546cb38fb5
parent0d38518c38fec68a1fa8cf9d3ae946faa08d6c42 (diff)
image: Allocate a temporary buffer for inline span composition
Allow the inpline span compositor to operate on wider images than its temporary buffer by allocating a scanline mask. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/cairo-image-compositor.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/src/cairo-image-compositor.c b/src/cairo-image-compositor.c
index 460c9b59..97152502 100644
--- a/src/cairo-image-compositor.c
+++ b/src/cairo-image-compositor.c
@@ -2594,6 +2594,11 @@ _inplace_src_spans (void *abstract_renderer,
return CAIRO_STATUS_SUCCESS;
}
+static void free_pixels (pixman_image_t *image, void *data)
+{
+ free (data);
+}
+
static cairo_int_status_t
inplace_renderer_init (cairo_image_span_renderer_t *r,
const cairo_composite_rectangles_t *composite,
@@ -2601,6 +2606,7 @@ inplace_renderer_init (cairo_image_span_renderer_t *r,
cairo_bool_t needs_clip)
{
cairo_image_surface_t *dst = (cairo_image_surface_t *)composite->surface;
+ uint8_t *buf;
if (composite->mask_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID)
return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -2714,9 +2720,6 @@ inplace_renderer_init (cairo_image_span_renderer_t *r,
r->op = _pixman_operator (composite->op);
}
- if (width > sizeof (r->buf))
- return CAIRO_INT_STATUS_UNSUPPORTED;
-
r->src = _pixman_image_for_pattern (dst, src, FALSE,
&composite->bounded,
&composite->source_sample_area,
@@ -2725,14 +2728,27 @@ inplace_renderer_init (cairo_image_span_renderer_t *r,
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
/* Create an effectively unbounded mask by repeating the single line */
+ buf = r->buf;
+ if (width > sizeof (r->buf)) {
+ buf = malloc (width);
+ if (unlikely (buf == NULL)) {
+ pixman_image_unref (r->src);
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ }
+ }
r->mask = pixman_image_create_bits (PIXMAN_a8,
width, composite->unbounded.height,
- (uint32_t *)r->buf, 0);
+ (uint32_t *)buf, 0);
if (unlikely (r->mask == NULL)) {
pixman_image_unref (r->src);
+ if (buf != r->buf)
+ free (buf);
return _cairo_error(CAIRO_STATUS_NO_MEMORY);
}
+ if (buf != r->buf)
+ pixman_image_set_destroy_function (r->mask, free_pixels, buf);
+
r->u.composite.dst = dst->pixman_image;
}