[cairo-commit] 3 commits - src/cairo-xcb-private.h src/cairo-xcb-shm.c src/cairo-xcb-surface.c src/cairo-xcb-surface-core.c src/cairo-xcb-surface-render.c

Uli Schlachter psychon at kemper.freedesktop.org
Fri Sep 2 06:22:33 PDT 2011


 src/cairo-xcb-private.h        |    2 +
 src/cairo-xcb-shm.c            |   18 ++++++++++
 src/cairo-xcb-surface-core.c   |    4 +-
 src/cairo-xcb-surface-render.c |   72 +++++++++++++++++++++--------------------
 src/cairo-xcb-surface.c        |    3 +
 5 files changed, 62 insertions(+), 37 deletions(-)

New commits:
commit 968eb30bba1dc942ccd31e4450fdd3bb74c83cb6
Author: Uli Schlachter <psychon at znc.in>
Date:   Thu Sep 1 13:34:43 2011 +0200

    xcb: Steal from the pending list for GetImage
    
    Before using some piece of SHM again, we must be sure that the X11 server is no
    longer working with it. For this, we send a GetInputFocus when we are done with
    the SHM locally and will only use the memory again when the reply comes in.
    
    However, if we are allocating the memory for SHM GetImage, then we can re-use
    memory earlier, because the server processes requests in order. So it will only
    start writing to the memory after it is done with earlier requests for this
    memory. So instead of using GetInputFocus for synchronisation, the SHM GetImage
    request will automatically do this for us.
    
    Thanks to Chris Wilson for this idea.
    
    Signed-off-by: Uli Schlachter <psychon at znc.in>

