summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-12-05 15:39:03 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2011-12-05 17:17:26 +0000
commit0ce8dad9a2330575276b28a37098fe6cc4bf877f (patch)
treef07404ea268a100d4d43131f3415dcb98e90d206
parent31c0726f682159e6465719c389975ec8885fa38b (diff)
gl: Decouple glyphs on shutdown from the scaled font caches
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/cairo-gl-glyphs.c24
-rw-r--r--src/cairo-rtree-private.h5
-rw-r--r--src/cairo-rtree.c28
3 files changed, 47 insertions, 10 deletions
diff --git a/src/cairo-gl-glyphs.c b/src/cairo-gl-glyphs.c
index 90ff8a6a..3285fc57 100644
--- a/src/cairo-gl-glyphs.c
+++ b/src/cairo-gl-glyphs.c
@@ -124,6 +124,7 @@ _cairo_gl_glyph_cache_add_glyph (cairo_gl_context_t *ctx,
&glyph_private->base,
cache,
_cairo_gl_glyph_fini);
+ glyph_private->node.owner = (void*)scaled_glyph;
scaled_glyph->dev_private = glyph_private;
scaled_glyph->dev_private_key = cache;
@@ -205,16 +206,6 @@ _cairo_gl_glyph_cache_unlock (cairo_gl_glyph_cache_t *cache)
_cairo_rtree_unpin (&cache->rtree);
}
-static void
-_cairo_gl_font_fini (cairo_scaled_font_private_t *_priv,
- cairo_scaled_font_t *scaled_font)
-{
- cairo_gl_font_t *priv = (cairo_gl_font_t *)_priv;
-
- cairo_list_del (&priv->link);
- free (priv);
-}
-
static cairo_status_t
render_glyphs (cairo_gl_surface_t *dst,
int dst_x, int dst_y,
@@ -456,10 +447,23 @@ _cairo_gl_glyph_cache_init (cairo_gl_glyph_cache_t *cache)
sizeof (cairo_gl_glyph_t));
}
+static void
+_cairo_gl_glyph_cache_fini_glyph (cairo_rtree_node_t *node,
+ void *cache)
+{
+ cairo_gl_glyph_t *glyph_private = (cairo_gl_glyph_t *) node;
+ if (glyph_private->node.owner) {
+ cairo_list_del (&glyph_private->base.link);
+ glyph_private->node.owner = NULL;
+ }
+}
+
void
_cairo_gl_glyph_cache_fini (cairo_gl_context_t *ctx,
cairo_gl_glyph_cache_t *cache)
{
+ _cairo_rtree_foreach (&cache->rtree,
+ _cairo_gl_glyph_cache_fini_glyph, NULL);
_cairo_rtree_fini (&cache->rtree);
cairo_surface_destroy (&cache->operand.texture.surface->base);
}
diff --git a/src/cairo-rtree-private.h b/src/cairo-rtree-private.h
index 11079e7e..3289f795 100644
--- a/src/cairo-rtree-private.h
+++ b/src/cairo-rtree-private.h
@@ -112,6 +112,11 @@ _cairo_rtree_evict_random (cairo_rtree_t *rtree,
int height,
cairo_rtree_node_t **out);
+cairo_private void
+_cairo_rtree_foreach (cairo_rtree_t *rtree,
+ void (*func)(cairo_rtree_node_t *, void *data),
+ void *data);
+
static inline void *
_cairo_rtree_pin (cairo_rtree_t *rtree, cairo_rtree_node_t *node)
{
diff --git a/src/cairo-rtree.c b/src/cairo-rtree.c
index d6e57916..94af45b8 100644
--- a/src/cairo-rtree.c
+++ b/src/cairo-rtree.c
@@ -368,6 +368,34 @@ _cairo_rtree_reset (cairo_rtree_t *rtree)
cairo_list_add (&rtree->root.link, &rtree->available);
}
+static void
+_cairo_rtree_node_foreach (cairo_rtree_node_t *node,
+ void (*func)(cairo_rtree_node_t *, void *data),
+ void *data)
+{
+ int i;
+
+ for (i = 0; i < 4 && node->children[i] != NULL; i++)
+ _cairo_rtree_node_foreach(node->children[i], func, data);
+
+ func(node, data);
+}
+
+void
+_cairo_rtree_foreach (cairo_rtree_t *rtree,
+ void (*func)(cairo_rtree_node_t *, void *data),
+ void *data)
+{
+ int i;
+
+ if (rtree->root.state == CAIRO_RTREE_NODE_OCCUPIED) {
+ func(&rtree->root, data);
+ } else {
+ for (i = 0; i < 4 && rtree->root.children[i] != NULL; i++)
+ _cairo_rtree_node_foreach (rtree->root.children[i], func, data);
+ }
+}
+
void
_cairo_rtree_fini (cairo_rtree_t *rtree)
{