[cairo-commit] 2 commits - src/cairo-cache.c src/cairo-xcb-screen.c src/cairo-xcb-surface-render.c

Chris Wilson ickle at kemper.freedesktop.org
Sun Apr 11 13:08:44 PDT 2010


 src/cairo-cache.c              |   10 ++-----
 src/cairo-xcb-screen.c         |    4 ++
 src/cairo-xcb-surface-render.c |   57 +++++++++++++++++++----------------------
 3 files changed, 33 insertions(+), 38 deletions(-)

New commits:
commit d95037db9915033ef1eee24c2fc05e8a95af5457
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 11 21:04:29 2010 +0100

    cache: Tidy _cairo_cache_shrink_to_accommodate()
    
    There is no need to shrink the cache if we add an entry of size 0, so
    don't by moving the guards in _cairo_cache_shrink_to_accommodate() to the
    callers.

diff --git a/src/cairo-cache.c b/src/cairo-cache.c
index 1bc3089..7d99845 100644
--- a/src/cairo-cache.c
+++ b/src/cairo-cache.c
@@ -175,9 +175,7 @@ _cairo_cache_thaw (cairo_cache_t *cache)
 {
     assert (cache->freeze_count > 0);
 
-    cache->freeze_count--;
-
-    if (cache->freeze_count == 0)
+    if (--cache->freeze_count == 0)
 	_cairo_cache_shrink_to_accommodate (cache, 0);
 }
 
