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

Uli Schlachter psychon at kemper.freedesktop.org
Sun Sep 18 11:09:45 PDT 2011


 src/cairo-clip-surface.c       |    5 +++
 src/cairo-xcb-surface-render.c |   59 ++++++++++++++++++++++++++++-------------
 2 files changed, 46 insertions(+), 18 deletions(-)

New commits:
commit 36a14230453a1fd282671a4ab7ac072b69b9a5f6
Author: Uli Schlachter <psychon at znc.in>
Date:   Fri Sep 16 23:20:46 2011 +0200

    xcb: Remove an unused variable
    
    Signed-off-by: Uli Schlachter <psychon at znc.in>

diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c
index 1d46ffd..42178b2 100644
--- a/src/cairo-xcb-surface-render.c
+++ b/src/cairo-xcb-surface-render.c
@@ -2517,7 +2517,6 @@ _composite_boxes (cairo_xcb_surface_t *dst,
 {
     cairo_clip_t *clip = extents->clip;
     cairo_bool_t need_clip_mask = ! _cairo_clip_is_region (clip);
-    cairo_region_t *clip_region = _cairo_clip_get_region (clip);
     cairo_status_t status;
 
     /* If the boxes are not pixel-aligned, we will need to compute a real mask */
@@ -2530,11 +2529,6 @@ _composite_boxes (cairo_xcb_surface_t *dst,
 	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
-    if (clip_region != NULL &&
-	cairo_region_contains_rectangle (clip_region,
-					 &extents->bounded) == CAIRO_REGION_OVERLAP_IN)
-	clip_region = NULL;
-
     status = _cairo_xcb_connection_acquire (dst->connection);
     if (unlikely (status))
 	return status;
commit cdd75ec407f1f9148acc4267b07a874245c1ddf7
Author: Uli Schlachter <psychon at znc.in>
Date:   Fri Sep 16 19:31:32 2011 +0200

    xcb: Use a mask in _composite_boxes() when needed
    
    This doesn't just need a clip without any path, it also needs pixel aligned
    boxes.
    
    This improves the result for unaligned boxes in tighten-bounds.
    
    Signed-off-by: Uli Schlachter <psychon at znc.in>

diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c
index c8171c1..1d46ffd 100644
--- a/src/cairo-xcb-surface-render.c
+++ b/src/cairo-xcb-surface-render.c
@@ -2515,8 +2515,8 @@ _composite_boxes (cairo_xcb_surface_t *dst,
 		  cairo_boxes_t *boxes,
 		  const cairo_composite_rectangles_t *extents)
 {
-    cairo_bool_t need_clip_mask = extents->clip->path != NULL;
     cairo_clip_t *clip = extents->clip;
+    cairo_bool_t need_clip_mask = ! _cairo_clip_is_region (clip);
     cairo_region_t *clip_region = _cairo_clip_get_region (clip);
     cairo_status_t status;
 
commit e580565e28c3c2999199bee1f83be60905cba8d5
Author: Uli Schlachter <psychon at znc.in>
Date:   Fri Sep 16 18:28:10 2011 +0200

    xcb: Stop using _cairo_clip_get_surface()
    
    This function changed its behavior and no longer does what we want. Instead,
    this now uses its own function which uses _cairo_clip_combine_with_surface().
    
    This fixes crashes in the tighten-bounds and random-clip tests. These happened
    because cairo-xcb was trying to be clever. ;-)
    
    Since _cairo_clip_get_surface() did less, the resulting surface had
    deferred_clear == true and picture == XCB_NONE. The code then tried using this
    evil picture and either ran into an assert() or caused a BadPicture error.
    
    Signed-off-by: Uli Schlachter <psychon at znc.in>

diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c
index 88333e3..c8171c1 100644
--- a/src/cairo-xcb-surface-render.c
+++ b/src/cairo-xcb-surface-render.c
@@ -1591,6 +1591,36 @@ _composite_traps (void *closure,
 
 /* low-level composite driver */
 
+static cairo_xcb_surface_t *
+get_clip_surface (const cairo_clip_t *clip,
+		  cairo_xcb_surface_t *target,
+		  int *tx, int *ty)
+{
+    cairo_surface_t *surface;
+    cairo_status_t status;
+
+    surface = _cairo_surface_create_similar_solid (&target->base,
+						   CAIRO_CONTENT_ALPHA,
+						   clip->extents.width,
+						   clip->extents.height,
+						   CAIRO_COLOR_WHITE);
+    if (unlikely (surface->status))
+	return (cairo_xcb_surface_t *) surface;
+
+    assert (surface->backend == &_cairo_xcb_surface_backend);
+    status = _cairo_clip_combine_with_surface (clip, surface,
+					       clip->extents.x, clip->extents.y);
+    if (unlikely (status)) {
+	cairo_surface_destroy (surface);
+	surface = _cairo_surface_create_in_error (status);
+    }
+
+    *tx = clip->extents.x;
+    *ty = clip->extents.y;
+
+    return (cairo_xcb_surface_t *) surface;
+}
+
 typedef cairo_int_status_t
 (*xcb_draw_func_t) (void				*closure,
 		    cairo_xcb_surface_t			*dst,
@@ -1890,7 +1920,7 @@ _clip_and_composite_combine (cairo_clip_t		*clip,
     if (unlikely (status))
 	goto CLEANUP_SURFACE;
 
-    clip_surface = (cairo_xcb_surface_t *) _cairo_clip_get_surface (clip, &dst->base, &clip_x, &clip_y);
+    clip_surface = get_clip_surface (clip, dst, &clip_x, &clip_y);
     status = clip_surface->base.status;
     if (unlikely (status))
 	goto CLEANUP_SURFACE;
@@ -2126,7 +2156,7 @@ _cairo_xcb_surface_fixup_unbounded_with_mask (cairo_xcb_surface_t *dst,
     cairo_xcb_surface_t *mask;
     int mask_x, mask_y;
 
-    mask = (cairo_xcb_surface_t *) _cairo_clip_get_surface (clip, &dst->base, &mask_x, &mask_y);
+    mask = get_clip_surface (clip, dst, &mask_x, &mask_y);
     if (unlikely (mask->base.status))
 	return mask->base.status;
 
@@ -2380,7 +2410,7 @@ _clip_and_composite (cairo_xcb_surface_t	*dst,
 
     if (need_clip & NEED_CLIP_REGION) {
 	clip_region = _cairo_clip_get_region (extents->clip);
-	if ((need_clip & FORCE_CLIP_REGION) == 0 &&
+	if ((need_clip & FORCE_CLIP_REGION) == 0 && clip_region != NULL &&
 	    cairo_region_contains_rectangle (clip_region,
 					     &extents->unbounded) == CAIRO_REGION_OVERLAP_IN)
 	    clip_region = NULL;
@@ -2527,21 +2557,20 @@ _composite_boxes (cairo_xcb_surface_t *dst,
 	cairo_surface_pattern_t mask;
 
 	if (need_clip_mask) {
-	    cairo_surface_t *clip_surface;
+	    cairo_xcb_surface_t *clip_surface;
 	    int clip_x, clip_y;
 
-	    clip_surface = _cairo_clip_get_surface (extents->clip,
-						    &dst->base,
-						    &clip_x, &clip_y);
-	    if (unlikely (clip_surface->status))
-		return clip_surface->status;
+	    clip_surface = get_clip_surface (extents->clip, dst,
+					     &clip_x, &clip_y);
+	    if (unlikely (clip_surface->base.status))
+		return clip_surface->base.status;
 
-	    _cairo_pattern_init_for_surface (&mask, clip_surface);
+	    _cairo_pattern_init_for_surface (&mask, &clip_surface->base);
 	    mask.base.filter = CAIRO_FILTER_NEAREST;
 	    cairo_matrix_init_translate (&mask.base.matrix,
 					 -clip_x,
 					 -clip_y);
-	    cairo_surface_destroy (clip_surface);
+	    cairo_surface_destroy (&clip_surface->base);
 
 	    if (op == CAIRO_OPERATOR_CLEAR) {
 		src = NULL;
commit 6fb4c3ae3521fa789aa63b3b37f17336e5b7b617
Author: Uli Schlachter <psychon at znc.in>
Date:   Fri Sep 16 18:16:01 2011 +0200

    _cairo_clip_get_surface(): Don't lose errors
    
    If one of the _cairo_surface_fill() calls failed, this function would stop and
    return an intermediate result, thus hiding the error that happened.
    
    Signed-off-by: Uli Schlachter <psychon at znc.in>

diff --git a/src/cairo-clip-surface.c b/src/cairo-clip-surface.c
index e1e9312..244e7f2 100644
--- a/src/cairo-clip-surface.c
+++ b/src/cairo-clip-surface.c
@@ -130,6 +130,11 @@ _cairo_clip_get_surface (const cairo_clip_t *clip,
     copy->path = copy_path;
     _cairo_clip_destroy (copy);
 
+    if (unlikely (status)) {
+	cairo_surface_destroy (surface);
+	return _cairo_surface_create_in_error (status);
+    }
+
     *tx = clip->extents.x;
     *ty = clip->extents.y;
     return surface;


More information about the cairo-commit mailing list