summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgreg <greg@blackbox>2009-06-18 14:09:35 +0200
committergreg <greg@blackbox>2009-06-19 05:17:22 +0200
commit2f59cd0e21b3f4a953b67525fa56b133d4d6b352 (patch)
tree14d1c2ebf7cb0aa2f147f13472d4536c3c34c908
parent3dcfa5a61e58068b38fb97477e8935550ca8c683 (diff)
downloadlibass-2f59cd0e21b3f4a953b67525fa56b133d4d6b352.tar.bz2
libass-2f59cd0e21b3f4a953b67525fa56b133d4d6b352.tar.xz
Remove cache globals; move cache data into a separate cache_store struct
that is part of ass_renderer.
-rw-r--r--libass/ass_cache.c86
-rw-r--r--libass/ass_cache.h81
-rw-r--r--libass/ass_font.c6
-rw-r--r--libass/ass_font.h3
-rw-r--r--libass/ass_render.c50
5 files changed, 117 insertions, 109 deletions
diff --git a/libass/ass_cache.c b/libass/ass_cache.c
index 2e941c0..69efa55 100644
--- a/libass/ass_cache.c
+++ b/libass/ass_cache.c
@@ -37,26 +37,6 @@
#include "ass_cache.h"
-typedef struct hashmap_item_s {
- void* key;
- void* value;
- struct hashmap_item_s* next;
-} hashmap_item_t;
-typedef hashmap_item_t* hashmap_item_p;
-
-struct hashmap_s {
- int nbuckets;
- size_t key_size, value_size;
- hashmap_item_p* root;
- hashmap_item_dtor_t item_dtor; // a destructor for hashmap key/value pairs
- hashmap_key_compare_t key_compare;
- hashmap_hash_t hash;
- // stats
- int hit_count;
- int miss_count;
- int count;
-};
-
#define FNV1_32A_INIT (unsigned)0x811c9dc5
static inline unsigned fnv_32a_buf(void* buf, size_t len, unsigned hval)
@@ -171,8 +151,6 @@ void* hashmap_find(hashmap_t* map, void* key)
//---------------------------------
// font cache
-hashmap_t* font_cache;
-
static unsigned font_desc_hash(void* buf, size_t len)
{
ass_font_desc_t* desc = buf;
@@ -203,7 +181,7 @@ static void font_hash_dtor(void* key, size_t key_size, void* value, size_t value
free(key);
}
-ass_font_t* ass_font_cache_find(ass_font_desc_t* desc)
+ass_font_t* ass_font_cache_find(hashmap_t* font_cache, ass_font_desc_t* desc)
{
return hashmap_find(font_cache, desc);
}
@@ -212,20 +190,22 @@ ass_font_t* ass_font_cache_find(ass_font_desc_t* desc)
* \brief Add a face struct to cache.
* \param font font struct
*/
-void* ass_font_cache_add(ass_font_t* font)
+void* ass_font_cache_add(hashmap_t* font_cache, ass_font_t* font)
{
return hashmap_insert(font_cache, &(font->desc), font);
}
-void ass_font_cache_init(void)
+hashmap_t* ass_font_cache_init(void)
{
+ hashmap_t* font_cache;
font_cache = hashmap_init(sizeof(ass_font_desc_t),
sizeof(ass_font_t),
1000,
font_hash_dtor, font_compare, font_desc_hash);
+ return font_cache;
}
-void ass_font_cache_done(void)
+void ass_font_cache_done(hashmap_t* font_cache)
{
hashmap_done(font_cache);
}
@@ -240,8 +220,6 @@ void ass_font_cache_done(void)
//---------------------------------
// bitmap cache
-hashmap_t* bitmap_cache;
-
static void bitmap_hash_dtor(void* key, size_t key_size, void* value, size_t value_size)
{
bitmap_hash_val_t* v = value;
@@ -252,7 +230,7 @@ static void bitmap_hash_dtor(void* key, size_t key_size, void* value, size_t val
free(value);
}
-void* cache_add_bitmap(bitmap_hash_key_t* key, bitmap_hash_val_t* val)
+void* cache_add_bitmap(hashmap_t* bitmap_cache, bitmap_hash_key_t* key, bitmap_hash_val_t* val)
{
return hashmap_insert(bitmap_cache, key, val);
}
@@ -262,36 +240,36 @@ void* cache_add_bitmap(bitmap_hash_key_t* key, bitmap_hash_val_t* val)
* \param key hash key
* \return requested hash val or 0 if not found
*/
-bitmap_hash_val_t* cache_find_bitmap(bitmap_hash_key_t* key)
+bitmap_hash_val_t* cache_find_bitmap(hashmap_t* bitmap_cache, bitmap_hash_key_t* key)
{
return hashmap_find(bitmap_cache, key);
}
-void ass_bitmap_cache_init(void)
+hashmap_t* ass_bitmap_cache_init(void)
{
+ hashmap_t* bitmap_cache;
bitmap_cache = hashmap_init(sizeof(bitmap_hash_key_t),
sizeof(bitmap_hash_val_t),
0xFFFF + 13,
bitmap_hash_dtor, bitmap_compare,
bitmap_hash);
+ return bitmap_cache;
}
-void ass_bitmap_cache_done(void)
+void ass_bitmap_cache_done(hashmap_t* bitmap_cache)
{
hashmap_done(bitmap_cache);
}
-void ass_bitmap_cache_reset(void)
+hashmap_t* ass_bitmap_cache_reset(hashmap_t* bitmap_cache)
{
- ass_bitmap_cache_done();
- ass_bitmap_cache_init();
+ ass_bitmap_cache_done(bitmap_cache);
+ return ass_bitmap_cache_init();
}
//---------------------------------
// glyph cache
-hashmap_t* glyph_cache;
-
static void glyph_hash_dtor(void* key, size_t key_size, void* value, size_t value_size)
{
glyph_hash_val_t* v = value;
@@ -301,7 +279,7 @@ static void glyph_hash_dtor(void* key, size_t key_size, void* value, size_t valu
free(value);
}
-void* cache_add_glyph(glyph_hash_key_t* key, glyph_hash_val_t* val)
+void* cache_add_glyph(hashmap_t* glyph_cache, glyph_hash_key_t* key, glyph_hash_val_t* val)
{
return hashmap_insert(glyph_cache, key, val);
}
@@ -311,36 +289,36 @@ void* cache_add_glyph(glyph_hash_key_t* key, glyph_hash_val_t* val)
* \param key hash key
* \return requested hash val or 0 if not found
*/
-glyph_hash_val_t* cache_find_glyph(glyph_hash_key_t* key)
+glyph_hash_val_t* cache_find_glyph(hashmap_t* glyph_cache, glyph_hash_key_t* key)
{
return hashmap_find(glyph_cache, key);
}
-void ass_glyph_cache_init(void)
+hashmap_t* ass_glyph_cache_init(void)
{
+ hashmap_t* glyph_cache;
glyph_cache = hashmap_init(sizeof(glyph_hash_key_t),
sizeof(glyph_hash_val_t),
0xFFFF + 13,
glyph_hash_dtor, glyph_compare, glyph_hash);
+ return glyph_cache;
}
-void ass_glyph_cache_done(void)
+void ass_glyph_cache_done(hashmap_t* glyph_cache)
{
hashmap_done(glyph_cache);
}
-void ass_glyph_cache_reset(void)
+hashmap_t* ass_glyph_cache_reset(hashmap_t* glyph_cache)
{
- ass_glyph_cache_done();
- ass_glyph_cache_init();
+ ass_glyph_cache_done(glyph_cache);
+ return ass_glyph_cache_init();
}
//---------------------------------
// composite cache
-hashmap_t* composite_cache;
-
static void composite_hash_dtor(void* key, size_t key_size, void* value, size_t value_size)
{
composite_hash_val_t* v = value;
@@ -350,7 +328,7 @@ static void composite_hash_dtor(void* key, size_t key_size, void* value, size_t
free(value);
}
-void* cache_add_composite(composite_hash_key_t* key, composite_hash_val_t* val)
+void* cache_add_composite(hashmap_t* composite_cache, composite_hash_key_t* key, composite_hash_val_t* val)
{
return hashmap_insert(composite_cache, key, val);
}
@@ -360,27 +338,29 @@ void* cache_add_composite(composite_hash_key_t* key, composite_hash_val_t* val)
* \param key hash key
* \return requested hash val or 0 if not found
*/
-composite_hash_val_t* cache_find_composite(composite_hash_key_t* key)
+composite_hash_val_t* cache_find_composite(hashmap_t* composite_cache, composite_hash_key_t* key)
{
return hashmap_find(composite_cache, key);
}
-void ass_composite_cache_init(void)
+hashmap_t* ass_composite_cache_init(void)
{
+ hashmap_t* composite_cache;
composite_cache = hashmap_init(sizeof(composite_hash_key_t),
sizeof(composite_hash_val_t),
0xFFFF + 13,
composite_hash_dtor, NULL, NULL);
+ return composite_cache;
}
-void ass_composite_cache_done(void)
+void ass_composite_cache_done(hashmap_t* composite_cache)
{
hashmap_done(composite_cache);
}
-void ass_composite_cache_reset(void)
+hashmap_t* ass_composite_cache_reset(hashmap_t* composite_cache)
{
- ass_composite_cache_done();
- ass_composite_cache_init();
+ ass_composite_cache_done(composite_cache);
+ return ass_composite_cache_init();
}
diff --git a/libass/ass_cache.h b/libass/ass_cache.h
index f227303..55c543e 100644
--- a/libass/ass_cache.h
+++ b/libass/ass_cache.h
@@ -27,10 +27,41 @@
#include "ass_font.h"
#include "ass_bitmap.h"
-void ass_font_cache_init(void);
-ass_font_t* ass_font_cache_find(ass_font_desc_t* desc);
-void* ass_font_cache_add(ass_font_t* font);
-void ass_font_cache_done(void);
+typedef void (*hashmap_item_dtor_t)(void* key, size_t key_size, void* value, size_t value_size);
+typedef int (*hashmap_key_compare_t)(void* key1, void* key2, size_t key_size);
+typedef unsigned (*hashmap_hash_t)(void* key, size_t key_size);
+
+typedef struct hashmap_item_s {
+ void* key;
+ void* value;
+ struct hashmap_item_s* next;
+} hashmap_item_t;
+typedef hashmap_item_t* hashmap_item_p;
+
+typedef struct hashmap_s {
+ int nbuckets;
+ size_t key_size, value_size;
+ hashmap_item_p* root;
+ hashmap_item_dtor_t item_dtor; // a destructor for hashmap key/value pairs
+ hashmap_key_compare_t key_compare;
+ hashmap_hash_t hash;
+ // stats
+ int hit_count;
+ int miss_count;
+ int count;
+} hashmap_t;
+
+hashmap_t* hashmap_init(size_t key_size, size_t value_size, int nbuckets,
+ hashmap_item_dtor_t item_dtor, hashmap_key_compare_t key_compare,
+ hashmap_hash_t hash);
+void hashmap_done(hashmap_t* map);
+void* hashmap_insert(hashmap_t* map, void* key, void* value);
+void* hashmap_find(hashmap_t* map, void* key);
+
+hashmap_t* ass_font_cache_init(void);
+ass_font_t* ass_font_cache_find(hashmap_t*, ass_font_desc_t* desc);
+void* ass_font_cache_add(hashmap_t*, ass_font_t* font);
+void ass_font_cache_done(hashmap_t*);
// Create definitions for bitmap_hash_key and glyph_hash_key
#define CREATE_STRUCT_DEFINITIONS
@@ -42,11 +73,11 @@ typedef struct bitmap_hash_val_s {
bitmap_t* bm_s;
} bitmap_hash_val_t;
-void ass_bitmap_cache_init(void);
-void* cache_add_bitmap(bitmap_hash_key_t* key, bitmap_hash_val_t* val);
-bitmap_hash_val_t* cache_find_bitmap(bitmap_hash_key_t* key);
-void ass_bitmap_cache_reset(void);
-void ass_bitmap_cache_done(void);
+hashmap_t* ass_bitmap_cache_init(void);
+void* cache_add_bitmap(hashmap_t*, bitmap_hash_key_t* key, bitmap_hash_val_t* val);
+bitmap_hash_val_t* cache_find_bitmap(hashmap_t* bitmap_cache, bitmap_hash_key_t* key);
+hashmap_t* ass_bitmap_cache_reset(hashmap_t* bitmap_cache);
+void ass_bitmap_cache_done(hashmap_t* bitmap_cache);
// Cache for composited bitmaps
@@ -62,11 +93,11 @@ typedef struct composite_hash_val_s {
unsigned char* b;
} composite_hash_val_t;
-void ass_composite_cache_init(void);
-void* cache_add_composite(composite_hash_key_t* key, composite_hash_val_t* val);
-composite_hash_val_t* cache_find_composite(composite_hash_key_t* key);
-void ass_composite_cache_reset(void);
-void ass_composite_cache_done(void);
+hashmap_t* ass_composite_cache_init(void);
+void* cache_add_composite(hashmap_t*, composite_hash_key_t* key, composite_hash_val_t* val);
+composite_hash_val_t* cache_find_composite(hashmap_t* composite_cache, composite_hash_key_t* key);
+hashmap_t* ass_composite_cache_reset(hashmap_t* composite_cache);
+void ass_composite_cache_done(hashmap_t* composite_cache);
typedef struct glyph_hash_val_s {
@@ -76,22 +107,10 @@ typedef struct glyph_hash_val_s {
FT_Vector advance; // 26.6, advance distance to the next bitmap in line
} glyph_hash_val_t;
-void ass_glyph_cache_init(void);
-void* cache_add_glyph(glyph_hash_key_t* key, glyph_hash_val_t* val);
-glyph_hash_val_t* cache_find_glyph(glyph_hash_key_t* key);
-void ass_glyph_cache_reset(void);
-void ass_glyph_cache_done(void);
-
-typedef struct hashmap_s hashmap_t;
-typedef void (*hashmap_item_dtor_t)(void* key, size_t key_size, void* value, size_t value_size);
-typedef int (*hashmap_key_compare_t)(void* key1, void* key2, size_t key_size);
-typedef unsigned (*hashmap_hash_t)(void* key, size_t key_size);
-
-hashmap_t* hashmap_init(size_t key_size, size_t value_size, int nbuckets,
- hashmap_item_dtor_t item_dtor, hashmap_key_compare_t key_compare,
- hashmap_hash_t hash);
-void hashmap_done(hashmap_t* map);
-void* hashmap_insert(hashmap_t* map, void* key, void* value);
-void* hashmap_find(hashmap_t* map, void* key);
+hashmap_t* ass_glyph_cache_init(void);
+void* cache_add_glyph(hashmap_t*, glyph_hash_key_t* key, glyph_hash_val_t* val);
+glyph_hash_val_t* cache_find_glyph(hashmap_t* glyph_cache, glyph_hash_key_t* key);
+hashmap_t* ass_glyph_cache_reset(hashmap_t* glyph_cache);
+void ass_glyph_cache_done(hashmap_t* glyph_cache);
#endif /* LIBASS_CACHE_H */
diff --git a/libass/ass_font.c b/libass/ass_font.c
index 73ee1c4..57b2fdf 100644
--- a/libass/ass_font.c
+++ b/libass/ass_font.c
@@ -157,13 +157,13 @@ static int add_face(void* fc_priv, ass_font_t* font, uint32_t ch)
/**
* \brief Create a new ass_font_t according to "desc" argument
*/
-ass_font_t* ass_font_new(ass_library_t* library, FT_Library ftlibrary, void* fc_priv, ass_font_desc_t* desc)
+ass_font_t* ass_font_new(void* font_cache, ass_library_t* library, FT_Library ftlibrary, void* fc_priv, ass_font_desc_t* desc)
{
int error;
ass_font_t* fontp;
ass_font_t font;
- fontp = ass_font_cache_find(desc);
+ fontp = ass_font_cache_find((hashmap_t*)font_cache, desc);
if (fontp)
return fontp;
@@ -184,7 +184,7 @@ ass_font_t* ass_font_new(ass_library_t* library, FT_Library ftlibrary, void* fc_
free(font.desc.family);
return 0;
} else
- return ass_font_cache_add(&font);
+ return ass_font_cache_add((hashmap_t*)font_cache, &font);
}
/**
diff --git a/libass/ass_font.h b/libass/ass_font.h
index 5204318..6a6793d 100644
--- a/libass/ass_font.h
+++ b/libass/ass_font.h
@@ -49,7 +49,8 @@ typedef struct ass_font_s {
double size;
} ass_font_t;
-ass_font_t* ass_font_new(ass_library_t* library, FT_Library ftlibrary, void* fc_priv, ass_font_desc_t* desc);
+// FIXME: passing the hashmap via a void pointer is very ugly.
+ass_font_t* ass_font_new(void* font_cache, ass_library_t* library, FT_Library ftlibrary, void* fc_priv, ass_font_desc_t* desc);
void ass_font_set_transform(ass_font_t* font, double scale_x, double scale_y, FT_Vector* v);
void ass_font_set_size(ass_font_t* font, double size);
void ass_font_get_asc_desc(ass_font_t* font, uint32_t ch, int* asc, int* desc);
diff --git a/libass/ass_render.c b/libass/ass_render.c
index 61a2b42..8c2af83 100644
--- a/libass/ass_render.c
+++ b/libass/ass_render.c
@@ -173,6 +173,13 @@ typedef struct render_context_s {
} render_context_t;
+typedef struct cache_store_s {
+ hashmap_t* font_cache;
+ hashmap_t* glyph_cache;
+ hashmap_t* bitmap_cache;
+ hashmap_t* composite_cache;
+} cache_store_t;
+
struct ass_renderer_s {
ass_library_t* library;
FT_Library ftlibrary;
@@ -201,6 +208,7 @@ struct ass_renderer_s {
render_context_t state;
text_info_t text_info;
+ cache_store_t cache;
};
struct render_priv_s {
@@ -269,10 +277,10 @@ ass_renderer_t* ass_renderer_init(ass_library_t* library)
priv->ftlibrary = ft;
// images_root and related stuff is zero-filled in calloc
- ass_font_cache_init();
- ass_bitmap_cache_init();
- ass_composite_cache_init();
- ass_glyph_cache_init();
+ priv->cache.font_cache = ass_font_cache_init();
+ priv->cache.bitmap_cache = ass_bitmap_cache_init();
+ priv->cache.composite_cache = ass_composite_cache_init();
+ priv->cache.glyph_cache = ass_glyph_cache_init();
priv->text_info.glyphs = calloc(MAX_GLYPHS, sizeof(glyph_info_t));
@@ -285,10 +293,10 @@ ass_init_exit:
void ass_renderer_done(ass_renderer_t* render_priv)
{
- ass_font_cache_done();
- ass_bitmap_cache_done();
- ass_composite_cache_done();
- ass_glyph_cache_done();
+ ass_font_cache_done(render_priv->cache.font_cache);
+ ass_bitmap_cache_done(render_priv->cache.bitmap_cache);
+ ass_composite_cache_done(render_priv->cache.composite_cache);
+ ass_glyph_cache_done(render_priv->cache.glyph_cache);
if (render_priv->state.stroker) {
FT_Stroker_Done(render_priv->state.stroker);
render_priv->state.stroker = 0;
@@ -405,7 +413,7 @@ static ass_image_t** render_glyph(ass_renderer_t* render_priv, bitmap_t* bm, int
* Mainly useful for translucent glyphs and especially borders, to avoid the
* luminance adding up where they overlap (which looks ugly)
*/
-static void render_overlap(ass_image_t** last_tail, ass_image_t** tail, bitmap_hash_key_t *last_hash, bitmap_hash_key_t* hash) {
+static void render_overlap(ass_renderer_t* render_priv, ass_image_t** last_tail, ass_image_t** tail, bitmap_hash_key_t *last_hash, bitmap_hash_key_t* hash) {
int left, top, bottom, right;
int old_left, old_top, w, h, cur_left, cur_top;
int x, y, opos, cpos;
@@ -458,7 +466,7 @@ static void render_overlap(ass_image_t** last_tail, ass_image_t** tail, bitmap_h
hk.ay = ay;
hk.bx = bx;
hk.by = by;
- hv = cache_find_composite(&hk);
+ hv = cache_find_composite(render_priv->cache.composite_cache, &hk);
if (hv) {
(*last_tail)->bitmap = hv->a;
(*tail)->bitmap = hv->b;
@@ -489,7 +497,7 @@ static void render_overlap(ass_image_t** last_tail, ass_image_t** tail, bitmap_h
hv = calloc(1, sizeof(*hv));
hv->a = (*last_tail)->bitmap;
hv->b = (*tail)->bitmap;
- cache_add_composite(nhk, hv);
+ cache_add_composite(render_priv->cache.composite_cache, nhk, hv);
}
/**
@@ -520,7 +528,7 @@ static ass_image_t* render_text(ass_renderer_t* render_priv, int dst_x, int dst_
here_tail = tail;
tail = render_glyph(render_priv, bm, pen_x, pen_y, info->c[3], 0, 1000000, tail);
if (last_tail && tail != here_tail && ((info->c[3] & 0xff) > 0))
- render_overlap(last_tail, here_tail, last_hash, &info->hash_key);
+ render_overlap(render_priv, last_tail, here_tail, last_hash, &info->hash_key);
last_tail = here_tail;
last_hash = &info->hash_key;
}
@@ -541,7 +549,7 @@ static ass_image_t* render_text(ass_renderer_t* render_priv, int dst_x, int dst_
here_tail = tail;
tail = render_glyph(render_priv, bm, pen_x, pen_y, info->c[2], 0, 1000000, tail);
if (last_tail && tail != here_tail && ((info->c[2] & 0xff) > 0))
- render_overlap(last_tail, here_tail, last_hash, &info->hash_key);
+ render_overlap(render_priv, last_tail, here_tail, last_hash, &info->hash_key);
last_tail = here_tail;
last_hash = &info->hash_key;
}
@@ -683,7 +691,7 @@ static void update_font(ass_renderer_t* render_priv)
else if (val == 1) val = 110; //italic
desc.italic = val;
- render_priv->state.font = ass_font_new(render_priv->library, render_priv->ftlibrary, render_priv->fontconfig_priv, &desc);
+ render_priv->state.font = ass_font_new(render_priv->cache.font_cache, render_priv->library, render_priv->ftlibrary, render_priv->fontconfig_priv, &desc);
free(desc.family);
if (render_priv->state.font)
@@ -1438,7 +1446,7 @@ static void get_outline_glyph(ass_renderer_t* render_priv, int symbol, glyph_inf
memset(info, 0, sizeof(glyph_info_t));
- val = cache_find_glyph(&key);
+ val = cache_find_glyph(render_priv->cache.glyph_cache, &key);
if (val) {
FT_Glyph_Copy(val->glyph, &info->glyph);
if (val->outline_glyph)
@@ -1469,7 +1477,7 @@ static void get_outline_glyph(ass_renderer_t* render_priv, int symbol, glyph_inf
FT_Glyph_Copy(info->outline_glyph, &v.outline_glyph);
v.advance = info->advance;
v.bbox_scaled = info->bbox;
- cache_add_glyph(&key, &v);
+ cache_add_glyph(render_priv->cache.glyph_cache, &key, &v);
}
}
@@ -1488,7 +1496,7 @@ static void get_bitmap_glyph(ass_renderer_t* render_priv, glyph_info_t* info)
bitmap_hash_val_t* val;
bitmap_hash_key_t* key = &info->hash_key;
- val = cache_find_bitmap(key);
+ val = cache_find_bitmap(render_priv->cache.bitmap_cache, key);
/* val = 0; */
if (val) {
@@ -1519,7 +1527,7 @@ static void get_bitmap_glyph(ass_renderer_t* render_priv, glyph_info_t* info)
hash_val.bm_o = info->bm_o;
hash_val.bm = info->bm;
hash_val.bm_s = info->bm_s;
- cache_add_bitmap(&(info->hash_key), &hash_val);
+ cache_add_bitmap(render_priv->cache.bitmap_cache, &(info->hash_key), &hash_val);
}
}
// deallocate glyphs
@@ -2197,9 +2205,9 @@ static void ass_free_images(ass_image_t* img)
static void ass_reconfigure(ass_renderer_t* priv)
{
priv->render_id = ++last_render_id;
- ass_glyph_cache_reset();
- ass_bitmap_cache_reset();
- ass_composite_cache_reset();
+ priv->cache.glyph_cache = ass_glyph_cache_reset(priv->cache.glyph_cache);
+ priv->cache.bitmap_cache = ass_bitmap_cache_reset(priv->cache.bitmap_cache);
+ priv->cache.composite_cache = ass_composite_cache_reset(priv->cache.composite_cache);
ass_free_images(priv->prev_images_root);
priv->prev_images_root = 0;
}