@@ -241,9 +239,6 @@ static void
 _cairo_cache_shrink_to_accommodate (cairo_cache_t *cache,
 				    unsigned long  additional)
 {
-    if (cache->freeze_count)
-	return;
-
     while (cache->size + additional > cache->max_size) {
 	if (! _cairo_cache_remove_random (cache))
 	    return;
@@ -268,7 +263,8 @@ _cairo_cache_insert (cairo_cache_t	 *cache,
 {
     cairo_status_t status;
 
-    _cairo_cache_shrink_to_accommodate (cache, entry->size);
+    if (entry->size && ! cache->freeze_count)
+	_cairo_cache_shrink_to_accommodate (cache, entry->size);
 
     status = _cairo_hash_table_insert (cache->hash_table,
 				       (cairo_hash_entry_t *) entry);
commit e6309c6307179388c5de938bffdb44b83b694f28
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 11 21:03:00 2010 +0100

    xcb: Use normal finish to decouple from surface cache.
    
    Hook into the standard finishing process for a more robust cache removal
    mechanism. firefox was able to trigger some double free asserts
    otherwise.

diff --git a/src/cairo-xcb-screen.c b/src/cairo-xcb-screen.c
index c0235e3..e4e6225 100644
--- a/src/cairo-xcb-screen.c
+++ b/src/cairo-xcb-screen.c
@@ -116,7 +116,8 @@ _surface_cache_entry_destroy (void *closure)
 {
     struct pattern_cache_entry *entry = closure;
 
-    cairo_surface_finish (entry->picture);
+    if (entry->picture->snapshot_of != NULL)
+	_cairo_surface_detach_snapshot (entry->picture);
     cairo_surface_destroy (entry->picture);
     _cairo_freelist_free (&entry->screen->pattern_cache_entry_freelist, entry);
 }
@@ -381,6 +382,7 @@ _cairo_xcb_screen_store_surface_picture (cairo_xcb_screen_t *screen,
     status = _cairo_cache_insert (&screen->surface_pattern_cache,
 				  &entry->key);
     if (unlikely (status)) {
+	cairo_surface_destroy (picture);
 	_cairo_freelist_free (&screen->pattern_cache_entry_freelist, entry);
 	return status;
     }
diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c
index d8edbd1..72a448e 100644
--- a/src/cairo-xcb-surface-render.c
+++ b/src/cairo-xcb-surface-render.c
@@ -51,7 +51,6 @@ typedef struct _cairo_xcb_picture {
 
     cairo_surface_t *owner;
 
-    cairo_xcb_connection_t *connection;
     cairo_xcb_screen_t *screen;
     xcb_render_picture_t picture;
     xcb_render_pictformat_t xrender_format;
@@ -68,6 +67,12 @@ typedef struct _cairo_xcb_picture {
     int x, y;
 } cairo_xcb_picture_t;
 
+static inline cairo_xcb_connection_t *
+_picture_to_connection (cairo_xcb_picture_t *picture)
+{
+    return (cairo_xcb_connection_t *) picture->base.device;
+}
+
 static void
 _cairo_xcb_surface_ensure_picture (cairo_xcb_surface_t *surface);
 
@@ -84,22 +89,25 @@ static cairo_status_t
 _cairo_xcb_picture_finish (void *abstract_surface)
 {
     cairo_xcb_picture_t *surface = abstract_surface;
+    cairo_xcb_connection_t *connection = _picture_to_connection (surface);
     cairo_status_t status;
 
-    if (surface->owner != NULL) {
+    if (surface->owner != NULL)
 	cairo_surface_destroy (surface->owner);
-    } else {
-	status = _cairo_xcb_connection_acquire (surface->connection);
-	if (unlikely (status))
-	    return status;
 
-	if (_cairo_xcb_connection_take_socket (surface->connection) == CAIRO_STATUS_SUCCESS) {
-	    _cairo_xcb_connection_render_free_picture (surface->connection,
-						       surface->picture);
-	}
-	_cairo_xcb_connection_release (surface->connection);
+    status = _cairo_xcb_connection_acquire (connection);
+    if (unlikely (status))
+	return status;
+
+    _cairo_xcb_screen_remove_surface_picture (surface->screen, &surface->base);
+
+    if (surface->owner == NULL) {
+	if (_cairo_xcb_connection_take_socket (connection) == CAIRO_STATUS_SUCCESS)
+	    _cairo_xcb_connection_render_free_picture (connection, surface->picture);
     }
 
+    _cairo_xcb_connection_release (connection);
+
     return CAIRO_STATUS_SUCCESS;
 }
 
@@ -130,10 +138,9 @@ _cairo_xcb_picture_create (cairo_xcb_screen_t *screen,
 
     _cairo_surface_init (&surface->base,
 			 &_cairo_xcb_picture_backend,
-			 NULL,
+			 &screen->connection->device,
 			 _cairo_content_from_pixman_format (pixman_format));
 
-    surface->connection = screen->connection;
     surface->screen = screen;
     surface->owner = NULL;
     surface->picture = _cairo_xcb_connection_get_xid (screen->connection);
@@ -165,10 +172,9 @@ _cairo_xcb_picture_copy (cairo_xcb_surface_t *target)
 
     _cairo_surface_init (&surface->base,
 			 &_cairo_xcb_picture_backend,
-			 NULL,
+			 target->base.device,
 			 target->base.content);
 
-    surface->connection = target->connection;
     surface->screen = target->screen;
     surface->owner = cairo_surface_reference (&target->base);
     _cairo_xcb_surface_ensure_picture (target);
@@ -484,7 +490,7 @@ _cairo_xcb_picture_set_matrix (cairo_xcb_picture_t *picture,
 					(pixman_transform_t *) &transform, xc, yc);
 
 	if (memcmp (&picture->transform, &transform, sizeof (xcb_render_transform_t))) {
-	    _cairo_xcb_connection_render_set_picture_transform (picture->connection,
+	    _cairo_xcb_connection_render_set_picture_transform (_picture_to_connection(picture),
 								picture->picture,
 								&transform);
 
@@ -540,7 +546,7 @@ _cairo_xcb_picture_set_filter (cairo_xcb_picture_t *picture,
 	break;
     }
 
-    _cairo_xcb_connection_render_set_picture_filter (picture->connection,
+    _cairo_xcb_connection_render_set_picture_filter (_picture_to_connection (picture),
 						     picture->picture,
 						     len, (char *) render_filter);
     picture->filter = filter;
@@ -575,7 +581,7 @@ _cairo_xcb_picture_set_extend (cairo_xcb_picture_t *picture,
 	break;
     }
 
-    _cairo_xcb_connection_render_change_picture (picture->connection,
+    _cairo_xcb_connection_render_change_picture (_picture_to_connection (picture),
 						 picture->picture,
 						 XCB_RENDER_CP_REPEAT, pa);
     picture->extend = extend;
@@ -592,7 +598,7 @@ _cairo_xcb_picture_set_component_alpha (cairo_xcb_picture_t *picture,
 
     pa[0] = ca;
 
-    _cairo_xcb_connection_render_change_picture (picture->connection,
+    _cairo_xcb_connection_render_change_picture (_picture_to_connection (picture),
 						 picture->picture,
 						 XCB_RENDER_CP_COMPONENT_ALPHA,
 						 pa);
@@ -642,7 +648,7 @@ _solid_picture (cairo_xcb_surface_t *target,
 	    rect.x = rect.y = 0;
 	    rect.width = rect.height = 1;
 
-	    _cairo_xcb_connection_render_fill_rectangles (picture->connection,
+	    _cairo_xcb_connection_render_fill_rectangles (_picture_to_connection (picture),
 							  XCB_RENDER_PICT_OP_SRC,
 							  picture->picture,
 							  xcb_color, 1, &rect);
@@ -1086,15 +1092,6 @@ setup_picture:
     return picture;
 }
 
-static void
-_decouple_cached_picture (cairo_surface_t *surface)
-{
-    cairo_xcb_picture_t *picture = (cairo_xcb_picture_t *) surface;
-
-    if (! picture->base.finished)
-	_cairo_xcb_screen_remove_surface_picture (picture->screen, &picture->base);
-}
-
 static cairo_xcb_picture_t *
 _copy_to_picture (cairo_xcb_surface_t *source,
 		  cairo_bool_t force)
@@ -1372,7 +1369,7 @@ _cairo_xcb_surface_picture (cairo_xcb_surface_t *target,
 
     status = _cairo_surface_attach_snapshot (source,
 					     &picture->base,
-					     _decouple_cached_picture);
+					     cairo_surface_finish);
     if (unlikely (status)) {
 	cairo_surface_destroy (&picture->base);
 	return (cairo_xcb_picture_t *) _cairo_surface_create_in_error (status);


More information about the cairo-commit mailing list