From: Enlightenment S. <no-...@en...> - 2010-07-05 06:40:27
|
Log: 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. Author: nash Date: 2010-07-04 23:40:20 -0700 (Sun, 04 Jul 2010) New Revision: 50047 Modified: trunk/evas/src/lib/engines/common/evas_font_draw.c trunk/evas/src/lib/engines/common/evas_font_main.c Modified: trunk/evas/src/lib/engines/common/evas_font_draw.c =================================================================== --- trunk/evas/src/lib/engines/common/evas_font_draw.c 2010-07-05 06:26:47 UTC (rev 50046) +++ trunk/evas/src/lib/engines/common/evas_font_draw.c 2010-07-05 06:40:20 UTC (rev 50047) @@ -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 @@ - 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ free(last); } - return save; - #ifdef INTERNATIONAL_SUPPORT if (level_list) free(level_list); if (visual_text) free(visual_text); #endif + return save; } Modified: trunk/evas/src/lib/engines/common/evas_font_main.c =================================================================== --- trunk/evas/src/lib/engines/common/evas_font_main.c 2010-07-05 06:26:47 UTC (rev 50046) +++ trunk/evas/src/lib/engines/common/evas_font_main.c 2010-07-05 06:40:20 UTC (rev 50047) @@ -20,9 +20,7 @@ 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); } |