diff --git a/src/cairo-xcb-private.h b/src/cairo-xcb-private.h
index c99f117..e87f0e8 100644
--- a/src/cairo-xcb-private.h
+++ b/src/cairo-xcb-private.h
@@ -77,6 +77,7 @@ struct _cairo_xcb_shm_info {
     cairo_xcb_connection_t *connection;
     uint32_t shm;
     uint32_t offset;
+    size_t size;
     void *mem;
     cairo_xcb_shm_mem_pool_t *pool;
     xcb_get_input_focus_cookie_t sync;
@@ -307,6 +308,7 @@ _cairo_xcb_connection_destroy (cairo_xcb_connection_t *connection)
 cairo_private cairo_int_status_t
 _cairo_xcb_connection_allocate_shm_info (cairo_xcb_connection_t *display,
 					 size_t size,
+					 cairo_bool_t might_reuse,
 					 cairo_xcb_shm_info_t **shm_info_out);
 
 cairo_private void
diff --git a/src/cairo-xcb-shm.c b/src/cairo-xcb-shm.c
index ffcaec8..6972720 100644
--- a/src/cairo-xcb-shm.c
+++ b/src/cairo-xcb-shm.c
@@ -492,6 +492,7 @@ _cairo_xcb_shm_process_pending (cairo_xcb_connection_t *connection, shm_wait_typ
 cairo_int_status_t
 _cairo_xcb_connection_allocate_shm_info (cairo_xcb_connection_t *connection,
 					 size_t size,
+					 cairo_bool_t might_reuse,
 					 cairo_xcb_shm_info_t **shm_info_out)
 {
     cairo_xcb_shm_info_t *shm_info;
@@ -506,6 +507,22 @@ _cairo_xcb_connection_allocate_shm_info (cairo_xcb_connection_t *connection,
     CAIRO_MUTEX_LOCK (connection->shm_mutex);
     _cairo_xcb_shm_process_pending (connection, PENDING_POLL);
 
+    if (might_reuse) {
+	cairo_list_foreach_entry (shm_info, cairo_xcb_shm_info_t,
+		&connection->shm_pending, pending) {
+	    if (shm_info->size >= size) {
+		cairo_list_del (&shm_info->pending);
+		CAIRO_MUTEX_UNLOCK (connection->shm_mutex);
+
+		xcb_discard_reply (connection->xcb_connection, shm_info->sync.sequence);
+		shm_info->sync.sequence = XCB_NONE;
+
+		*shm_info_out = shm_info;
+		return CAIRO_STATUS_SUCCESS;
+	    }
+	}
+    }
+
     cairo_list_foreach_entry_safe (pool, next, cairo_xcb_shm_mem_pool_t,
 				   &connection->shm_pools, link)
     {
@@ -599,6 +616,7 @@ _cairo_xcb_connection_allocate_shm_info (cairo_xcb_connection_t *connection,
     shm_info->connection = connection;
     shm_info->pool = pool;
     shm_info->shm = pool->shmseg;
+    shm_info->size = size;
     shm_info->offset = (char *) mem - (char *) pool->base;
     shm_info->mem = mem;
     shm_info->sync.sequence = XCB_NONE;
diff --git a/src/cairo-xcb-surface-core.c b/src/cairo-xcb-surface-core.c
index 20cb5d3..c288575 100644
--- a/src/cairo-xcb-surface-core.c
+++ b/src/cairo-xcb-surface-core.c
@@ -164,8 +164,8 @@ _cairo_xcb_shm_image_create_shm (cairo_xcb_connection_t *connection,
     if (size <= CAIRO_XCB_SHM_SMALL_IMAGE)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    status = _cairo_xcb_connection_allocate_shm_info (connection,
-						      size, &shm_info);
+    status = _cairo_xcb_connection_allocate_shm_info (connection, size,
+						      FALSE, &shm_info);
     if (unlikely (status))
 	return status;
 
diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index ebea5ff..9639f91 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -221,6 +221,7 @@ static cairo_surface_t *
 _cairo_xcb_surface_create_shm_image (cairo_xcb_connection_t *connection,
 				     pixman_format_code_t pixman_format,
 				     int width, int height,
+				     cairo_bool_t might_reuse,
 				     cairo_xcb_shm_info_t **shm_info_out)
 {
     cairo_surface_t *image;
@@ -234,6 +235,7 @@ _cairo_xcb_surface_create_shm_image (cairo_xcb_connection_t *connection,
 					 PIXMAN_FORMAT_BPP (pixman_format));
     status = _cairo_xcb_connection_allocate_shm_info (connection,
 						      stride * height,
+						      might_reuse,
 						      &shm_info);
     if (unlikely (status))
 	return _cairo_surface_create_in_error (status);
@@ -278,6 +280,7 @@ _get_shm_image (cairo_xcb_surface_t *surface,
     image = _cairo_xcb_surface_create_shm_image (surface->connection,
 						 surface->pixman_format,
 						 width, height,
+						 TRUE,
 						 &shm_info);
     if (unlikely (image == NULL || image->status))
 	goto done;
commit ea5255653176dfab0fdfe78a3186587b01559735
Author: Uli Schlachter <psychon at znc.in>
Date:   Wed Aug 31 12:24:20 2011 +0200

    xcb: Fix fixup_unbounded_with_mask
    
    This code was casting a pixman_box32_t* to cairo_box_t*. However, a box uses
    fixed point numbers while the pixman box uses integers which means the result
    was off by factor 256.
    
    The fix is to replace the use of _cairo_boxes_limit() with
    _cairo_boxes_init_with_clip(). However, this means this function no needs to be
    passed a clip instead of a clip region which causes some minor changes to
    _composite_boxes().
    
    This improves the result for tighten-bounds again. Out of the tested
    combinations, 10 are fixed by this. This bug was hit by code similar to this
    (Repeating here since that test has so many different cases):
    
    cairo_set_operator (cr, CAIRO_OPERATOR_IN);
    cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
    cairo_rectangle (cr, 0, 0, SIZE, SIZE);
    cairo_rectangle (cr, 0, 0, SIZE, SIZE);
    cairo_rectangle (cr, SIZE / 4, SIZE / 4, SIZE / 2, SIZE / 2);
    cairo_clip_preserve (cr);
    cairo_fill (cr);
    
    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 4639cbe..aa9100f 100644
--- a/src/cairo-xcb-surface-render.c
+++ b/src/cairo-xcb-surface-render.c
@@ -2203,7 +2203,7 @@ _cairo_xcb_surface_fixup_unbounded_with_mask (cairo_xcb_surface_t *dst,
 static cairo_status_t
 _cairo_xcb_surface_fixup_unbounded_boxes (cairo_xcb_surface_t *dst,
 					  const cairo_composite_rectangles_t *extents,
-					  cairo_region_t *clip_region,
+					  cairo_clip_t *clip,
 					  cairo_boxes_t *boxes)
 {
     cairo_boxes_t clear;
@@ -2212,7 +2212,7 @@ _cairo_xcb_surface_fixup_unbounded_boxes (cairo_xcb_surface_t *dst,
     struct _cairo_boxes_chunk *chunk;
     int i;
 
-    if (boxes->num_boxes <= 1 && clip_region == NULL)
+    if (boxes->num_boxes <= 1 && clip == NULL)
 	return _cairo_xcb_surface_fixup_unbounded (dst, extents);
 
     _cairo_boxes_init (&clear);
@@ -2222,7 +2222,7 @@ _cairo_xcb_surface_fixup_unbounded_boxes (cairo_xcb_surface_t *dst,
     box.p2.x = _cairo_fixed_from_int (extents->unbounded.x);
     box.p2.y = _cairo_fixed_from_int (extents->unbounded.y + extents->unbounded.height);
 
-    if (clip_region == NULL) {
+    if (clip == NULL) {
 	cairo_boxes_t tmp;
 
 	_cairo_boxes_init (&tmp);
@@ -2239,10 +2239,7 @@ _cairo_xcb_surface_fixup_unbounded_boxes (cairo_xcb_surface_t *dst,
 
 	tmp.chunks.next = NULL;
     } else {
-	pixman_box32_t *pbox;
-
-	pbox = pixman_region32_rectangles (&clip_region->rgn, &i);
-	_cairo_boxes_limit (&clear, (cairo_box_t *) pbox, i);
+	_cairo_boxes_init_with_clip (&clear, clip);
 
 	status = _cairo_boxes_add (&clear, CAIRO_ANTIALIAS_DEFAULT, &box);
 	assert (status == CAIRO_STATUS_SUCCESS);
@@ -2490,7 +2487,8 @@ _composite_boxes (cairo_xcb_surface_t *dst,
 		  const cairo_composite_rectangles_t *extents)
 {
     cairo_bool_t need_clip_mask = extents->clip->path != NULL;
-    cairo_region_t *clip_region = _cairo_clip_get_region (extents->clip);
+    cairo_clip_t *clip = extents->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 */
@@ -2503,8 +2501,10 @@ _composite_boxes (cairo_xcb_surface_t *dst,
 	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
-    if (cairo_region_contains_rectangle (clip_region, &extents->bounded) == CAIRO_REGION_OVERLAP_IN)
+    if (cairo_region_contains_rectangle (clip_region, &extents->bounded) == CAIRO_REGION_OVERLAP_IN) {
+	clip = NULL;
 	clip_region = NULL;
+    }
 
     status = _cairo_xcb_connection_acquire (dst->connection);
     if (unlikely (status))
@@ -2561,7 +2561,7 @@ _composite_boxes (cairo_xcb_surface_t *dst,
     if (status == CAIRO_STATUS_SUCCESS && ! extents->is_bounded) {
 	status =
 	    _cairo_xcb_surface_fixup_unbounded_boxes (dst, extents,
-						      clip_region, boxes);
+						      clip, boxes);
     }
 
     _cairo_xcb_connection_release (dst->connection);
commit ed7f992c1345e46aadf7b5b60350e483c11bf518
Author: Uli Schlachter <psychon at znc.in>
Date:   Wed Aug 31 11:41:00 2011 +0200

    xcb: Skip drawing if bounded extents are empty
    
    This only wraps the whole code block in an if which checks if the bounded
    extents are empty. No other changes are done in here.
    
    This fixes the failed assertion from the tighten-bounds test.
    
    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 8231962..4639cbe 100644
--- a/src/cairo-xcb-surface-render.c
+++ b/src/cairo-xcb-surface-render.c
@@ -2402,34 +2402,36 @@ _clip_and_composite (cairo_xcb_surface_t	*dst,
 	src = NULL;
     }
 
-    if (op == CAIRO_OPERATOR_SOURCE) {
-	status = _clip_and_composite_source (extents->clip, src,
-					     draw_func, mask_func, draw_closure,
-					     dst, &extents->bounded);
-    } else {
-	if (op == CAIRO_OPERATOR_CLEAR) {
-	    op = CAIRO_OPERATOR_DEST_OUT;
-	    src = NULL;
-	}
+    if (extents->bounded.width != 0 && extents->bounded.height != 0) {
+	if (op == CAIRO_OPERATOR_SOURCE) {
+	    status = _clip_and_composite_source (extents->clip, src,
+						 draw_func, mask_func, draw_closure,
+						 dst, &extents->bounded);
+	} else {
+	    if (op == CAIRO_OPERATOR_CLEAR) {
+		op = CAIRO_OPERATOR_DEST_OUT;
+		src = NULL;
+	    }
 
-	if (need_clip & NEED_CLIP_SURFACE) {
-	    if (extents->is_bounded) {
-		status = _clip_and_composite_with_mask (extents->clip, op, src,
-							draw_func,
-							mask_func,
-							draw_closure,
-							dst, &extents->bounded);
+	    if (need_clip & NEED_CLIP_SURFACE) {
+		if (extents->is_bounded) {
+		    status = _clip_and_composite_with_mask (extents->clip, op, src,
+							    draw_func,
+							    mask_func,
+							    draw_closure,
+							    dst, &extents->bounded);
+		} else {
+		    status = _clip_and_composite_combine (extents->clip, op, src,
+							  draw_func, draw_closure,
+							  dst, &extents->bounded);
+		}
 	    } else {
-		status = _clip_and_composite_combine (extents->clip, op, src,
-						      draw_func, draw_closure,
-						      dst, &extents->bounded);
+		status = draw_func (draw_closure,
+				    dst, op, src,
+				    0, 0,
+				    &extents->bounded,
+				    extents->clip);
 	    }
-	} else {
-	    status = draw_func (draw_closure,
-				dst, op, src,
-				0, 0,
-				&extents->bounded,
-				extents->clip);
 	}
     }
 


More information about the cairo-commit mailing list