evas: lock less font rendering.
authorCedric BAIL <cedric.bail@free.fr>
Thu, 26 Apr 2012 08:18:51 +0000 (08:18 +0000)
committerCedric BAIL <cedric.bail@free.fr>
Thu, 26 Apr 2012 08:18:51 +0000 (08:18 +0000)
SVN revision: 70497

legacy/evas/ChangeLog
legacy/evas/NEWS
legacy/evas/src/lib/engines/common/evas_font.h
legacy/evas/src/lib/engines/common/evas_font_draw.c
legacy/evas/src/lib/engines/common/evas_pipe.c
legacy/evas/src/lib/engines/common/evas_pipe.h
legacy/evas/src/lib/engines/common/evas_text_utils.c
legacy/evas/src/lib/engines/common/evas_text_utils.h
legacy/evas/src/lib/include/evas_common.h

index 4421517..c5075c7 100644 (file)
 
         * 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.
index 2a94cb8..84d01e2 100644 (file)
@@ -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:
index 533d897..f8f2afd 100644 (file)
@@ -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);
index 638cdfe..a038971 100644 (file)
@@ -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);
                }
index 66085c8..3853e12 100644 (file)
@@ -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);
 }
index 37b0136..9680542 100644 (file)
@@ -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);
index a00df91..3efe4bb 100644 (file)
@@ -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;
index 7f1c802..9f3134d 100644 (file)
@@ -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
index e853064..f4480b3 100644 (file)
@@ -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;
 };