diff options
author | Arik Devens <arik@src.gnome.org> | 2001-01-31 09:27:01 +0000 |
---|---|---|
committer | Arik Devens <arik@src.gnome.org> | 2001-01-31 09:27:01 +0000 |
commit | c6d2a19ad7cb45ee3b781286c50757e1927048a4 (patch) | |
tree | 8e91fda9a24e2f1e044550a19bd769f6afd5d640 /librsvg | |
parent | 0f36e5658943d1d90ac8cbde5776c4c9c89c44b9 (diff) | |
download | nautilus-c6d2a19ad7cb45ee3b781286c50757e1927048a4.tar.gz |
Refactored the glyph cache to be a bit smarter about when to insert and remove from its cache.
Diffstat (limited to 'librsvg')
-rw-r--r-- | librsvg/rsvg-ft.c | 84 |
1 files changed, 43 insertions, 41 deletions
diff --git a/librsvg/rsvg-ft.c b/librsvg/rsvg-ft.c index 694e74ffa..c2a24ac6b 100644 --- a/librsvg/rsvg-ft.c +++ b/librsvg/rsvg-ft.c @@ -199,43 +199,48 @@ rsvg_ft_glyph_bytes (RsvgFTGlyph *glyph) /** * rsvg_gt_glyph_evict: Evict lru glyph from glyph cache. * @ctx: The RsvgFT context. + * @amount_to_evict: The amount above the high water mark for the cache + * that we are. * - * Chooses the least recently used glyph that without a refcount, and - * evicts it. - * - * Return value: true if a glyph was successfully evicted. + * Evicts any glyphs with a reference count of 1 until it is either + * below the high water mark or out of glyphs. **/ -static gboolean -rsvg_ft_glyph_evict (RsvgFTCtx *ctx) +static void +rsvg_ft_glyph_evict (RsvgFTCtx *ctx, int amount_to_evict) { RsvgFTGlyphCacheEntry *victim; RsvgFTGlyph *glyph; - - for (victim = ctx->glyph_last; victim != NULL; victim = victim->prev) - if (victim->glyph->refcnt == 1) - break; - - if (victim == NULL) - return FALSE; - - if (victim->prev != NULL) - victim->prev->next = victim->next; - else - ctx->glyph_first = victim->next; - if (victim->next != NULL) - victim->next->prev = victim->prev; - else - ctx->glyph_last = victim->prev; - - glyph = victim->glyph; - ctx->glyph_bytes -= rsvg_ft_glyph_bytes (glyph); - rsvg_ft_glyph_unref (glyph); - - g_hash_table_remove (ctx->glyph_hash_table, victim->desc); - g_free (victim->desc); - g_free (victim); - - return TRUE; + int evicted_so_far = 0; + + for (victim = ctx->glyph_last; victim != NULL; victim = victim->prev) { + if (victim->glyph->refcnt == 1) { + evicted_so_far += rsvg_ft_glyph_bytes (victim->glyph); + + if (victim->prev != NULL) { + victim->prev->next = victim->next; + } + else { + ctx->glyph_first = victim->next; + } + if (victim->next != NULL) { + victim->next->prev = victim->prev; + } else { + ctx->glyph_last = victim->prev; + } + + glyph = victim->glyph; + ctx->glyph_bytes -= rsvg_ft_glyph_bytes (glyph); + rsvg_ft_glyph_unref (glyph); + + g_hash_table_remove (ctx->glyph_hash_table, victim->desc); + g_free (victim->desc); + g_free (victim); + + if (evicted_so_far >= amount_to_evict) { + break; + } + } + } } /** @@ -248,7 +253,7 @@ rsvg_ft_glyph_evict (RsvgFTCtx *ctx) * * Inserts @glyph into the glyph cache under the glyph descriptor @desc. * This routine also takes care of evicting glyphs when the cache - * becomes full. + * reaches its high water limit. **/ static void rsvg_ft_glyph_insert (RsvgFTCtx *ctx, const RsvgFTGlyphDesc *desc, @@ -259,14 +264,11 @@ rsvg_ft_glyph_insert (RsvgFTCtx *ctx, const RsvgFTGlyphDesc *desc, ctx->glyph_bytes += rsvg_ft_glyph_bytes (glyph); - /* check for full cache and evict if so */ - while (ctx->glyph_bytes > ctx->glyph_bytes_max) { - if (!rsvg_ft_glyph_evict (ctx)) { - g_warning ("rsvg_ft_glyph_insert: unable to free any glyph cache entry, suggesting resource leak."); - break; - } + if ((ctx->glyph_bytes < ctx->glyph_bytes_max) && + (ctx->glyph_bytes + rsvg_ft_glyph_bytes (glyph) >= ctx->glyph_bytes_max)) { + rsvg_ft_glyph_evict (ctx, ctx->glyph_bytes + rsvg_ft_glyph_bytes (glyph) - ctx->glyph_bytes_max); } - + new_desc = g_new (RsvgFTGlyphDesc, 1); memcpy (new_desc, desc, sizeof (RsvgFTGlyphDesc)); entry = g_new (RsvgFTGlyphCacheEntry, 1); @@ -864,7 +866,7 @@ rsvg_ft_measure_or_render_string (RsvgFTCtx *ctx, } if (glyph_index != 0) last_glyph = glyph_index; - + glyph = rsvg_ft_get_glyph_cached (ctx, fh, glyph_index, sx, sy, glyph_affine, glyph_xy + n_glyphs * 2); |