[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