From 6d605629cafb9e7c6bb4c923624e16062d2dee48 Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Thu, 28 Jun 2012 10:13:05 +0000 Subject: [PATCH] fix refcounting issue with font instances. SVN revision: 72990 --- legacy/evas/ChangeLog | 5 + .../evas/src/lib/engines/common/evas_font.h | 1 + .../src/lib/engines/common/evas_font_load.c | 108 ++++++++---------- .../src/lib/engines/common/evas_text_utils.c | 18 ++- 4 files changed, 71 insertions(+), 61 deletions(-) diff --git a/legacy/evas/ChangeLog b/legacy/evas/ChangeLog index 3aa59d8095..860ce218b1 100644 --- a/legacy/evas/ChangeLog +++ b/legacy/evas/ChangeLog @@ -832,3 +832,8 @@ * Handled evas_gl_make_current to return error when either surface or context is NULL. Before, when that was the case, it just did make_current(NULL, NULL) internally. + +2012-04-28 Carsten Haitzler (The Rasterman) + + * Fix font instance refcounting for textprops that hang around. + diff --git a/legacy/evas/src/lib/engines/common/evas_font.h b/legacy/evas/src/lib/engines/common/evas_font.h index 3769b13975..313c23e9b7 100644 --- a/legacy/evas/src/lib/engines/common/evas_font.h +++ b/legacy/evas/src/lib/engines/common/evas_font.h @@ -42,6 +42,7 @@ EAPI RGBA_Font *evas_common_font_load (const char *name, EAPI RGBA_Font *evas_common_font_add (RGBA_Font *fn, const char *name, int size, Font_Rend_Flags wanted_rend); EAPI RGBA_Font *evas_common_font_memory_add (RGBA_Font *fn, const char *source, const char *name, int size, const void *data, int data_size, Font_Rend_Flags wanted_rend); EAPI void evas_common_font_free (RGBA_Font *fn); +EAPI void evas_common_font_int_unref (RGBA_Font_Int *fi); EAPI void evas_common_font_hinting_set (RGBA_Font *fn, Font_Hint_Flags hinting); EAPI Eina_Bool evas_common_hinting_available (Font_Hint_Flags hinting); EAPI RGBA_Font *evas_common_font_memory_hinting_load (const char *source, const char *name, int size, const void *data, int data_size, Font_Hint_Flags hinting, Font_Rend_Flags wanted_rend); diff --git a/legacy/evas/src/lib/engines/common/evas_font_load.c b/legacy/evas/src/lib/engines/common/evas_font_load.c index 2307fde8df..4024565760 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_load.c +++ b/legacy/evas/src/lib/engines/common/evas_font_load.c @@ -80,7 +80,7 @@ _evas_common_font_int_free(RGBA_Font_Int *fi) hb_font_destroy(fi->ft.hb_font); #endif evas_common_font_source_free(fi->src); - if (fi->references == 0) fonts_lru = eina_list_remove(fonts_lru, fi); + if (fi->references <= 0) fonts_lru = eina_list_remove(fonts_lru, fi); if (fi->fash) fi->fash->freeme(fi->fash); if (fi->inuse) { @@ -509,13 +509,7 @@ evas_common_font_memory_load(const char *source, const char *name, int size, con fn = calloc(1, sizeof(RGBA_Font)); if (!fn) { - fi->references--; - if (fi->references == 0) - { - fonts_lru = eina_list_prepend(fonts_lru, fi); - evas_common_font_int_modify_cache_by(fi, 1); - evas_common_font_flush(); - } + evas_common_font_int_unref(fi); return NULL; } fn->fonts = eina_list_append(fn->fonts, fi); @@ -552,13 +546,7 @@ evas_common_font_load(const char *name, int size, Font_Rend_Flags wanted_rend) { if (evas_common_font_source_load_complete(fi->src)) { - fi->references--; - if (fi->references == 0) - { - fonts_lru = eina_list_prepend(fonts_lru, fi); - evas_common_font_int_modify_cache_by(fi, 1); - evas_common_font_flush(); - } + evas_common_font_int_unref(fi); return NULL; } } @@ -567,13 +555,7 @@ evas_common_font_load(const char *name, int size, Font_Rend_Flags wanted_rend) fn = calloc(1, sizeof(RGBA_Font)); if (!fn) { - fi->references--; - if (fi->references == 0) - { - fonts_lru = eina_list_prepend(fonts_lru, fi); - evas_common_font_int_modify_cache_by(fi, 1); - evas_common_font_flush(); - } + evas_common_font_int_unref(fi); return NULL; } @@ -636,6 +618,18 @@ evas_common_font_memory_add(RGBA_Font *fn, const char *source, const char *name, return NULL; } +EAPI void +evas_common_font_int_unref(RGBA_Font_Int *fi) +{ + fi->references--; + if (fi->references == 0) + { + fonts_lru = eina_list_append(fonts_lru, fi); + evas_common_font_int_modify_cache_by(fi, 1); + evas_common_font_flush(); + } +} + EAPI void evas_common_font_free(RGBA_Font *fn) { @@ -646,14 +640,7 @@ evas_common_font_free(RGBA_Font *fn) fn->references--; if (fn->references > 0) return; EINA_LIST_FOREACH(fn->fonts, l, fi) - { - fi->references--; - if (fi->references == 0) - { - fonts_lru = eina_list_append(fonts_lru, fi); - evas_common_font_int_modify_cache_by(fi, 1); - } - } + evas_common_font_int_unref(fi); evas_common_font_flush(); eina_list_free(fn->fonts); if (fn->fash) fn->fash->freeme(fn->fash); @@ -758,37 +745,40 @@ _evas_common_font_int_clear(RGBA_Font_Int *fi) return; } evas_common_font_int_modify_cache_by(fi, -1); - if (fi->fash) - { - for (k = 0; k <= 0xff; k++) // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16) - { - Fash_Glyph_Map2 *fmap2 = fi->fash->bucket[k]; - if (fmap2) - { - for (j = 0; j <= 0xff; j++) // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16) - { - Fash_Glyph_Map *fmap = fmap2->bucket[j]; - if (fmap) + if (fi->references <= 1) + { + if (fi->fash) + { + for (k = 0; k <= 0xff; k++) // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16) + { + Fash_Glyph_Map2 *fmap2 = fi->fash->bucket[k]; + if (fmap2) { - for (i = 0; i <= 0xff; i++) - { - RGBA_Font_Glyph *fg = fmap->item[i]; - if ((fg) && (fg != (void *)(-1))) - { - FT_Done_Glyph(fg->glyph); - /* extension calls */ - if (fg->ext_dat_free) fg->ext_dat_free(fg->ext_dat); - if (fg->glyph_out_free) fg->glyph_out_free(fg->glyph_out); - free(fg); - fmap->item[i] = NULL; - } - } + for (j = 0; j <= 0xff; j++) // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16) + { + Fash_Glyph_Map *fmap = fmap2->bucket[j]; + if (fmap) + { + for (i = 0; i <= 0xff; i++) + { + RGBA_Font_Glyph *fg = fmap->item[i]; + if ((fg) && (fg != (void *)(-1))) + { + FT_Done_Glyph(fg->glyph); + /* extension calls */ + if (fg->ext_dat_free) fg->ext_dat_free(fg->ext_dat); + if (fg->glyph_out_free) fg->glyph_out_free(fg->glyph_out); + free(fg); + fmap->item[i] = NULL; + } + } + } + } } - } - } - } - fi->fash->freeme(fi->fash); - fi->fash = NULL; + } + fi->fash->freeme(fi->fash); + fi->fash = NULL; + } } if (fi->inuse) fonts_use_usage -= fi->usage; fi->usage = 0; diff --git a/legacy/evas/src/lib/engines/common/evas_text_utils.c b/legacy/evas/src/lib/engines/common/evas_text_utils.c index dca75f6cd3..c1c1a2335e 100644 --- a/legacy/evas/src/lib/engines/common/evas_text_utils.c +++ b/legacy/evas/src/lib/engines/common/evas_text_utils.c @@ -47,6 +47,8 @@ evas_common_text_props_content_ref(Evas_Text_Props *props) return; props->info->refcount++; + if (props->font_instance) + ((RGBA_Font_Int *)props->font_instance)->references++; } void @@ -56,6 +58,12 @@ evas_common_text_props_content_unref(Evas_Text_Props *props) if (!props->info) return; + if (props->font_instance) + { + evas_common_font_int_unref(props->font_instance); + props->font_instance = NULL; + } + if (--(props->info->refcount) == 0) { if (props->bin) @@ -478,8 +486,14 @@ evas_common_text_props_content_create(void *_fi, const Eina_Unicode *text, } text_props->info = calloc(1, sizeof(Evas_Text_Props_Info)); - text_props->font_instance = fi; - + if (text_props->font_instance != fi) + { + if (text_props->font_instance) + evas_common_font_int_unref(text_props->font_instance); + text_props->font_instance = fi; + fi->references++; + } + evas_common_font_int_reload(fi); if (fi->src->current_size != fi->size) {