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
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.

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

View File

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

View File

@ -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)
{