From 2f59cd0e21b3f4a953b67525fa56b133d4d6b352 Mon Sep 17 00:00:00 2001 From: greg Date: Thu, 18 Jun 2009 14:09:35 +0200 Subject: Remove cache globals; move cache data into a separate cache_store struct that is part of ass_renderer. --- libass/ass_cache.c | 86 ++++++++++++++++++++--------------------------------- libass/ass_cache.h | 81 ++++++++++++++++++++++++++++++------------------- libass/ass_font.c | 6 ++-- libass/ass_font.h | 3 +- libass/ass_render.c | 50 ++++++++++++++++++------------- 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; } -- cgit v1.2.3