fix refcounting issue with font instances.

SVN revision: 72990
This commit is contained in:
Carsten Haitzler 2012-06-28 10:13:05 +00:00
parent c6f644fbe0
commit 6d605629ca
4 changed files with 71 additions and 61 deletions

View File

@ -832,3 +832,8 @@
* Handled evas_gl_make_current to return error when either surface * Handled evas_gl_make_current to return error when either surface
or context is NULL. Before, when that was the case, it just did or context is NULL. Before, when that was the case, it just did
make_current(NULL, NULL) internally. make_current(NULL, NULL) internally.
2012-04-28 Carsten Haitzler (The Rasterman)
* Fix font instance refcounting for textprops that hang around.

View File

@ -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_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 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_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 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 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); 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);

View File

@ -80,7 +80,7 @@ _evas_common_font_int_free(RGBA_Font_Int *fi)
hb_font_destroy(fi->ft.hb_font); hb_font_destroy(fi->ft.hb_font);
#endif #endif
evas_common_font_source_free(fi->src); 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->fash) fi->fash->freeme(fi->fash);
if (fi->inuse) 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)); fn = calloc(1, sizeof(RGBA_Font));
if (!fn) if (!fn)
{ {
fi->references--; evas_common_font_int_unref(fi);
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();
}
return NULL; return NULL;
} }
fn->fonts = eina_list_append(fn->fonts, fi); 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)) if (evas_common_font_source_load_complete(fi->src))
{ {
fi->references--; evas_common_font_int_unref(fi);
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();
}
return NULL; 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)); fn = calloc(1, sizeof(RGBA_Font));
if (!fn) if (!fn)
{ {
fi->references--; evas_common_font_int_unref(fi);
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();
}
return NULL; return NULL;
} }
@ -636,6 +618,18 @@ evas_common_font_memory_add(RGBA_Font *fn, const char *source, const char *name,
return NULL; 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 EAPI void
evas_common_font_free(RGBA_Font *fn) evas_common_font_free(RGBA_Font *fn)
{ {
@ -646,14 +640,7 @@ evas_common_font_free(RGBA_Font *fn)
fn->references--; fn->references--;
if (fn->references > 0) return; if (fn->references > 0) return;
EINA_LIST_FOREACH(fn->fonts, l, fi) EINA_LIST_FOREACH(fn->fonts, l, fi)
{ evas_common_font_int_unref(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(); evas_common_font_flush();
eina_list_free(fn->fonts); eina_list_free(fn->fonts);
if (fn->fash) fn->fash->freeme(fn->fash); if (fn->fash) fn->fash->freeme(fn->fash);
@ -758,37 +745,40 @@ _evas_common_font_int_clear(RGBA_Font_Int *fi)
return; return;
} }
evas_common_font_int_modify_cache_by(fi, -1); evas_common_font_int_modify_cache_by(fi, -1);
if (fi->fash) if (fi->references <= 1)
{ {
for (k = 0; k <= 0xff; k++) // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16) if (fi->fash)
{ {
Fash_Glyph_Map2 *fmap2 = fi->fash->bucket[k]; for (k = 0; k <= 0xff; k++) // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16)
if (fmap2) {
{ Fash_Glyph_Map2 *fmap2 = fi->fash->bucket[k];
for (j = 0; j <= 0xff; j++) // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16) if (fmap2)
{
Fash_Glyph_Map *fmap = fmap2->bucket[j];
if (fmap)
{ {
for (i = 0; i <= 0xff; i++) for (j = 0; j <= 0xff; j++) // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16)
{ {
RGBA_Font_Glyph *fg = fmap->item[i]; Fash_Glyph_Map *fmap = fmap2->bucket[j];
if ((fg) && (fg != (void *)(-1))) if (fmap)
{ {
FT_Done_Glyph(fg->glyph); for (i = 0; i <= 0xff; i++)
/* extension calls */ {
if (fg->ext_dat_free) fg->ext_dat_free(fg->ext_dat); RGBA_Font_Glyph *fg = fmap->item[i];
if (fg->glyph_out_free) fg->glyph_out_free(fg->glyph_out); if ((fg) && (fg != (void *)(-1)))
free(fg); {
fmap->item[i] = NULL; 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; if (fi->inuse) fonts_use_usage -= fi->usage;
fi->usage = 0; fi->usage = 0;

View File

@ -47,6 +47,8 @@ evas_common_text_props_content_ref(Evas_Text_Props *props)
return; return;
props->info->refcount++; props->info->refcount++;
if (props->font_instance)
((RGBA_Font_Int *)props->font_instance)->references++;
} }
void void
@ -56,6 +58,12 @@ evas_common_text_props_content_unref(Evas_Text_Props *props)
if (!props->info) if (!props->info)
return; return;
if (props->font_instance)
{
evas_common_font_int_unref(props->font_instance);
props->font_instance = NULL;
}
if (--(props->info->refcount) == 0) if (--(props->info->refcount) == 0)
{ {
if (props->bin) 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->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); evas_common_font_int_reload(fi);
if (fi->src->current_size != fi->size) if (fi->src->current_size != fi->size)
{ {