From 9914146a4c868c7f5128d017b8718a6d23c802b9 Mon Sep 17 00:00:00 2001 From: cedric Date: Thu, 26 Apr 2012 08:18:51 +0000 Subject: [PATCH] evas: lock less font rendering. git-svn-id: http://svn.enlightenment.org/svn/e/trunk/evas@70497 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- ChangeLog | 6 ++- NEWS | 8 +++ src/lib/engines/common/evas_font.h | 1 + src/lib/engines/common/evas_font_draw.c | 48 +++++++++++++----- src/lib/engines/common/evas_pipe.c | 84 +++++++++++++++++++++++++++----- src/lib/engines/common/evas_pipe.h | 1 + src/lib/engines/common/evas_text_utils.c | 17 ++++--- src/lib/engines/common/evas_text_utils.h | 2 + src/lib/include/evas_common.h | 2 + 9 files changed, 138 insertions(+), 31 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4421517..c5075c7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -704,6 +704,10 @@ * Fix shader binary saving to save with dir existing already. -2012-04-26 Carsten Haitzler (The Rasterman) +2012-04-26 Carsten Haitzler (The Rasterman) 1.2.0 release + +2012-04-26 Cedric Bail + + * Lock less font rendering. diff --git a/NEWS b/NEWS index 2a94cb8..84d01e2 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,11 @@ +Evas 1.3.0 + +Changes since Evas 1.2.0: +------------------------- + +Improvements: + * Lock less font rendering. + Evas 1.2.0 Changes since Evas 1.1.0: diff --git a/src/lib/engines/common/evas_font.h b/src/lib/engines/common/evas_font.h index 533d897..f8f2afd 100644 --- a/src/lib/engines/common/evas_font.h +++ b/src/lib/engines/common/evas_font.h @@ -22,6 +22,7 @@ EAPI int evas_common_font_glyph_search (RGBA_Font *fn, RGB EAPI RGBA_Font_Glyph *evas_common_font_int_cache_glyph_get (RGBA_Font_Int *fi, FT_UInt index); EAPI FT_UInt evas_common_get_char_index (RGBA_Font_Int* fi, Eina_Unicode gl); EAPI void evas_common_font_draw_init (void); +EAPI void evas_common_font_draw_prepare (const Evas_Text_Props *text_props); /* load */ EAPI void evas_common_font_dpi_set (int dpi); diff --git a/src/lib/engines/common/evas_font_draw.c b/src/lib/engines/common/evas_font_draw.c index 638cdfe..a038971 100644 --- a/src/lib/engines/common/evas_font_draw.c +++ b/src/lib/engines/common/evas_font_draw.c @@ -88,7 +88,7 @@ evas_common_font_draw_finish(void) * is on the right, and not on the left). */ static void -evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn __UNUSED__, int x, int y, +evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, const Evas_Text_Props *text_props, RGBA_Gfx_Func func, int ext_x, int ext_y, int ext_w, int ext_h, int im_w, int im_h __UNUSED__) { @@ -213,15 +213,8 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font idx = EVAS_FONT_WALK_INDEX; - LKL(fi->ft_mutex); fg = evas_common_font_int_cache_glyph_get(fi, idx); - if (!fg) - { - LKU(fi->ft_mutex); - continue; - } - - LKU(fi->ft_mutex); + if (!fg) continue; if (dc->font_ext.func.gl_new) { @@ -408,6 +401,39 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font } EAPI void +evas_common_font_draw_prepare(const Evas_Text_Props *text_props) +{ + RGBA_Font_Int *fi; + EVAS_FONT_WALK_TEXT_INIT(); + + fi = text_props->font_instance; + if (!fi) return; + + evas_common_font_int_reload(fi); + + if (fi->src->current_size != fi->size) + { + + FTLOCK(); + FT_Activate_Size(fi->ft.size); + FTUNLOCK(); + fi->src->current_size = fi->size; + } + + EVAS_FONT_WALK_TEXT_START() + { + FT_UInt idx; + RGBA_Font_Glyph *fg; + + if (!EVAS_FONT_WALK_IS_VISIBLE) continue; + idx = EVAS_FONT_WALK_INDEX; + + fg = evas_common_font_int_cache_glyph_get(fi, idx); + } + EVAS_FONT_WALK_TEXT_END(); +} + +EAPI void evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const Evas_Text_Props *text_props) { int ext_x, ext_y, ext_w, ext_h; @@ -454,7 +480,7 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int if (!dc->cutout.rects) { - evas_common_font_draw_internal(dst, dc, fn, x, y, text_props, + evas_common_font_draw_internal(dst, dc, x, y, text_props, func, ext_x, ext_y, ext_w, ext_h, im_w, im_h); } @@ -470,7 +496,7 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int { r = rects->rects + i; evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h); - evas_common_font_draw_internal(dst, dc, fn, x, y, text_props, + evas_common_font_draw_internal(dst, dc, x, y, text_props, func, r->x, r->y, r->w, r->h, im_w, im_h); } diff --git a/src/lib/engines/common/evas_pipe.c b/src/lib/engines/common/evas_pipe.c index 66085c8..3853e12 100644 --- a/src/lib/engines/common/evas_pipe.c +++ b/src/lib/engines/common/evas_pipe.c @@ -1252,6 +1252,7 @@ evas_common_pipe_text_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, op->op_func = evas_common_pipe_text_draw_do; op->free_func = evas_common_pipe_op_text_free; evas_common_pipe_draw_context_copy(dc, op); + evas_common_pipe_text_prepare(intl_props); } /**************** IMAGE *****************/ @@ -1563,10 +1564,12 @@ evas_common_pipe_map_render(RGBA_Image *root) } #ifdef BUILD_PTHREAD -static Eina_List *task = NULL; +static Eina_List *im_task = NULL; +static Eina_List *text_task = NULL; static Thinfo task_thinfo[TH_MAX]; static pthread_barrier_t task_thbarrier[2]; -static LK(task_mutext); +static LK(im_task_mutex); +static LK(text_task_mutex); #endif #ifdef BUILD_PTHREAD @@ -1581,14 +1584,14 @@ evas_common_pipe_load(void *data) /* wait for start signal */ pthread_barrier_wait(&(tinfo->barrier[0])); - while (task) + while (im_task) { RGBA_Image *im = NULL; - LKL(task_mutext); - im = eina_list_data_get(task); - task = eina_list_remove_list(task, task); - LKU(task_mutext); + LKL(im_task_mutex); + im = eina_list_data_get(im_task); + im_task = eina_list_remove_list(im_task, im_task); + LKU(im_task_mutex); if (im) { @@ -1600,6 +1603,28 @@ evas_common_pipe_load(void *data) } } + while (text_task) + { + Evas_Text_Props *text_props; + RGBA_Font_Int *fi; + + LKL(text_task_mutex); + fi = eina_list_data_get(text_task); + text_task = eina_list_remove_list(text_task, text_task); + LKU(text_task_mutex); + + if (fi) + { + LKL(fi->ft_mutex); + EINA_LIST_FREE(fi->task, text_props) + { + evas_common_font_draw_prepare(text_props); + text_props->changed = EINA_FALSE; + } + LKU(fi->ft_mutex); + } + } + /* send finished signal */ pthread_barrier_wait(&(tinfo->barrier[1])); } @@ -1611,7 +1636,7 @@ evas_common_pipe_load(void *data) static volatile int bval = 0; static void -evas_common_pipe_image_load_do(void) +evas_common_pipe_load_do(void) { #ifdef BUILD_PTHREAD /* Notify worker thread. */ @@ -1633,13 +1658,15 @@ evas_common_pipe_init(void) cpunum = eina_cpu_count(); thread_num = cpunum; + fprintf(stderr, "number of cpu: %i\n", cpunum); // on single cpu we still want this initted.. otherwise we block forever // waiting onm pthread barriers for async rendering on a single core! // if (thread_num == 1) return EINA_FALSE; eina_threads_init(); - LKI(task_mutext); + LKI(im_task_mutex); + LKI(text_task_mutex); pthread_barrier_init(&(thbarrier[0]), NULL, thread_num + 1); pthread_barrier_init(&(thbarrier[1]), NULL, thread_num + 1); @@ -1704,18 +1731,51 @@ evas_common_pipe_image_load(RGBA_Image *im) return ; add_task: - task = eina_list_append(task, im); + LKL(im_task_mutex); + im_task = eina_list_append(im_task, im); + LKU(im_task_mutex); im->flags |= RGBA_IMAGE_TODO_LOAD; } EAPI void +evas_common_pipe_text_prepare(const Evas_Text_Props *text_props) +{ + RGBA_Font_Int *fi; + const Evas_Text_Props *tmp_props; + const Eina_List *l; + + if (!text_props->changed) return ; + + fi = text_props->font_instance; + if (!fi) return ; + + LKL(fi->ft_mutex); + + if (!fi->task) + { + LKL(text_task_mutex); + text_task = eina_list_append(text_task, fi); + LKU(text_task_mutex); + } + + EINA_LIST_FOREACH(fi->task, l, tmp_props) + if (tmp_props == text_props) + goto end; + + fi->task = eina_list_append(fi->task, text_props); + + end: + LKU(fi->ft_mutex); +} + +EAPI void evas_common_pipe_map_begin(RGBA_Image *root) { if (!evas_common_pipe_init()) { RGBA_Image *im; - EINA_LIST_FREE(task, im) + EINA_LIST_FREE(im_task, im) { if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888) evas_cache_image_load_data(&im->cache_entry); @@ -1725,7 +1785,7 @@ evas_common_pipe_map_begin(RGBA_Image *root) } } - evas_common_pipe_image_load_do(); + evas_common_pipe_load_do(); evas_common_pipe_map_render(root); } diff --git a/src/lib/engines/common/evas_pipe.h b/src/lib/engines/common/evas_pipe.h index 37b0136..9680542 100644 --- a/src/lib/engines/common/evas_pipe.h +++ b/src/lib/engines/common/evas_pipe.h @@ -95,6 +95,7 @@ EAPI void evas_common_pipe_rectangle_draw(RGBA_Image *dst, RGBA_Draw_Context *dc EAPI void evas_common_pipe_line_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1); EAPI void evas_common_pipe_poly_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Polygon_Point *points, int x, int y); EAPI void evas_common_pipe_text_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const Evas_Text_Props *intl_props); +EAPI void evas_common_pipe_text_prepare(const Evas_Text_Props *text_props); EAPI void evas_common_pipe_image_load(RGBA_Image *im); EAPI void evas_common_pipe_image_draw(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, int smooth, int src_region_x, int src_region_y, int src_region_w, int src_region_h, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h); EAPI void evas_common_pipe_map_begin(RGBA_Image *root); diff --git a/src/lib/engines/common/evas_text_utils.c b/src/lib/engines/common/evas_text_utils.c index a00df91..3efe4bb 100644 --- a/src/lib/engines/common/evas_text_utils.c +++ b/src/lib/engines/common/evas_text_utils.c @@ -5,6 +5,8 @@ #include "language/evas_language_utils.h" #include "evas_font_ot.h" +#define PROPS_CHANGE(Props) Props->changed = EINA_TRUE; + void evas_common_text_props_bidi_set(Evas_Text_Props *props, Evas_BiDi_Paragraph_Props *bidi_par_props, size_t start) @@ -19,12 +21,14 @@ evas_common_text_props_bidi_set(Evas_Text_Props *props, (void) bidi_par_props; props->bidi.dir = EVAS_BIDI_DIRECTION_LTR; #endif + PROPS_CHANGE(props); } void evas_common_text_props_script_set(Evas_Text_Props *props, Evas_Script_Type scr) { props->script = scr; + PROPS_CHANGE(props); } void @@ -249,6 +253,8 @@ evas_common_text_props_split(Evas_Text_Props *base, } ext->text_len = base->text_len - (ext->text_offset - base->text_offset); base->text_len = (ext->text_offset - base->text_offset); + PROPS_CHANGE(base); + PROPS_CHANGE(ext); } /* Won't work in the middle of ligatures */ @@ -268,6 +274,7 @@ evas_common_text_props_merge(Evas_Text_Props *item1, item1->len += item2->len; item1->text_len += item2->text_len; + PROPS_CHANGE(item1); } EAPI Eina_Bool @@ -299,6 +306,8 @@ evas_common_text_props_content_create(void *_fi, const Eina_Unicode *text, fi->src->current_size = fi->size; } + text_props->changed = EINA_TRUE; + #ifdef OT_SUPPORT size_t char_index; Evas_Font_Glyph_Info *gl_itr; @@ -419,13 +428,8 @@ evas_common_text_props_content_create(void *_fi, const Eina_Unicode *text, idx = evas_common_get_char_index(fi, REPLACEMENT_CHAR); } - LKL(fi->ft_mutex); fg = evas_common_font_int_cache_glyph_get(fi, idx); - if (!fg) - { - LKU(fi->ft_mutex); - continue; - } + if (!fg) continue; kern = 0; if ((use_kerning) && (prev_index) && (idx) && @@ -440,7 +444,6 @@ evas_common_text_props_content_create(void *_fi, const Eina_Unicode *text, } pface = fi->src->ft.face; - LKU(fi->ft_mutex); gl_itr->index = idx; gl_itr->x_bear = fg->glyph_out->left; diff --git a/src/lib/engines/common/evas_text_utils.h b/src/lib/engines/common/evas_text_utils.h index 7f1c802..9f3134d 100644 --- a/src/lib/engines/common/evas_text_utils.h +++ b/src/lib/engines/common/evas_text_utils.h @@ -24,6 +24,8 @@ struct _Evas_Text_Props Evas_Script_Type script; Evas_Text_Props_Info *info; void *font_instance; + + Eina_Bool changed : 1; }; struct _Evas_Text_Props_Info diff --git a/src/lib/include/evas_common.h b/src/lib/include/evas_common.h index e853064..f4480b3 100644 --- a/src/lib/include/evas_common.h +++ b/src/lib/include/evas_common.h @@ -950,6 +950,8 @@ struct _RGBA_Font_Int Font_Rend_Flags wanted_rend; /* The wanted rendering style */ Font_Rend_Flags runtime_rend; /* The rendering we need to do on runtime in order to comply with the wanted_rend. */ + + Eina_List *task; unsigned char sizeok : 1; unsigned char inuse : 1; }; -- 2.7.4