From: raster Date: Thu, 28 Jun 2012 10:13:05 +0000 (+0000) Subject: fix refcounting issue with font instances. X-Git-Tag: 2.0_alpha~46^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=20792cb37fc7f5942cd6b8cf1ce77d09da878d4d;p=framework%2Fuifw%2Fevas.git fix refcounting issue with font instances. git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@72990 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- diff --git a/ChangeLog b/ChangeLog index 3aa59d8..860ce21 100644 --- a/ChangeLog +++ b/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/src/lib/engines/common/evas_font.h b/src/lib/engines/common/evas_font.h index 3769b13..313c23e 100644 --- a/src/lib/engines/common/evas_font.h +++ b/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/src/lib/engines/common/evas_font_load.c b/src/lib/engines/common/evas_font_load.c index 2307fde..4024565 100644 --- a/src/lib/engines/common/evas_font_load.c +++ b/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; } @@ -637,6 +619,18 @@ evas_common_font_memory_add(RGBA_Font *fn, const char *source, const char *name, } 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) { Eina_List *l; @@ -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/src/lib/engines/common/evas_text_utils.c b/src/lib/engines/common/evas_text_utils.c index dca75f6..c1c1a23 100644 --- a/src/lib/engines/common/evas_text_utils.c +++ b/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) {