[cairo-commit] src/cairo-xcb-surface-render.c

Andrea Canciani ranma42 at kemper.freedesktop.org
Tue Jan 25 03:23:00 PST 2011


 src/cairo-xcb-surface-render.c |   56 ++++++++++++++++++++++++-----------------
 1 file changed, 34 insertions(+), 22 deletions(-)

New commits:
commit f60e8f0bb231547ff473dd23807193c847c99a3d
Author: Andrea Canciani <ranma42 at gmail.com>
Date:   Tue Jan 25 08:41:27 2011 +0100

    xcb: Fix compositing of pixel-aligned rectangles
    
    bef8b28300ab1f9b46db9d54b072f6f9318dca30 introduced a regression in
    the compositing of pixel-aligned rectangles, because it only
    translates the destination, instead of destination, source and mask,
    by the extents offset.
    
    The same commit introduces some memleaks when the acquisition of an
    xcb picture fails.
    
    74374fce9d71d373287cddc3a0bf4aaf4bda568b causes incorrect rendering
    whenever extents are not tight.
    
    Fixes https://bugs.freedesktop.org/show_bug.cgi?id=33448

diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c
index 37921f9..9a059fc 100644
--- a/src/cairo-xcb-surface-render.c
+++ b/src/cairo-xcb-surface-render.c
@@ -1445,8 +1445,10 @@ _render_composite_boxes (cairo_xcb_surface_t	*dst,
 {
     cairo_xcb_picture_t *src, *mask;
     const struct _cairo_boxes_chunk *chunk;
-    xcb_rectangle_t stack_boxes[128];
+    xcb_rectangle_t stack_boxes[CAIRO_STACK_ARRAY_LENGTH (xcb_rectangle_t)];
     xcb_rectangle_t *clip_boxes;
+    cairo_rectangle_int_t stack_extents;
+    cairo_status_t status;
     int num_boxes;
     int render_op;
 
@@ -1457,18 +1459,19 @@ _render_composite_boxes (cairo_xcb_surface_t	*dst,
 	mask_pattern = NULL;
     }
 
-    src = _cairo_xcb_picture_for_pattern (dst, src_pattern, extents);
-    if (unlikely (src->base.status))
-	return src->base.status;
-
     /* amalgamate into a single Composite call by setting a clip region */
     clip_boxes = stack_boxes;
-    if (boxes->num_boxes > ARRAY_LENGTH(stack_boxes)) {
-	clip_boxes = _cairo_malloc_ab(boxes->num_boxes, sizeof(xcb_rectangle_t));
+    if (boxes->num_boxes > ARRAY_LENGTH (stack_boxes)) {
+	clip_boxes = _cairo_malloc_ab (boxes->num_boxes, sizeof (xcb_rectangle_t));
 	if (unlikely (clip_boxes == NULL))
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
+    src = _cairo_xcb_picture_for_pattern (dst, src_pattern, extents);
+    status = src->base.status;
+    if (unlikely (status))
+	goto cleanup_boxes;
+
     num_boxes = 0;
     for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
 	const cairo_box_t *box = chunk->base;
@@ -1492,27 +1495,32 @@ _render_composite_boxes (cairo_xcb_surface_t	*dst,
 
     if (num_boxes) {
 	if (num_boxes > 1) {
-	    _cairo_xcb_connection_render_set_picture_clip_rectangles(dst->connection,
-								     dst->picture,
-								     0, 0,
-								     num_boxes,
-								     clip_boxes);
+	    _cairo_xcb_connection_render_set_picture_clip_rectangles (dst->connection,
+								      dst->picture,
+								      0, 0,
+								      num_boxes,
+								      clip_boxes);
+	} else {
+	    stack_extents.x = clip_boxes[0].x;
+	    stack_extents.y = clip_boxes[0].y;
+	    stack_extents.width = clip_boxes[0].width;
+	    stack_extents.height = clip_boxes[0].height;
+	    extents = &stack_extents;
 	}
 
 	if (mask_pattern != NULL) {
 	    mask = _cairo_xcb_picture_for_pattern (dst, mask_pattern, extents);
-	    if (unlikely (mask->base.status)) {
-		cairo_surface_destroy (&src->base);
-		return mask->base.status;
-	    }
+	    status = mask->base.status;
+	    if (unlikely (status))
+		goto cleanup_clip;
 
 	    _cairo_xcb_connection_render_composite (dst->connection,
 						    render_op,
 						    src->picture,
 						    mask->picture,
 						    dst->picture,
-						    src->x, src->y,
-						    mask->x, mask->y,
+						    src->x + extents->x, src->y + extents->y,
+						    mask->x + extents->x, mask->y + extents->y,
 						    extents->x, extents->y,
 						    extents->width, extents->height);
 
@@ -1523,22 +1531,26 @@ _render_composite_boxes (cairo_xcb_surface_t	*dst,
 						    src->picture,
 						    XCB_NONE,
 						    dst->picture,
-						    src->x, src->y,
+						    src->x + extents->x, src->y + extents->y,
 						    0, 0,
 						    extents->x, extents->y,
 						    extents->width, extents->height);
 	}
 
+cleanup_clip:
+
 	if (num_boxes > 1)
 	    _cairo_xcb_surface_clear_clip_region (dst);
     }
 
+    cairo_surface_destroy (&src->base);
+
+cleanup_boxes:
+
     if (clip_boxes != stack_boxes)
 	free (clip_boxes);
 
-    cairo_surface_destroy (&src->base);
-
-    return CAIRO_STATUS_SUCCESS;
+    return status;
 }
 
 


More information about the cairo-commit mailing list