summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrigori Goronzy <greg@blackbox>2010-07-22 21:40:19 +0200
committerGrigori Goronzy <greg@blackbox>2010-07-22 21:42:56 +0200
commit87c7e53c357375fe19dada6e2e3cc87464ae8ec5 (patch)
tree65347498472f013628c5472c0eb40420c848a13a
parent3e53f1cf3db9b5e41a7f6e15605607b91892e351 (diff)
downloadlibass-87c7e53c357375fe19dada6e2e3cc87464ae8ec5.tar.bz2
libass-87c7e53c357375fe19dada6e2e3cc87464ae8ec5.tar.xz
Cache vector clip masks
Cache pre-rasterized vector clip masks, big speedup if vector clipping is used extensively.
-rw-r--r--Changelog3
-rw-r--r--libass/ass_render.c42
2 files changed, 34 insertions, 11 deletions
diff --git a/Changelog b/Changelog
index 376b337..ec94382 100644
--- a/Changelog
+++ b/Changelog
@@ -5,6 +5,9 @@ libass (0.9.10)
* Add ass_flush_events API function
* Improve fullname font matching
* Better PAR correction if text transforms are used
+ * Performance improvements
+ * Cache vector clip masks
+ * Avoid unnecessary glyph copies
libass (0.9.9)
* Parse numbers in a locale-independent way
diff --git a/libass/ass_render.c b/libass/ass_render.c
index f013591..59d13ed 100644
--- a/libass/ass_render.c
+++ b/libass/ass_render.c
@@ -579,21 +579,42 @@ static void blend_vector_clip(ASS_Renderer *render_priv,
FT_BitmapGlyph clip_bm;
ASS_Image *cur;
ASS_Drawing *drawing = render_priv->state.clip_drawing;
+ GlyphHashKey key;
+ GlyphHashValue *val;
int error;
if (!drawing)
return;
- // Rasterize it
- FT_Glyph_Copy((FT_Glyph) drawing->glyph, &glyph);
- error = FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1);
- if (error) {
- ass_msg(render_priv->library, MSGL_WARN,
- "Clip vector rasterization failed: %d. Skipping.", error);
- goto blend_vector_exit;
+ // Try to get mask from cache
+ ass_drawing_hash(drawing);
+ memset(&key, 0, sizeof(key));
+ key.ch = -2;
+ key.drawing_hash = drawing->hash;
+ val = cache_find_glyph(render_priv->cache.glyph_cache, &key);
+
+ if (val) {
+ clip_bm = (FT_BitmapGlyph) val->glyph;
+ } else {
+ GlyphHashValue v;
+
+ // Not found in cache, rasterize it
+ glyph = (FT_Glyph) drawing->glyph;
+ error = FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1);
+ if (error) {
+ ass_msg(render_priv->library, MSGL_WARN,
+ "Clip vector rasterization failed: %d. Skipping.", error);
+ FT_Done_Glyph(glyph);
+ goto blend_vector_exit;
+ }
+ clip_bm = (FT_BitmapGlyph) glyph;
+ clip_bm->top = -clip_bm->top;
+
+ // Add to cache
+ memset(&v, 0, sizeof(v));
+ v.glyph = glyph;
+ cache_add_glyph(render_priv->cache.glyph_cache, &key, &v);
}
- clip_bm = (FT_BitmapGlyph) glyph;
- clip_bm->top = -clip_bm->top;
assert(clip_bm->bitmap.pitch >= 0);
@@ -672,8 +693,6 @@ static void blend_vector_clip(ASS_Renderer *render_priv,
cur->bitmap = nbuffer;
}
- // Free clip vector and its bitmap, we don't need it anymore
- FT_Done_Glyph(glyph);
blend_vector_exit:
ass_drawing_free(render_priv->state.clip_drawing);
render_priv->state.clip_drawing = 0;
@@ -1030,6 +1049,7 @@ get_outline_glyph(ASS_Renderer *render_priv, int symbol, GlyphInfo *info,
key.drawing_hash = drawing->hash;
// not very clean, but works
key.size = drawing->scale;
+ key.ch = -1;
} else {
key.font = render_priv->state.font;
key.size = render_priv->state.font_size;