Add more control over word-cache size. Also really fix my leak on international text.

The new wordcache option is an environment variable called:
	EVAS_WORD_CACHE_MAX_WORDS
set this to a number between 1-500 to change the cache size.

Larger values (40+) fix regressions in a few of the expedite tests.



SVN revision: 50047
This commit is contained in:
Brett Nash 2010-07-05 06:40:20 +00:00
parent 1c185410b4
commit 8dfc47998e
2 changed files with 27 additions and 12 deletions

View File

@ -12,6 +12,7 @@
#define WORD_CACHE_MAXLEN 50
/* How many to cache */
#define WORD_CACHE_NWORDS 20
static int max_cached_words = WORD_CACHE_NWORDS;
struct prword {
EINA_INLIST;
@ -44,18 +45,29 @@ struct cinfo {
static Eina_Inlist *words = NULL;
static struct prword *evas_font_word_prerender(RGBA_Draw_Context *dc, const char *text, int len, RGBA_Font *fn, RGBA_Font_Int *fi,int use_kerning);
#ifdef EVAS_FRAME_QUEUING
EAPI void
evas_common_font_draw_init(void)
{
char *p;
int tmp;
#ifdef EVAS_FRAME_QUEUING
LKI(lock_font_draw);
LKI(lock_fribidi);
#endif
if ((p = getenv("EVAS_WORD_CACHE_MAX_WORDS")))
{
tmp = strtol(p,NULL,10);
/* 0 to disable of course */
if (tmp > -1 && tmp < 500){
max_cached_words = tmp;
}
}
}
#ifdef EVAS_FRAME_QUEUING
EAPI void
evas_common_font_draw_finish(void)
{
@ -393,13 +405,16 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
FT_UInt prev_index;
DATA32 *im;
int c;
char *p;
int char_index = 0; /* the index of the current char */
#if defined(METRIC_CACHE) || defined(WORD_CACHE)
/* A fast strNlen would be nice (there is a wcsnlen strangely) */
for (len = 0 ; text[len] && len < WORD_CACHE_MAXLEN ; len ++)
;
/* A fast (portable) strNlen would be nice (there is a wcsnlen strangely) */
if ((p = memchr(text, 0, WORD_CACHE_MAXLEN)))
len = p - text;
else
len = WORD_CACHE_MAXLEN;
if (len > 2 && len < WORD_CACHE_MAXLEN){
struct prword *word = evas_font_word_prerender(dc, text, len, fn, fi,
@ -777,10 +792,13 @@ evas_font_word_prerender(RGBA_Draw_Context *dc, const char *in_text, int len, RG
struct prword *w;
int gl;
const char *in_ss = eina_stringshare_add(in_text);
EINA_INLIST_FOREACH(words,w){
if (w->len == len && w->font == fn && fi->size == w->size &&
(w->str == in_text || strcmp(w->str, in_text) == 0)){
(w->str == in_ss)){
words = eina_inlist_promote(words, EINA_INLIST_GET(w));
eina_stringshare_del(in_ss);
return w;
}
}
@ -866,7 +884,7 @@ evas_font_word_prerender(RGBA_Draw_Context *dc, const char *in_text, int len, RG
save = malloc(sizeof(struct prword));
save->cinfo = metrics;
save->str = eina_stringshare_add(text);
save->str = in_ss;
save->font = fn;
save->size = fi->size;
save->len = len;
@ -878,7 +896,7 @@ evas_font_word_prerender(RGBA_Draw_Context *dc, const char *in_text, int len, RG
words = eina_inlist_prepend(words, EINA_INLIST_GET(save));
/* Clean up if too long */
if (eina_inlist_count(words) > 20){
if (eina_inlist_count(words) > max_cached_words){
struct prword *last = (struct prword *)(words->last);
if (last->im) free(last->im);
if (last->cinfo) free(last->cinfo);
@ -887,13 +905,12 @@ evas_font_word_prerender(RGBA_Draw_Context *dc, const char *in_text, int len, RG
free(last);
}
return save;
#ifdef INTERNATIONAL_SUPPORT
if (level_list) free(level_list);
if (visual_text) free(visual_text);
#endif
return save;
}

View File

@ -20,9 +20,7 @@ evas_common_font_init(void)
error = FT_Init_FreeType(&evas_ft_lib);
if (error) return;
evas_common_font_load_init();
#ifdef EVAS_FRAME_QUEUING
evas_common_font_draw_init();
#endif
LKI(lock_font_draw);
LKI(lock_fribidi);
}