evas: add more infrastructure to the prepare stage of pipe rendering.
authorcedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Wed, 4 Jul 2012 09:39:23 +0000 (09:39 +0000)
committercedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Wed, 4 Jul 2012 09:39:23 +0000 (09:39 +0000)
NOTE: this improve some test by 10 to 15% some other are down by 5%.
Their is still more tunning and improvement possible now (Particularly
with Map), but it will do for now.

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@73264 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

42 files changed:
ChangeLog
NEWS
src/lib/canvas/evas_clip.c
src/lib/canvas/evas_map.c
src/lib/canvas/evas_object_image.c
src/lib/canvas/evas_object_smart.c
src/lib/canvas/evas_render.c
src/lib/engines/common/evas_draw.h
src/lib/engines/common/evas_draw_main.c
src/lib/engines/common/evas_font.h
src/lib/engines/common/evas_font_draw.c
src/lib/engines/common/evas_font_main.c
src/lib/engines/common/evas_image_scalecache.c
src/lib/engines/common/evas_line_main.c
src/lib/engines/common/evas_map_image.c
src/lib/engines/common/evas_map_image.h
src/lib/engines/common/evas_map_image_internal.c
src/lib/engines/common/evas_pipe.c
src/lib/engines/common/evas_pipe.h
src/lib/engines/common/evas_rectangle.h
src/lib/engines/common/evas_rectangle_main.c
src/lib/engines/common/evas_scale_main.c
src/lib/engines/common/evas_scale_main.h
src/lib/engines/common/evas_scale_sample.c
src/lib/engines/common/evas_scale_smooth.c
src/lib/engines/common/evas_text_utils.c
src/lib/engines/common/evas_text_utils.h
src/lib/engines/common_16/evas_soft16_main.c
src/lib/engines/common_16/evas_soft16_rectangle.c
src/lib/engines/common_8/evas_soft8_main.c
src/lib/engines/common_8/evas_soft8_rectangle.c
src/lib/include/evas_common.h
src/lib/include/evas_private.h
src/modules/engines/directfb/evas_engine.c
src/modules/engines/gl_common/evas_gl_font.c
src/modules/engines/gl_common/evas_gl_image.c
src/modules/engines/gl_common/evas_gl_polygon.c
src/modules/engines/gl_common/evas_gl_rectangle.c
src/modules/engines/gl_x11/evas_engine.c
src/modules/engines/software_generic/evas_engine.c
src/modules/engines/software_x11/evas_engine.h
src/modules/engines/software_x11/evas_xlib_outbuf.c

index bddda5f..44e6c1f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
        * upstream merge
        * Merge remote-tracking branch 'remotes/origin/upstream'
 
-2012-07-03 Christopher Michael
+2012-07-03  Christopher Michael
 
        * Merge Tizen changes to upstream EFL.
        * Support gif scaling in evas gif loader.
        * When freeing a gl_x11 window, make sure to call eglMakeCurrent with a null surface
                to inform EGL that this window is no longer valid.
 
+2012-07-04  Cedric Bail
+
+       * Make pipeline rendering use more extensively the prepare stage.
diff --git a/NEWS b/NEWS
index 3ec27d8..3ecd549 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -13,7 +13,8 @@ Improvements:
    * Don't wake up prepare thread if there is nothing to prepare.
    * Limit the updated region to fit in CPU cache for Pipe rendering.
    * Cache convertion from Evas_Map to RGBA_Map.
-   * evas_object_smart_members_get() now returns NULL on non-smart objects
+   * evas_object_smart_members_get() now returns NULL on non-smart objects.
+   * Pipeline rendering use prepare stage more extensively.
 
 Fixes:
    * Add missing files in the tarball.
index 435a0ff..6baa28c 100644 (file)
@@ -179,11 +179,11 @@ evas_object_clip_set(Evas_Object *obj, Evas_Object *clip)
    if (obj == clip) return;
    if (evas_object_intercept_call_clip_set(obj, clip)) return;
    // illegal to set anything but a rect as a clip
-   if (clip->type != o_rect_type)
-     {
-        ERR("For now a clip on other object than a rectangle is disabled");
-        return;
-     }
+   /* if (clip->type != o_rect_type) */
+   /*   { */
+   /*      ERR("For now a clip on other object than a rectangle is disabled"); */
+   /*      return; */
+   /*   } */
    if (obj->smart.smart)
      {
        if (obj->smart.smart->smart_class->clip_set)
@@ -228,7 +228,7 @@ evas_object_clip_set(Evas_Object *obj, Evas_Object *clip)
 
    /* If it's NOT a rectangle set the mask bits too */
    /* FIXME: Optmz ths chck */
-   if (strcmp(evas_object_type_get(clip),"rectangle") == 0)
+   if (clip->type == o_rect_type)
       obj->cur.mask = NULL;
    else
      {
index 9c2d71a..f402db7 100644 (file)
@@ -144,7 +144,9 @@ _evas_map_copy(Evas_Map *dst, const Evas_Map *src)
         ERR("cannot copy map of different sizes: dst=%i, src=%i", dst->count, src->count);
         return EINA_FALSE;
      }
-   memcpy(dst->points, src->points, src->count * sizeof(Evas_Map_Point));
+   if (dst == src) return EINA_TRUE;
+   if (dst->points != src->points)
+     memcpy(dst->points, src->points, src->count * sizeof(Evas_Map_Point));
    dst->smooth = src->smooth;
    dst->alpha = src->alpha;
    dst->persp = src->persp;
@@ -170,10 +172,10 @@ _evas_map_free(Evas_Object *obj, Evas_Map *m)
      {
         if (m->surface)
           obj->layer->evas->engine.func->image_map_surface_free
-          (obj->layer->evas->engine.data.output, m->surface);
+            (obj->layer->evas->engine.data.output, m->surface);
         if (obj->spans)
           {
-             // FIXME: destroy engine side spans
+             obj->layer->evas->engine.func->image_map_clean(obj->layer->evas->engine.data.output, obj->spans);
              free(obj->spans);
              obj->spans = NULL;
           }      
@@ -487,7 +489,7 @@ evas_object_map_set(Evas_Object *obj, const Evas_Map *map)
      _evas_map_copy(obj->cur.map, map);
    else
      {
-        if (obj->cur.map) evas_map_free(obj->cur.map);
+        if (obj->cur.map) _evas_map_free(obj, obj->cur.map);
         obj->cur.map = _evas_map_dup(map);
         if (obj->cur.usemap)
            evas_object_mapped_clip_across_mark(obj);
index b880be8..b18ac65 100644 (file)
@@ -2952,14 +2952,11 @@ evas_object_image_render(Evas_Object *obj, void *output, void *context, void *su
          }
         if ((obj->cur.map) && (obj->cur.map->count > 3) && (obj->cur.usemap))
           {
-             RGBA_Map_Point *pts;
-
              evas_object_map_update(obj, x, y, imagew, imageh, uvw, uvh);
-             pts = obj->spans->pts;
 
              obj->layer->evas->engine.func->image_map_draw
-               (output, context, surface, pixels, obj->cur.map->count,
-               pts, o->cur.smooth_scale | obj->cur.map->smooth, 0);
+               (output, context, surface, pixels, obj->spans,
+               o->cur.smooth_scale | obj->cur.map->smooth, 0);
           }
         else
           {
index 83b4e88..3d9c89d 100644 (file)
@@ -1008,19 +1008,74 @@ static void
 evas_object_smart_render_pre(Evas_Object *obj)
 {
    if (obj->pre_render_done) return;
-   if (!obj->child_has_map)
+   if (!obj->child_has_map && !obj->cur.cached_surface)
      {
 #if 0
         Evas_Object_Smart *o;
 
+        fprintf(stderr, "");
         o = (Evas_Object_Smart *)(obj->object_data);
-        if (o->member_count > 1 &&
+        if (/* o->member_count > 1 && */
             obj->cur.bounding_box.w == obj->prev.bounding_box.w &&
             obj->cur.bounding_box.h == obj->prev.bounding_box.h &&
             (obj->cur.bounding_box.x != obj->prev.bounding_box.x ||
              obj->cur.bounding_box.y != obj->prev.bounding_box.y))
           {
-             fprintf(stderr, "Wouhou, I can detect moving smart object (%s, %p < %p)\n", evas_object_type_get(obj), obj, obj->smart.parent);
+             Eina_Bool cache_map = EINA_FALSE;
+
+             /* Check parent speed */
+             /* - same speed => do not map this object */
+             /* - different speed => map this object */
+             /* - if parent is mapped then map this object */
+
+             if (!obj->smart.parent || obj->smart.parent->child_has_map)
+               {
+                  cache_map = EINA_TRUE;
+               }
+             else
+               {
+                  if (_evas_render_has_map(obj->smart.parent))
+                    {
+                       cache_map = EINA_TRUE;
+                    }
+                  else
+                    {
+                       int speed_x, speed_y;
+                       int speed_px, speed_py;
+
+                       speed_x = obj->cur.geometry.x - obj->prev.geometry.x;
+                       speed_y = obj->cur.geometry.y - obj->prev.geometry.y;
+
+                       speed_px = obj->smart.parent->cur.geometry.x - obj->smart.parent->prev.geometry.x;
+                       speed_py = obj->smart.parent->cur.geometry.y - obj->smart.parent->prev.geometry.y;
+
+                       /* speed_x = obj->cur.bounding_box.x - obj->prev.bounding_box.x; */
+                       /* speed_y = obj->cur.bounding_box.y - obj->prev.bounding_box.y; */
+
+                       /* speed_px = obj->smart.parent->cur.bounding_box.x - obj->smart.parent->prev.bounding_box.x; */
+                       /* speed_py = obj->smart.parent->cur.bounding_box.y - obj->smart.parent->prev.bounding_box.y; */
+
+                       fprintf(stderr, "speed: '%s',%p (%i, %i) vs '%s',%p (%i, %i)\n",
+                               evas_object_type_get(obj), obj, speed_x, speed_y,
+                               evas_object_type_get(obj->smart.parent), obj->smart.parent, speed_px, speed_py);
+
+                       if (speed_x != speed_px || speed_y != speed_py)
+                         cache_map = EINA_TRUE;
+                    }
+               }
+
+             if (cache_map)
+               fprintf(stderr, "Wouhou, I can detect moving smart object (%s, %p [%i, %i, %i, %i] < %s, %p [%i, %i, %i, %i])\n",
+                       evas_object_type_get(obj), obj,
+                       obj->cur.bounding_box.x - obj->prev.bounding_box.x,
+                       obj->cur.bounding_box.y - obj->prev.bounding_box.y,
+                       obj->cur.bounding_box.w, obj->cur.bounding_box.h,
+                       evas_object_type_get(obj->smart.parent), obj->smart.parent,
+                       obj->smart.parent->cur.bounding_box.x - obj->smart.parent->prev.bounding_box.x,
+                       obj->smart.parent->cur.bounding_box.y - obj->smart.parent->prev.bounding_box.y,
+                       obj->smart.parent->cur.bounding_box.w, obj->smart.parent->cur.bounding_box.h);
+
+             obj->cur.cached_surface = cache_map;
           }
 #endif
      }
index 11edcf3..374938b 100644 (file)
@@ -822,7 +822,6 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
       _evas_render_has_map(obj));
    if (_evas_render_has_map(obj))
      {
-        RGBA_Map_Point *pts;
         int sw, sh;
         Eina_Bool changed = EINA_FALSE, rendered = EINA_FALSE;
 
@@ -840,7 +839,6 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
           }
 
         evas_object_map_update(obj, off_x, off_y, sw, sh, sw, sh);
-        pts = obj->spans->pts;
 
         if (obj->cur.map->surface)
           {
@@ -1032,7 +1030,7 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
                (e->engine.data.output, e->engine.data.context);
              obj->layer->evas->engine.func->image_map_draw
                (e->engine.data.output, e->engine.data.context, surface,
-                   obj->cur.map->surface, obj->cur.map->count, pts,
+                   obj->cur.map->surface, obj->spans,
                    obj->cur.map->smooth, 0);
           }
         // FIXME: needs to cache these maps and
index 34e0ed3..6599d54 100644 (file)
@@ -24,7 +24,7 @@ EAPI void               evas_common_draw_context_cutouts_free            (Cutout
 EAPI void               evas_common_draw_context_cutouts_del             (Cutout_Rects* rects, int idx);
 EAPI void               evas_common_draw_context_add_cutout              (RGBA_Draw_Context *dc, int x, int y, int w, int h);
 EAPI void               evas_common_draw_context_clear_cutouts           (RGBA_Draw_Context *dc);
-EAPI Cutout_Rects      *evas_common_draw_context_apply_cutouts           (RGBA_Draw_Context *dc);
+EAPI Cutout_Rects      *evas_common_draw_context_apply_cutouts           (RGBA_Draw_Context *dc, Cutout_Rects *recycle);
 EAPI void               evas_common_draw_context_apply_clear_cutouts     (Cutout_Rects* rects);
 EAPI void               evas_common_draw_context_apply_clean_cutouts     (Cutout_Rects* rects);
 EAPI void               evas_common_draw_context_set_anti_alias          (RGBA_Draw_Context *dc, unsigned char aa);
index d08e788..28b54cd 100644 (file)
@@ -14,6 +14,7 @@ evas_common_draw_context_cutouts_new(void)
 EAPI void
 evas_common_draw_context_cutouts_free(Cutout_Rects* rects)
 {
+   if (!rects) return ;
    rects->active = 0;
 }
 
@@ -90,7 +91,7 @@ evas_common_draw_context_free(RGBA_Draw_Context *dc)
 EAPI void
 evas_common_draw_context_clear_cutouts(RGBA_Draw_Context *dc)
 {
-   evas_common_draw_context_apply_clean_cutouts(&dc->cutout);
+   evas_common_draw_context_cutouts_free(&dc->cutout);
 }
 
 EAPI void
@@ -557,9 +558,9 @@ evas_common_draw_context_cutout_split(Cutout_Rects* res, int idx, Cutout_Rect *s
 }
 
 EAPI Cutout_Rects*
-evas_common_draw_context_apply_cutouts(RGBA_Draw_Context *dc)
+evas_common_draw_context_apply_cutouts(RGBA_Draw_Context *dc, Cutout_Rects *reuse)
 {
-   Cutout_Rects*        res, *res2;
+   Cutout_Rects*        res = NULL;
    int                  i;
    int                  j;
 
@@ -567,7 +568,15 @@ evas_common_draw_context_apply_cutouts(RGBA_Draw_Context *dc)
    if ((dc->clip.w <= 0) || (dc->clip.h <= 0)) return NULL;
 
 
-   res = evas_common_draw_context_cutouts_new();
+   if (!reuse)
+     {
+        res = evas_common_draw_context_cutouts_new();
+     }
+   else
+     {
+        evas_common_draw_context_cutouts_free(reuse);
+        res = reuse;
+     }
    evas_common_draw_context_cutouts_add(res, dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h);
 
    for (i = 0; i < dc->cutout.active; ++i)
@@ -636,15 +645,18 @@ evas_common_draw_context_apply_cutouts(RGBA_Draw_Context *dc)
                     }
                }
           }
-        res2 = evas_common_draw_context_cutouts_new();
+
+        /* Repack the cutout */
+        j = 0;
         for (i = 0; i < res->active; i++)
           {
              if (RI.w == 0) continue;
-             evas_common_draw_context_cutouts_add(res2, RI.x, RI.y, RI.w, RI.h);
+             if (i != j)
+               RJ = RI;
+             j++;
           }
-        free(res->rects);
-        free(res);
-        return res2;
+        res->active = j;
+        return res;
      }
    return res;
 }
index 313c23e..5c7c1af 100644 (file)
@@ -25,6 +25,8 @@ EAPI Eina_Bool         evas_common_font_int_cache_glyph_render(RGBA_Font_Glyph *
 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         (Evas_Text_Props *text_props);
+EAPI void              evas_common_font_draw_do(const Cutout_Rects *reuse, const Eina_Rectangle *clip, RGBA_Gfx_Func func, RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, const Evas_Text_Props *text_props);
+EAPI Eina_Bool         evas_common_font_draw_prepare_cutout(Cutout_Rects *reuse, RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Gfx_Func *func);
 
 /* load */
 EAPI void              evas_common_font_dpi_set              (int dpi);
index c1308a9..f635756 100644 (file)
@@ -40,21 +40,22 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, in
 
    im = dst->image.data;
 
-   if (!text_props->bin) return ;
+   if (!text_props->glyphs) return ;
 
-   glyphs = (void*) eina_binbuf_string_get(text_props->bin);
-   length = eina_binbuf_length_get(text_props->bin) / sizeof (Evas_Glyph);
-   for (it = 0; it < length; ++it)
+   glyphs = text_props->glyphs;
+   length = text_props->glyphs_length;
+   for (it = 0; it < length; ++it, ++glyphs)
      {
         RGBA_Font_Glyph *fg;
         int chr_x, chr_y;
 
-        fg = glyphs[it].fg;
+        fg = glyphs->fg;
 
-        glyphs[it].coord.w = fg->glyph_out->bitmap.width;
-        glyphs[it].coord.h = fg->glyph_out->bitmap.rows;
-        glyphs[it].j = fg->glyph_out->bitmap.pitch;
-        glyphs[it].data = fg->glyph_out->bitmap.buffer;
+       /* FIXME: Why was that moved out of prepare ? This increase cache miss. */
+        glyphs->coord.w = fg->glyph_out->bitmap.width;
+        glyphs->coord.h = fg->glyph_out->bitmap.rows;
+        glyphs->j = fg->glyph_out->bitmap.pitch;
+        glyphs->data = fg->glyph_out->bitmap.buffer;
 
         if (dc->font_ext.func.gl_new)
           {
@@ -63,19 +64,19 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, in
              fg->ext_dat_free = dc->font_ext.func.gl_free;
           }
 
-        chr_x = x + glyphs[it].coord.x/* EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF + EVAS_FONT_WALK_X_BEAR */;
-        chr_y = y + glyphs[it].coord.y/* EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR */;
+        chr_x = x + glyphs->coord.x/* EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF + EVAS_FONT_WALK_X_BEAR */;
+        chr_y = y + glyphs->coord.y/* EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR */;
 
         if (chr_x < (ext_x + ext_w))
           {
              DATA8 *data;
              int i, j, w, h;
 
-             data = glyphs[it].data;
-             j = glyphs[it].j;
-             w = glyphs[it].coord.w;
+             data = glyphs->data;
+             j = glyphs->j;
+             w = glyphs->coord.w;
              if (j < w) j = w;
-             h = glyphs[it].coord.h;
+             h = glyphs->coord.h;
 
 #ifdef HAVE_PIXMAN
 # ifdef PIXMAN_FONT             
@@ -230,16 +231,21 @@ evas_common_font_draw_prepare(Evas_Text_Props *text_props)
 {
    RGBA_Font_Int *fi;
    RGBA_Font_Glyph *fg;
+   Evas_Glyph *glyphs;
+   int glyphs_length;
+   int glyphs_max;
    EVAS_FONT_WALK_TEXT_INIT();
 
    fi = text_props->font_instance;
    if (!fi) return;
 
-   if (!text_props->changed && text_props->generation == fi->generation && text_props->bin)
+   if (!text_props->changed && text_props->generation == fi->generation && text_props->glyphs)
      return ;
 
-   if (!text_props->bin) text_props->bin = eina_binbuf_new();
-   else eina_binbuf_reset(text_props->bin);
+   glyphs = text_props->glyphs;
+   glyphs_length = 0;
+   glyphs_max = text_props->glyphs_length;
+   text_props->glyphs_length = 0;
 
    evas_common_font_int_reload(fi);
 
@@ -254,7 +260,7 @@ evas_common_font_draw_prepare(Evas_Text_Props *text_props)
 
    EVAS_FONT_WALK_TEXT_START()
      {
-        Evas_Glyph glyph;
+        Evas_Glyph *glyph;
         FT_UInt idx;
 
         if (!EVAS_FONT_WALK_IS_VISIBLE) continue;
@@ -264,15 +270,28 @@ evas_common_font_draw_prepare(Evas_Text_Props *text_props)
         if (!fg) continue;
         if (!fg->glyph_out) evas_common_font_int_cache_glyph_render(fg);
 
-        glyph.fg = fg;
-        glyph.coord.x = EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF + EVAS_FONT_WALK_X_BEAR;
-        glyph.coord.y = EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR;
-        glyph.idx = idx;
+       if (glyphs_length + 1 >= glyphs_max)
+         {
+             Evas_Glyph *tmp;
+
+             glyphs_max += 8;
+             tmp = realloc(glyphs, glyphs_max * sizeof (Evas_Glyph));
+             if (!tmp) return ;
+             glyphs = tmp;
+             text_props->glyphs = glyphs;
+         }
+
+        glyph = glyphs + glyphs_length++;
 
-        eina_binbuf_append_length(text_props->bin, (void*) &glyph, sizeof (Evas_Glyph));
+        glyph->fg = fg;
+        glyph->idx = idx;
+        glyph->coord.x = EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF + EVAS_FONT_WALK_X_BEAR;
+        glyph->coord.y = EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR;
      }
    EVAS_FONT_WALK_TEXT_END();
 
+   text_props->glyphs_length = glyphs_length;
+   text_props->glyphs = glyphs;
    /* check if there's a request queue in fi, if so ask cserve2 to render
     * those glyphs
     */
@@ -283,10 +302,10 @@ evas_common_font_draw_prepare(Evas_Text_Props *text_props)
 EAPI void
 evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, const Evas_Text_Props *text_props)
 {
+   static Cutout_Rects *rects = NULL;
    int ext_x, ext_y, ext_w, ext_h;
    int im_w, im_h;
    RGBA_Gfx_Func func;
-   Cutout_Rects *rects;
    Cutout_Rect  *r;
    int c, cx, cy, cw, ch;
    int i;
@@ -335,7 +354,7 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, cons
         /* our clip is 0 size.. abort */
         if ((dc->clip.w > 0) && (dc->clip.h > 0))
           {
-             rects = evas_common_draw_context_apply_cutouts(dc);
+             rects = evas_common_draw_context_apply_cutouts(dc, rects);
              for (i = 0; i < rects->active; ++i)
                {
                   r = rects->rects + i;
@@ -344,8 +363,96 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, cons
                                                  func, r->x, r->y, r->w, r->h,
                                                  im_w, im_h);
                }
-             evas_common_draw_context_apply_clear_cutouts(rects);
           }
         dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
      }
 }
+
+EAPI void
+evas_common_font_draw_do(const Cutout_Rects *reuse, const Eina_Rectangle *clip, RGBA_Gfx_Func func,
+                         RGBA_Image *dst, RGBA_Draw_Context *dc,
+                         int x, int y, const Evas_Text_Props *text_props)
+{
+   Eina_Rectangle area;
+   Cutout_Rect *r;
+   int i;
+   int im_w, im_h;
+
+   im_w = dst->cache_entry.w;
+   im_h = dst->cache_entry.h;
+
+   if (!reuse)
+     {
+        evas_common_draw_context_set_clip(dc, area.x, area.y, area.w, area.h);
+        evas_common_font_draw_internal(dst, dc, x, y, text_props,
+                                       func, clip->x, clip->y, clip->w, clip->h,
+                                       im_w, im_h);
+        return ;
+     }
+
+   for (i = 0; i < reuse->active; ++i)
+     {
+        r = reuse->rects + i;
+
+        EINA_RECTANGLE_SET(&area, r->x, r->y, r->w, r->h);
+        if (!eina_rectangle_intersection(&area, clip)) continue ;
+        evas_common_draw_context_set_clip(dc, area.x, area.y, area.w, area.h);
+        evas_common_font_draw_internal(dst, dc, x, y, text_props,
+                                       func, area.x, area.y, area.w, area.h,
+                                       im_w, im_h);
+     }
+}
+
+EAPI Eina_Bool
+evas_common_font_draw_prepare_cutout(Cutout_Rects *reuse, RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Gfx_Func *func)
+{
+   int ext_x, ext_y, ext_w, ext_h;
+   int im_w, im_h;
+
+   im_w = dst->cache_entry.w;
+   im_h = dst->cache_entry.h;
+
+   *func = evas_common_gfx_func_composite_mask_color_span_get(dc->col.col, dst, 1, dc->render_op);
+
+   ext_x = 0; ext_y = 0; ext_w = im_w; ext_h = im_h;
+   if (dc->clip.use)
+     {
+       ext_x = dc->clip.x;
+       ext_y = dc->clip.y;
+       ext_w = dc->clip.w;
+       ext_h = dc->clip.h;
+       if (ext_x < 0)
+         {
+            ext_w += ext_x;
+            ext_x = 0;
+         }
+       if (ext_y < 0)
+         {
+            ext_h += ext_y;
+            ext_y = 0;
+         }
+       if ((ext_x + ext_w) > im_w)
+         ext_w = im_w - ext_x;
+       if ((ext_y + ext_h) > im_h)
+         ext_h = im_h - ext_y;
+     }
+   if (ext_w <= 0) return EINA_FALSE;
+   if (ext_h <= 0) return EINA_FALSE;
+
+   if (dc->cutout.rects)
+     {
+        evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h);
+        /* our clip is 0 size.. abort */
+        if ((dc->clip.w > 0) && (dc->clip.h > 0))
+          {
+             reuse = evas_common_draw_context_apply_cutouts(dc, reuse);
+          }
+       else
+         {
+             return EINA_FALSE;
+         }
+     }
+
+   return EINA_TRUE;
+}
+
index bd4c678..100f3b7 100644 (file)
@@ -562,9 +562,14 @@ evas_common_get_char_index(RGBA_Font_Int* fi, Eina_Unicode gl)
 //     }
 
    evas_common_font_int_reload(fi);
-   FTLOCK();
+   /*
+    * There is no point in locking FreeType at this point as all caller
+    * are running in the main loop at a time where there is zero chance
+    * that something else try to use it.
+    */
+   /* FTLOCK(); */
    result.index = FT_Get_Char_Index(fi->src->ft.face, gl);
-   FTUNLOCK();
+   /* FTUNLOCK(); */
    result.gl = gl;
 
 //   eina_hash_direct_add(fi->indexes, &result->gl, result);
index 99ecd30..5a2d7a2 100644 (file)
@@ -221,8 +221,7 @@ _sci_find(RGBA_Image *im,
           {
              if (im->cache.list != l)
                {
-                  im->cache.list = eina_list_remove_list(im->cache.list, l);
-                  im->cache.list = eina_list_prepend(im->cache.list, sci);
+                  im->cache.list = eina_list_promote_list(im->cache.list, l);
                }
              return sci;
           }
index fc1385f..76417f5 100644 (file)
@@ -47,6 +47,8 @@ evas_common_line_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, in
    int  clx, cly, clw, clh;
    int  cuse, cx, cy, cw, ch;
 
+   /* No cutout ? FIXME ? */
+
    if ((x0 == x1) && (y0 == y1))
      {
        _evas_draw_point(dst, dc, x0, y0);
index 4106c20..776820f 100644 (file)
@@ -1,4 +1,5 @@
 #include "evas_common.h"
+#include "evas_private.h"
 #include "evas_blend_private.h"
 #ifdef EVAS_CSERVE2
 #include "evas_cs2_private.h"
@@ -33,7 +34,7 @@ struct _Line
    Span span[2];
 };
 
-static FPc
+static inline FPc
 _interp(int x1, int x2, int p, FPc u1, FPc u2)
 {
    FPc u;
@@ -46,7 +47,7 @@ _interp(int x1, int x2, int p, FPc u1, FPc u2)
    return u1 + u;
 }
 
-static DATA32
+static inline DATA32
 _interp_col(int x1, int x2, int p, DATA32 col1, DATA32 col2)
 {
    x2 -= x1;
@@ -56,7 +57,7 @@ _interp_col(int x1, int x2, int p, DATA32 col1, DATA32 col2)
    return INTERP_256(p, col2, col1);
 }
 
-static void
+static inline void
 _limit(Span *s, int c1, int c2, int nocol)
 {
    if (s->x1 < c1)
@@ -357,17 +358,293 @@ _calc_spans(RGBA_Map_Point *p, Line *spans, int ystart, int yend, int cx, int cy
      }
 }
 
+/* FIXME: Account for 10% during pipe rendering, should be improved
+ * Could be computing the interpolation once somehow.
+ */
+static void
+_clip_spans(Line *spans, int ystart, int yend,
+            int cx, int cw, Eina_Bool nocol)
+{
+   int y, yp;
+
+   for (y = ystart, yp = 0; y <= yend; y++, yp++)
+     {
+        if (spans[yp].span[0].x1 > -1)
+          {
+             if ((spans[yp].span[0].x1 >= (cx + cw)) ||
+                 (spans[yp].span[0].x2 < cx))
+               {
+                  spans[yp].span[0].x1 = -1;
+               }
+             else
+               {
+                  _limit(&(spans[yp].span[0]), cx, cx + cw, nocol);
+
+                  if ((spans[yp].span[1].x1 >= (cx + cw)) ||
+                      (spans[yp].span[1].x2 < cx))
+                    {
+                       spans[yp].span[1].x1 = -1;
+                    }
+                  else
+                    {
+                       _limit(&(spans[yp].span[1]),
+                              spans[yp].span[0].x2,
+                              cx + cw, nocol);
+                    }
+               }
+          }
+     }
+}
+
+typedef struct _RGBA_Map_Spans RGBA_Map_Spans;
+typedef struct _RGBA_Map_Cutout RGBA_Map_Cutout;
+
+struct _RGBA_Map_Spans
+{
+   Line *spans;
+   int size;
+   int ystart;
+   int yend;
+
+   int havecol;
+   Eina_Bool nocol;
+   Eina_Bool havea;
+   Eina_Bool direct;
+};
+
+struct _RGBA_Map_Cutout
+{
+   int count;
+
+   Cutout_Rects *rects;
+   RGBA_Map_Spans spans[1];
+};
+
+EAPI void
+evas_common_map_rgba_clean(RGBA_Map *m)
+{
+   RGBA_Map_Cutout *spans = m->engine_data;
+
+   if (spans)
+     {
+        int i;
+
+        if (spans->rects)
+          evas_common_draw_context_apply_clear_cutouts(spans->rects);
+        for (i = 0; i < spans->count; i++)
+          free(spans->spans[i].spans);
+        free(spans);
+     }
+
+   m->engine_data = NULL;
+}
+
+static void
+_rgba_map_cutout_resize(RGBA_Map *m, int count)
+{
+   RGBA_Map_Cutout *old = m->engine_data;
+   RGBA_Map_Cutout *r;
+   int size;
+   int i;
+
+   if (count == 0)
+     goto empty;
+
+   if (old && old->count == count)
+     {
+        return ;
+     }
+
+   size = sizeof (RGBA_Map_Cutout) + sizeof (RGBA_Map_Spans) * (count - 1);
+
+   if (old)
+     {
+        for (i = 0; i < old->count; i++)
+          {
+             free(old->spans[i].spans);
+             old->spans[i].spans = NULL;
+          }
+     }
+
+   r = realloc(old, size);
+   if (!r)
+     goto empty;
+
+   memset(r, 0, size);
+   m->engine_data = r;
+   r->count = count;
+   return ;
+
+ empty:
+   evas_common_map_rgba_clean(m);
+   return ;
+}
+
+static void
+_evas_common_map_rgba_span(RGBA_Map_Spans *span,
+                           RGBA_Image *src, RGBA_Image *dst,
+                           RGBA_Draw_Context *dc,
+                           RGBA_Map_Point *p,
+                           int cx, int cy, int cw, int ch)
+{
+   int ytop, ybottom, sw;
+   unsigned int i;
+
+   span->havecol = 4;
+   span->havea = 0;
+   span->direct = 0;
+
+   // find y yop line and y bottom line
+   ytop = p[0].y;
+   if ((p[0].col >> 24) < 0xff) span->havea = 1;
+   if (p[0].col == 0xffffffff) span->havecol--;
+   for (i = 1; i < 4; i++)
+     {
+        if (p[i].y < ytop) ytop = p[i].y;
+        if ((p[i].col >> 24) < 0xff) span->havea = 1;
+        if (p[i].col == 0xffffffff) span->havecol--;
+     }
+
+   ybottom = p[0].y;
+   for (i = 1; i < 4; i++)
+     {
+        if (p[i].y > ybottom) ybottom = p[i].y;
+     }
+   
+   // convert to screen space from fixed point
+   ytop = ytop >> FP;
+   ybottom = ybottom >> FP;
+   
+   // if its outside the clip vertical bounds - don't bother
+   if ((ytop >= (cy + ch)) || (ybottom < cy)) return;
+   
+   // limit to the clip vertical bounds
+   if (ytop < cy) span->ystart = cy;
+   else span->ystart = ytop;
+   if (ybottom >= (cy + ch)) span->yend = (cy + ch) - 1;
+   else span->yend = ybottom;
+
+   // get some source image information
+   sw = src->cache_entry.w;
+
+   // limit u,v coords of points to be within the source image
+   for (i = 0; i < 4; i++)
+     {
+        if (p[i].u < 0) p[i].u = 0;
+        else if (p[i].u > (int)(sw << FP))
+          p[i].u = src->cache_entry.w << FP;
+        
+        if (p[i].v < 0) p[i].v = 0;
+        else if (p[i].v > (int)(sw << FP))
+          p[i].v = src->cache_entry.h << FP;
+     }
+   
+   // allocate some spans to hold out span list
+   if (span->size < (span->yend - span->ystart + 1))
+     {
+        free(span->spans);
+        span->size = (span->yend - span->ystart + 1);
+        span->spans = calloc(1, span->size * sizeof(Line));
+     }
+   if (!span->spans) return;
+
+   // calculate the spans list
+   _calc_spans(p, span->spans, span->ystart, span->yend, cx, cy, cw, ch);
+
+   // if operation is solid, bypass buf and draw func and draw direct to dst
+   if ((!src->cache_entry.flags.alpha) && (!dst->cache_entry.flags.alpha) &&
+       (!dc->mul.use) && (!span->havea))
+     {
+        span->direct = 1;
+     }
+}
+
+EAPI Eina_Bool
+evas_common_map_rgba_prepare(RGBA_Image *src, RGBA_Image *dst,
+                             RGBA_Draw_Context *dc,
+                             RGBA_Map *m)
+{
+   RGBA_Map_Cutout *spans;
+   Cutout_Rects *rects;
+   Cutout_Rect *r;
+   int i;
+
+   if ((!dc->cutout.rects) && (!dc->clip.use))
+     {
+       evas_common_draw_context_clip_clip(dc, 0, 0,
+                                           dst->cache_entry.w, dst->cache_entry.h);
+       if ((dc->clip.w <= 0) || (dc->clip.h <= 0))
+         {
+             _rgba_map_cutout_resize(m, 0);
+             return EINA_FALSE;
+         }
+
+        _rgba_map_cutout_resize(m, 1);
+        if (!m->engine_data) return EINA_FALSE;
+
+        spans = m->engine_data;
+
+        _evas_common_map_rgba_span(&spans->spans[0], src, dst, dc, m->pts,
+                                   0, 0,
+                                   dst->cache_entry.w, dst->cache_entry.h);
+        return EINA_TRUE;
+     }
+
+   evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h);
+   /* our clip is 0 size.. abort */
+   if ((dc->clip.w <= 0) || (dc->clip.h <= 0))
+     {
+        _rgba_map_cutout_resize(m, 0);
+        return EINA_FALSE;
+     }
+
+   spans = m->engine_data;
+   if (spans)
+     {
+        rects = spans->rects;
+        spans->rects = NULL;
+     }
+   else
+     {
+        rects = evas_common_draw_context_cutouts_new();
+     }
+   rects = evas_common_draw_context_apply_cutouts(dc, rects);
+   _rgba_map_cutout_resize(m, rects->active);
+
+   spans = m->engine_data;
+   if (!spans)
+     {
+        evas_common_draw_context_apply_clear_cutouts(rects);
+        return EINA_FALSE;
+     }
+
+   spans->rects = rects;
+   for (i = 0; i < spans->rects->active; ++i)
+     {
+       r = spans->rects->rects + i;
+
+       _evas_common_map_rgba_span(&spans->spans[i], src, dst, dc, m->pts,
+                                 r->x, r->y, r->w, r->h);
+     }
+
+   return EINA_TRUE;
+}
+
 #ifdef BUILD_SCALE_SMOOTH
 # ifdef BUILD_MMX
 #  undef FUNC_NAME
+#  undef FUNC_NAME_DO
 #  define FUNC_NAME evas_common_map_rgba_internal_mmx
+#  define FUNC_NAME_DO evas_common_map_rgba_internal_mmx_do
 #  undef SCALE_USING_MMX
 #  define SCALE_USING_MMX
 #  include "evas_map_image_internal.c"
 # endif
 # ifdef BUILD_C
 #  undef FUNC_NAME
+#  undef FUNC_NAME_DO
 #  define FUNC_NAME evas_common_map_rgba_internal
+#  define FUNC_NAME_DO evas_common_map_rgba_internal_do
 #  undef SCALE_USING_MMX
 #  include "evas_map_image_internal.c"
 # endif
@@ -382,7 +659,7 @@ evas_common_map_rgba(RGBA_Image *src, RGBA_Image *dst,
 #ifdef BUILD_MMX
    int mmx, sse, sse2;
 #endif
-   Cutout_Rects *rects;
+   static Cutout_Rects *rects = NULL;
    Cutout_Rect  *r;
    int          c, cx, cy, cw, ch;
    int          i;
@@ -422,7 +699,7 @@ evas_common_map_rgba(RGBA_Image *src, RGBA_Image *dst,
         dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
         return;
      }
-   rects = evas_common_draw_context_apply_cutouts(dc);
+   rects = evas_common_draw_context_apply_cutouts(dc, rects);
    for (i = 0; i < rects->active; ++i)
      {
         r = rects->rects + i;
@@ -436,7 +713,65 @@ evas_common_map_rgba(RGBA_Image *src, RGBA_Image *dst,
           evas_common_map_rgba_internal(src, dst, dc, p, smooth, level);
 #endif        
      }
-   evas_common_draw_context_apply_clear_cutouts(rects);
    /* restore clip info */
    dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
 }
+
+EAPI void
+evas_common_map_rgba_do(const Eina_Rectangle *clip,
+                        RGBA_Image *src, RGBA_Image *dst,
+                       RGBA_Draw_Context *dc,
+                       const RGBA_Map *m,
+                       int smooth, int level)
+{
+#ifdef BUILD_MMX
+   int mmx, sse, sse2;
+#endif
+   const Cutout_Rects *rects;
+   const RGBA_Map_Cutout *spans;
+   Eina_Rectangle area;
+   Cutout_Rect *r;
+   int i;
+
+#ifdef BUILD_MMX
+   evas_common_cpu_can_do(&mmx, &sse, &sse2);
+#endif   
+
+   spans = m->engine_data;
+   rects = spans->rects;
+   if (rects->active == 0 &&
+       spans->count == 1)
+     {
+        evas_common_draw_context_set_clip(dc, clip->x, clip->y, clip->w, clip->h);
+#ifdef BUILD_MMX
+        if (mmx)
+          evas_common_map_rgba_internal_mmx_do(src, dst, dc,
+                                               &spans->spans[0], smooth, level);
+        else
+#endif
+#ifdef BUILD_C
+          evas_common_map_rgba_internal_do(src, dst, dc,
+                                           &spans->spans[0], smooth, level);
+#endif
+        return ;                                         
+     }
+
+   for (i = 0; i < rects->active; ++i)
+     {
+        r = rects->rects + i;
+
+        EINA_RECTANGLE_SET(&area, r->x, r->y, r->w, r->h);
+        if (!eina_rectangle_intersection(&area, clip)) continue ;
+        evas_common_draw_context_set_clip(dc, area.x, area.y, area.w, area.h);
+#ifdef BUILD_MMX
+        if (mmx)
+          evas_common_map_rgba_internal_mmx_do(src, dst, dc,
+                                               &spans->spans[i], smooth, level);
+        else
+#endif
+#ifdef BUILD_C
+          evas_common_map_rgba_internal_do(src, dst, dc,
+                                           &spans->spans[i], smooth, level);
+#endif
+     }
+}
index a7cb8cf..f9c7b97 100644 (file)
@@ -7,4 +7,17 @@ evas_common_map_rgba(RGBA_Image *src, RGBA_Image *dst,
                       int npoints, RGBA_Map_Point *points,
                       int smooth, int level);
 
+EAPI Eina_Bool
+evas_common_map_rgba_prepare(RGBA_Image *src, RGBA_Image *dst,
+                             RGBA_Draw_Context *dc,
+                             RGBA_Map *m);
+EAPI void
+evas_common_map_rgba_do(const Eina_Rectangle *clip,
+                        RGBA_Image *src, RGBA_Image *dst,
+                       RGBA_Draw_Context *dc,
+                       const RGBA_Map *m,
+                       int smooth, int level);
+EAPI void
+evas_common_map_rgba_clean(RGBA_Map *m);
+
 #endif /* _EVAS_MAP_H */
index d60117e..8f4660f 100644 (file)
@@ -74,7 +74,6 @@ FUNC_NAME(RGBA_Image *src, RGBA_Image *dst,
    
    // allocate some spans to hold out span list
    spans = alloca((yend - ystart + 1) * sizeof(Line));
-   if (!spans) return;
    memset(spans, 0, (yend - ystart + 1) * sizeof(Line));
 
    // calculate the spans list
@@ -94,7 +93,6 @@ FUNC_NAME(RGBA_Image *src, RGBA_Image *dst,
         int pa;
         
         buf = alloca(cw * sizeof(DATA32));
-        if (!buf) return;
         pa = src->cache_entry.flags.alpha;
         if (havea) src->cache_entry.flags.alpha = 1;
         if (dc->mul.use)
@@ -115,3 +113,68 @@ FUNC_NAME(RGBA_Image *src, RGBA_Image *dst,
 #include "evas_map_image_core.c"
      }
 }
+
+static void
+FUNC_NAME_DO(RGBA_Image *src, RGBA_Image *dst,
+             RGBA_Draw_Context *dc,
+             const RGBA_Map_Spans *ms,
+             int smooth, int level __UNUSED__) // level unused for now - for future use
+{
+   Line *spans;
+   DATA32 *buf = NULL, *sp;
+   RGBA_Gfx_Func func = NULL;
+   int cx, cy, cw, ch;
+   int ystart, yend, y, sw, shp, swp, direct;
+   int havecol;
+   int i;
+   
+   cx = dc->clip.x;
+   cy = dc->clip.y;
+   cw = dc->clip.w;
+   ch = dc->clip.h;
+
+   if (ms->ystart < cy) ystart = cy;
+   else ystart = ms->ystart;
+   if (ms->yend >= (cy + ch)) yend = (cy + ch) - 1;
+   else yend = ms->yend;
+
+   // get some source image information
+   sp = src->image.data;
+   sw = src->cache_entry.w;
+   swp = sw << (FP + FPI);
+   shp = src->cache_entry.h << (FP + FPI);
+   havecol = ms->havecol;
+   direct = ms->direct;
+
+   // allocate some s to hold out span list
+   spans = alloca((yend - ystart + 1) * sizeof(Line));
+   memcpy(spans, &ms->spans[ystart - ms->ystart],
+          (yend - ystart + 1) * sizeof(Line));
+   _clip_spans(spans, ystart, yend, cx, cw, ms->nocol);
+
+   // if operation is solid, bypass buf and draw func and draw direct to dst
+   if (!direct)
+     {
+        int pa;
+
+        buf = alloca(cw * sizeof(DATA32));
+        pa = src->cache_entry.flags.alpha;
+        if (ms->havea) src->cache_entry.flags.alpha = 1;
+        if (dc->mul.use)
+          func = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, cw, dc->render_op);
+        else
+          func = evas_common_gfx_func_composite_pixel_span_get(src, dst, cw, dc->render_op);
+        src->cache_entry.flags.alpha = pa;
+     }
+    
+   if (!havecol)
+     {
+#undef COLMUL     
+#include "evas_map_image_core.c"
+     }
+   else
+     {
+#define COLMUL 1
+#include "evas_map_image_core.c"
+     }
+}
index 0249595..590bcd4 100644 (file)
@@ -1,5 +1,3 @@
-// THIS IS DEPRECATED. WILL GO EVENTUALLTY. NO NEED TO SUPPORT ANYMORE
-
 #include "evas_common.h"
 #include <unistd.h>
 
@@ -79,14 +77,14 @@ evas_common_pipe_thread(void *data)
 
         EINA_INLIST_FOREACH(thinfo->tasks, info)
           {
-             EINA_INLIST_FOREACH(EINA_INLIST_GET(info->im->cache_entry.pipe), p)
+             EINA_INLIST_FOREACH(EINA_INLIST_GET(thinfo->im->cache_entry.pipe), p)
                {
                   int i;
 
                   for (i = 0; i < p->op_num; i++)
                     {
-                       if (p->op[i].op_func)
-                         p->op[i].op_func(info->im, &(p->op[i]), info);
+                       if (p->op[i].op_func && p->op[i].render)
+                         p->op[i].op_func(thinfo->im, &(p->op[i]), info);
                     }
                }
           }
@@ -100,12 +98,58 @@ evas_common_pipe_thread(void *data)
 #endif
 
 #ifdef BUILD_PTHREAD
+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(im_task_mutex);
+static LK(text_task_mutex);
+
 static int               thread_num = 0;
 static Thinfo            thinfo[TH_MAX];
 static pthread_barrier_t thbarrier[2];
 
 static RGBA_Pipe_Thread_Info *buf = NULL;
 static unsigned int           buf_size = 0;
+
+static Cutout_Rects *
+evas_pipe_cutout_rects_pop(Thinfo *info)
+{
+   Cutout_Rects *r;
+
+   r = eina_array_pop(&info->cutout_trash);
+   if (!r) r = evas_common_draw_context_cutouts_new();
+   return r;
+}
+
+static void
+evas_pipe_cutout_rects_push(Thinfo *info, Cutout_Rects *r)
+{
+   /* evas_common_draw_context_apply_clean_cutouts(r); */
+   evas_common_draw_context_cutouts_free(r);
+   eina_array_push(&info->cutout_trash, r);
+}
+
+static void
+evas_pipe_cutout_rects_rotate(Cutout_Rects *r)
+{
+   static int current = 0;
+
+   if (current >= thread_num) current = 0;
+   evas_pipe_cutout_rects_push(&task_thinfo[current], r);
+   current++;
+}
+
+static void
+evas_pipe_prepare_push(RGBA_Pipe_Op *op)
+{
+   static int current = 0;
+
+   if (current >= thread_num) current = 0;
+   eina_array_push(&task_thinfo[current].rects_task, op);
+   current++;
+}
+
 #endif
 
 static void
@@ -145,12 +189,11 @@ evas_common_pipe_begin(RGBA_Image *im)
    for (y = 0; y < im->cache_entry.h; y += estimatey)
      for (x = 0; x < im->cache_entry.w; x += estimatex)
        {
-          info->im = im;
-          info->x = x;
-          info->y = y;
-          info->w = (x + estimatex > im->cache_entry.w) ? im->cache_entry.w - x : estimatex;
-          info->h = (y + estimatey > im->cache_entry.h) ? im->cache_entry.h - y : estimatey;
+          EINA_RECTANGLE_SET(&info->area, x, y,
+                             (x + estimatex > im->cache_entry.w) ? im->cache_entry.w - x : estimatex,
+                             (y + estimatey > im->cache_entry.h) ? im->cache_entry.h - y : estimatey);
 
+         thinfo[cpu].im = im;
           thinfo[cpu].tasks = eina_inlist_prepend((void*) thinfo[cpu].tasks, EINA_INLIST_GET(info));
           cpu++;
           if (cpu >= (unsigned int) thread_num) cpu = 0;
@@ -180,18 +223,14 @@ evas_common_pipe_flush(RGBA_Image *im)
         RGBA_Pipe *p;
         int i;
 
-        info.im = im;
-        info.x = 0;
-        info.y = 0;
-        info.w = im->cache_entry.w;
-        info.h = im->cache_entry.h;
+        EINA_RECTANGLE_SET(&info.area, 0, 0, im->cache_entry.w, im->cache_entry.h);
 
         /* process pipe - 1 thead */
         for (p = im->cache_entry.pipe; p; p = (RGBA_Pipe *)(EINA_INLIST_GET(p))->next)
           {
              for (i = 0; i < p->op_num; i++)
                {
-                  if (p->op[i].op_func)
+                  if (p->op[i].render && p->op[i].op_func)
                     {
                        p->op[i].op_func(im, &(p->op[i]), &info);
                     }
@@ -223,6 +262,7 @@ evas_common_pipe_free(RGBA_Image *im)
                {
                   p->op[i].free_func(&(p->op[i]));
                }
+             if (p->op[i].rects) evas_pipe_cutout_rects_rotate(p->op[i].rects);
           }
         im->cache_entry.pipe = (RGBA_Pipe *)eina_inlist_remove(EINA_INLIST_GET(im->cache_entry.pipe), EINA_INLIST_GET(p));
         free(p);
@@ -239,10 +279,28 @@ evas_common_pipe_rectangle_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, cons
    RGBA_Draw_Context context;
 
    memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
-   evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
-   evas_common_rectangle_draw(dst, &(context),
-                              op->op.rect.x, op->op.rect.y,
-                              op->op.rect.w, op->op.rect.h);
+   evas_common_rectangle_draw_do(op->rects, &info->area, dst, &(context),
+                                op->op.rect.x, op->op.rect.y,
+                                op->op.rect.w, op->op.rect.h);
+}
+
+static Eina_Bool
+evas_common_pipe_rectangle_prepare(void *data, RGBA_Image *dst, RGBA_Pipe_Op *op)
+{
+   RGBA_Draw_Context context;
+   Cutout_Rects *recycle;
+   Thinfo *info = data;
+   Eina_Bool r;
+
+   recycle = evas_pipe_cutout_rects_pop(info);
+   memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
+   r = evas_common_rectangle_draw_prepare(recycle, dst, &context,
+                                          op->op.rect.x, op->op.rect.y,
+                                          op->op.rect.w, op->op.rect.h);
+   if (recycle->active) op->rects = recycle;
+   else evas_pipe_cutout_rects_push(info, recycle);
+
+   return r;
 }
 
 EAPI void
@@ -259,6 +317,8 @@ evas_common_pipe_rectangle_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, i
    op->op.rect.h = h;
    op->op_func = evas_common_pipe_rectangle_draw_do;
    op->free_func = evas_common_pipe_op_free;
+   op->prepare_func = evas_common_pipe_rectangle_prepare;
+   evas_pipe_prepare_push(op);
    evas_common_pipe_draw_context_copy(dc, op);
 }
 
@@ -269,7 +329,7 @@ evas_common_pipe_line_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGB
    RGBA_Draw_Context context;
 
    memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
-   evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
+   evas_common_draw_context_clip_clip(&(context), info->area.x, info->area.y, info->area.w, info->area.h);
    evas_common_line_draw(dst, &(context),
                          op->op.line.x0, op->op.line.y0,
                          op->op.line.x1, op->op.line.y1);
@@ -289,6 +349,7 @@ evas_common_pipe_line_draw(RGBA_Image *dst, RGBA_Draw_Context *dc,
    op->op.line.y1 = y1;
    op->op_func = evas_common_pipe_line_draw_do;
    op->free_func = evas_common_pipe_op_free;
+   op->prepare_func = NULL;
    evas_common_pipe_draw_context_copy(dc, op);
 }
 
@@ -298,6 +359,7 @@ evas_common_pipe_op_poly_free(RGBA_Pipe_Op *op)
 {
    RGBA_Polygon_Point *p;
 
+#if 0
    while (op->op.poly.points)
      {
         p = op->op.poly.points;
@@ -305,6 +367,7 @@ evas_common_pipe_op_poly_free(RGBA_Pipe_Op *op)
                                                       EINA_INLIST_GET(p));
         free(p);
      }
+#endif
    evas_common_pipe_op_free(op);
 }
 
@@ -314,9 +377,9 @@ evas_common_pipe_poly_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGB
    RGBA_Draw_Context context;
 
    memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
-   evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
+   evas_common_draw_context_clip_clip(&(context), info->area.x, info->area.y, info->area.w, info->area.h);
    evas_common_polygon_draw(dst, &(context),
-                            op->op.poly.points, 0, 0);
+                            op->op.poly.points, op->op.poly.x, op->op.poly.y);
 }
 
 EAPI void
@@ -324,12 +387,13 @@ evas_common_pipe_poly_draw(RGBA_Image *dst, RGBA_Draw_Context *dc,
                            RGBA_Polygon_Point *points, int x, int y)
 {
    RGBA_Pipe_Op *op;
-   RGBA_Polygon_Point *pts = NULL, *p, *pp;
+   /* RGBA_Polygon_Point *pts = NULL, *p, *pp; */
 
    if (!points) return;
    dst->cache_entry.pipe = evas_common_pipe_add(dst->cache_entry.pipe, &op);
    if (!dst->cache_entry.pipe) return;
    /* FIXME: copy points - maybe we should refcount? */
+#if 0
    for (p = points; p; p = (RGBA_Polygon_Point *)(EINA_INLIST_GET(p))->next)
      {
         pp = calloc(1, sizeof(RGBA_Polygon_Point));
@@ -340,9 +404,13 @@ evas_common_pipe_poly_draw(RGBA_Image *dst, RGBA_Draw_Context *dc,
              pts = (RGBA_Polygon_Point *)eina_inlist_append(EINA_INLIST_GET(pts), EINA_INLIST_GET(pp));
           }
      }
-   op->op.poly.points = pts;
+#endif
+   op->op.poly.x = x;
+   op->op.poly.y = y;
+   op->op.poly.points = points/* pts */;
    op->op_func = evas_common_pipe_poly_draw_do;
    op->free_func = evas_common_pipe_op_poly_free;
+   op->prepare_func = NULL; /* FIXME: If we really want to improve it, we should prepare span for it here */
    evas_common_pipe_draw_context_copy(dc, op);
 }
 
@@ -360,8 +428,24 @@ evas_common_pipe_text_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGB
    RGBA_Draw_Context context;
 
    memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
-   evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
-   evas_common_font_draw(dst, &(context), op->op.text.x, op->op.text.y, op->op.text.intl_props);
+   evas_common_font_draw_do(op->rects, &info->area, op->op.text.func, dst, &(context), op->op.text.x, op->op.text.y, op->op.text.intl_props);
+}
+
+static Eina_Bool
+evas_common_pipe_text_draw_prepare(void *data, RGBA_Image *dst, RGBA_Pipe_Op *op)
+{
+   RGBA_Draw_Context context;
+   Cutout_Rects *recycle;
+   Thinfo *info = data;
+   Eina_Bool r;
+
+   recycle = evas_pipe_cutout_rects_pop(info);
+   memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
+   r = evas_common_font_draw_prepare_cutout(recycle, dst, &context, &(op->op.text.func));
+   if (recycle->active) op->rects = recycle;
+   else evas_pipe_cutout_rects_push(info, recycle);
+
+   return r;
 }
 
 EAPI void
@@ -378,6 +462,8 @@ evas_common_pipe_text_draw(RGBA_Image *dst, RGBA_Draw_Context *dc,
    evas_common_text_props_content_ref(intl_props);
    op->op_func = evas_common_pipe_text_draw_do;
    op->free_func = evas_common_pipe_op_text_free;
+   op->prepare_func = evas_common_pipe_text_draw_prepare;
+   evas_pipe_prepare_push(op);
    evas_common_pipe_draw_context_copy(dc, op);
    evas_common_pipe_text_prepare(intl_props);
 }
@@ -394,15 +480,35 @@ evas_common_pipe_op_image_free(RGBA_Pipe_Op *op)
    evas_common_pipe_op_free(op);
 }
 
+static Eina_Bool
+evas_common_pipe_op_image_prepare(void *data, RGBA_Image *dst, RGBA_Pipe_Op *op)
+{
+   RGBA_Draw_Context context;
+   Cutout_Rects *recycle;
+   Thinfo *info = data;
+   Eina_Bool r;
+
+   recycle = evas_pipe_cutout_rects_pop(info);
+   memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
+   r = evas_common_scale_rgba_in_to_out_clip_prepare(recycle, op->op.image.src, dst, &(context),
+                                                     op->op.image.dx, op->op.image.dy,
+                                                     op->op.image.dw, op->op.image.dh);
+   if (recycle->active) op->rects = recycle;
+   else evas_pipe_cutout_rects_push(info, recycle);
+
+   return r;
+}
+
 static void
 evas_common_pipe_image_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA_Pipe_Thread_Info *info)
 {
    RGBA_Draw_Context context;
 
    memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
-   evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
 
 #ifdef SCALECACHE
+   /* FIXME: Make the scalecache path use the prepared Cutout ? */
+   evas_common_draw_context_clip_clip(&(context), info->area.x, info->area.y, info->area.w, info->area.h);
    evas_common_rgba_image_scalecache_do((Image_Entry *)(op->op.image.src),
                                         dst, &(context),
                                         op->op.image.smooth,
@@ -417,29 +523,31 @@ evas_common_pipe_image_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RG
 #else
    if (op->op.image.smooth)
      {
-        evas_common_scale_rgba_in_to_out_clip_smooth(op->op.image.src,
-                                                     dst, &(context),
-                                                     op->op.image.sx,
-                                                     op->op.image.sy,
-                                                     op->op.image.sw,
-                                                     op->op.image.sh,
-                                                     op->op.image.dx,
-                                                     op->op.image.dy,
-                                                     op->op.image.dw,
-                                                     op->op.image.dh);
+        evas_common_scale_rgba_in_to_out_clip_smooth_do(op->rects, &info->area,
+                                                        op->op.image.src,
+                                                        dst, &(context),
+                                                        op->op.image.sx,
+                                                        op->op.image.sy,
+                                                        op->op.image.sw,
+                                                        op->op.image.sh,
+                                                        op->op.image.dx,
+                                                        op->op.image.dy,
+                                                        op->op.image.dw,
+                                                        op->op.image.dh);
      }
    else
      {
-        evas_common_scale_rgba_in_to_out_clip_sample(op->op.image.src,
-                                                     dst, &(context),
-                                                     op->op.image.sx,
-                                                     op->op.image.sy,
-                                                     op->op.image.sw,
-                                                     op->op.image.sh,
-                                                     op->op.image.dx,
-                                                     op->op.image.dy,
-                                                     op->op.image.dw,
-                                                     op->op.image.dh);
+        evas_common_scale_rgba_in_to_out_clip_sample_do(op->rects, &info->area,
+                                                        op->op.image.src,
+                                                        dst, &(context),
+                                                        op->op.image.sx,
+                                                        op->op.image.sy,
+                                                        op->op.image.sw,
+                                                        op->op.image.sh,
+                                                        op->op.image.dx,
+                                                        op->op.image.dy,
+                                                        op->op.image.dw,
+                                                        op->op.image.dh);
      }
 #endif
 }
@@ -471,6 +579,8 @@ evas_common_pipe_image_draw(RGBA_Image *src, RGBA_Image *dst,
    op->op.image.src = src;
    op->op_func = evas_common_pipe_image_draw_do;
    op->free_func = evas_common_pipe_op_image_free;
+   op->prepare_func = evas_common_pipe_op_image_prepare;
+   evas_pipe_prepare_push(op);
    evas_common_pipe_draw_context_copy(dc, op);
 
    evas_common_pipe_image_load(src);
@@ -482,7 +592,7 @@ evas_common_pipe_op_map_free(RGBA_Pipe_Op *op)
    op->op.map.src->ref--;
    if (op->op.map.src->ref == 0)
      evas_cache_image_drop(&op->op.map.src->cache_entry);
-   free(op->op.map.p);
+   /* free(op->op.map.p); */
    evas_common_pipe_op_free(op);
 }
 
@@ -492,43 +602,56 @@ evas_common_pipe_map_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA
    RGBA_Draw_Context context;
 
    memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
-   evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
+   evas_common_map_rgba_do(&info->area, op->op.map.src, dst,
+                           &context, op->op.map.m,
+                           op->op.map.smooth, op->op.map.level);
+}
+
+static Eina_Bool
+evas_common_pipe_map_draw_prepare(void *data, RGBA_Image *dst, RGBA_Pipe_Op *op)
+{
+   RGBA_Draw_Context context;
+   Thinfo *info = data; 
+   Eina_Bool r; 
+
+   memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
+   r = evas_common_map_rgba_prepare(op->op.map.src, dst,
+                                   &context, op->op.map.m);
 
-   evas_common_map_rgba(op->op.map.src, dst,
-                        &context, op->op.map.npoints, op->op.map.p,
-                        op->op.map.smooth, op->op.map.level);
+   return r;
 }
 
 EAPI void
 evas_common_pipe_map_draw(RGBA_Image *src, RGBA_Image *dst,
-                          RGBA_Draw_Context *dc, int npoints, RGBA_Map_Point *p,
+                          RGBA_Draw_Context *dc, RGBA_Map *m,
                           int smooth, int level)
 {
    RGBA_Pipe_Op *op;
-   RGBA_Map_Point *pts_copy;
+   /* RGBA_Map_Point *pts_copy; */
    int i;
 
    if (!src) return;
-   pts_copy = malloc(sizeof (RGBA_Map_Point) * 4);
-   if (!pts_copy) return;
+   /* pts_copy = malloc(sizeof (RGBA_Map_Point) * 4); */
+   /* if (!pts_copy) return; */
    dst->cache_entry.pipe = evas_common_pipe_add(dst->cache_entry.pipe, &op);
    if (!dst->cache_entry.pipe) 
      {
-       free(pts_copy);
+       /* free(pts_copy); */
        return; 
      }
 
-   for (i = 0; i < 4; ++i)
-     pts_copy[i] = p[i];
+   /* for (i = 0; i < 4; ++i) */
+   /*   pts_copy[i] = p[i]; */
 
-   op->op.map.npoints = npoints;
    op->op.map.smooth = smooth;
    op->op.map.level = level;
    src->ref++;
    op->op.map.src = src;
-   op->op.map.p = pts_copy;
+   op->op.map.m = m;
    op->op_func = evas_common_pipe_map_draw_do;
    op->free_func = evas_common_pipe_op_map_free;
+   op->prepare_func = evas_common_pipe_map_draw_prepare;
+   evas_pipe_prepare_push(op);
    evas_common_pipe_draw_context_copy(dc, op);
 
    evas_common_pipe_image_load(src);
@@ -563,15 +686,6 @@ evas_common_pipe_map_render(RGBA_Image *root)
 }
 
 #ifdef BUILD_PTHREAD
-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(im_task_mutex);
-static LK(text_task_mutex);
-#endif
-
-#ifdef BUILD_PTHREAD
 static void*
 evas_common_pipe_load(void *data)
 {
@@ -580,6 +694,9 @@ evas_common_pipe_load(void *data)
   tinfo = data;
   for (;;)
     {
+      RGBA_Pipe_Op *op;
+      Eina_Array_Iterator it;
+      unsigned int i;
       /* wait for start signal */
       pthread_barrier_wait(&(tinfo->barrier[0]));
 
@@ -625,6 +742,10 @@ evas_common_pipe_load(void *data)
              }
        }
 
+      EINA_ARRAY_ITER_NEXT(&tinfo->rects_task, i, op, it)
+        op->render = op->prepare_func(tinfo, tinfo->im, op);
+      eina_array_clean(&tinfo->rects_task);
+
       /* send finished signal */
       pthread_barrier_wait(&(tinfo->barrier[1]));
     }
@@ -636,20 +757,23 @@ evas_common_pipe_load(void *data)
 static volatile int bval = 0;
 
 static void
-evas_common_pipe_load_do(void)
+evas_common_pipe_load_do(RGBA_Image *im)
 {
 #ifdef BUILD_PTHREAD
-  if (!im_task && !text_task) return ;
+   int i;
 
-  /* Notify worker thread. */
-  pthread_barrier_wait(&(task_thbarrier[0]));
+   for (i = 0; i < thread_num; i++)
+     task_thinfo[i].im = im;
 
-  /* sync worker threads */
-  pthread_barrier_wait(&(task_thbarrier[1]));
+   /* Notify worker thread. */
+   pthread_barrier_wait(&(task_thbarrier[0]));
+
+   /* sync worker threads */
+   pthread_barrier_wait(&(task_thbarrier[1]));
 #endif
 }
 
-static Eina_Bool
+EAPI Eina_Bool
 evas_common_pipe_init(void)
 {
 #ifdef BUILD_PTHREAD
@@ -703,6 +827,8 @@ evas_common_pipe_init(void)
             task_thinfo[i].thread_num = i;
             task_thinfo[i].tasks = NULL;
             task_thinfo[i].barrier = task_thbarrier;
+             eina_array_step_set(&task_thinfo[i].cutout_trash, sizeof (Eina_Array), 8);
+             eina_array_step_set(&task_thinfo[i].rects_task, sizeof (Eina_Array), 8);
             /* setup initial locks */
             pthread_create(&(task_thinfo[i].thread_id), &attr,
                            evas_common_pipe_load, &(task_thinfo[i]));
@@ -746,7 +872,7 @@ evas_common_pipe_text_prepare(Evas_Text_Props *text_props)
    fi = text_props->font_instance;
    if (!fi) return ;
 
-   if (!text_props->changed && text_props->generation == fi->generation && text_props->bin)
+   if (!text_props->changed && text_props->generation == fi->generation && text_props->glyphs)
      return ;
 
    LKL(fi->ft_mutex);
@@ -783,7 +909,7 @@ evas_common_pipe_map_begin(RGBA_Image *root)
        }
     }
 
-  evas_common_pipe_load_do();
+  evas_common_pipe_load_do(root);
 
   evas_common_pipe_map_render(root);
 }
index b461424..c6a28ff 100644 (file)
@@ -7,10 +7,13 @@
 #ifdef BUILD_PTHREAD
 typedef struct _Thinfo
 {
+   RGBA_Image            *im;
    int                    thread_num;
    pthread_t              thread_id;
    pthread_barrier_t     *barrier;
    const Eina_Inlist     *tasks;
+   Eina_Array             cutout_trash;
+   Eina_Array             rects_task;
 } Thinfo;
 #endif
 
@@ -18,6 +21,8 @@ typedef struct _Thinfo
  * threadable
  */
 
+EAPI Eina_Bool evas_common_pipe_init(void);
+
 EAPI void evas_common_pipe_free(RGBA_Image *im);
 EAPI void evas_common_pipe_rectangle_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h);
 EAPI void evas_common_pipe_line_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1);
@@ -28,8 +33,8 @@ 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);
 EAPI void evas_common_pipe_map_draw(RGBA_Image *src, RGBA_Image *dst,
-                                    RGBA_Draw_Context *dc, int npoints, RGBA_Map_Point *p,
-                                    int smooth, int level);
+                                   RGBA_Draw_Context *dc, RGBA_Map *m,
+                                   int smooth, int level);
 EAPI void evas_common_pipe_flush(RGBA_Image *im);
 
 #endif /* _EVAS_PIPE_H */
index a653b04..8fdcb77 100644 (file)
@@ -6,6 +6,8 @@ EAPI void           evas_common_rectangle_init          (void);
 
 EAPI void           evas_common_rectangle_draw          (RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h);
 
+EAPI void evas_common_rectangle_draw_do(const Cutout_Rects *reuse, const Eina_Rectangle *clip, RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h);
+EAPI Eina_Bool evas_common_rectangle_draw_prepare(Cutout_Rects *reuse, const RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h);
 
 #endif /* _EVAS_RECTANGLE_H */
 
index cd3d16c..4074761 100644 (file)
@@ -1,4 +1,5 @@
 #include "evas_common.h"
+#include "evas_private.h"
 #include "evas_blend_private.h"
 
 static void rectangle_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h);
@@ -11,7 +12,7 @@ evas_common_rectangle_init(void)
 EAPI void
 evas_common_rectangle_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h)
 {
-   Cutout_Rects *rects;
+   static Cutout_Rects *rects = NULL;
    Cutout_Rect  *r;
    int          c, cx, cy, cw, ch;
    int          i;
@@ -34,20 +35,67 @@ evas_common_rectangle_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y,
        /* our clip is 0 size.. abort */
        if ((dc->clip.w > 0) && (dc->clip.h > 0))
          {
-            rects = evas_common_draw_context_apply_cutouts(dc);
+             rects = evas_common_draw_context_apply_cutouts(dc, rects);
             for (i = 0; i < rects->active; ++i)
               {
                  r = rects->rects + i;
                  evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
                  rectangle_draw_internal(dst, dc, x, y, w, h);
               }
-            evas_common_draw_context_apply_clear_cutouts(rects);
          }
      }
    /* restore clip info */
    dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
 }
 
+EAPI Eina_Bool
+evas_common_rectangle_draw_prepare(Cutout_Rects *reuse, const RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h)
+{
+   if ((w <= 0) || (h <= 0)) return EINA_FALSE;
+   if (!(RECTS_INTERSECT(x, y, w, h, 0, 0, dst->cache_entry.w, dst->cache_entry.h)))
+     return EINA_FALSE;
+   /* save out clip info */
+   evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h);
+   /* no cutouts - cut right to the chase */
+   if (dc->cutout.rects)
+     {
+       evas_common_draw_context_clip_clip(dc, x, y, w, h);
+       /* our clip is 0 size.. abort */
+       if ((dc->clip.w > 0) && (dc->clip.h > 0))
+        reuse = evas_common_draw_context_apply_cutouts(dc, reuse);
+     }
+
+   return EINA_TRUE;
+}
+
+EAPI void
+evas_common_rectangle_draw_do(const Cutout_Rects *reuse,
+                              const Eina_Rectangle *clip,
+                              RGBA_Image *dst, RGBA_Draw_Context *dc,
+                              int x, int y, int w, int h)
+{
+   Eina_Rectangle area;
+   Cutout_Rect *r;
+   int i;
+
+   if (!reuse)
+     {
+        evas_common_draw_context_set_clip(dc, clip->x, clip->y, clip->w, clip->h);
+        rectangle_draw_internal(dst, dc, x, y, w, h);
+        return ;
+     }
+
+   for (i = 0; i < reuse->active; ++i)
+     {
+        r = reuse->rects + i;
+
+        EINA_RECTANGLE_SET(&area, r->x, r->y, r->w, r->h);
+        if (!eina_rectangle_intersection(&area, clip)) continue ;
+        evas_common_draw_context_set_clip(dc, area.x, area.y, area.w, area.h);
+        rectangle_draw_internal(dst, dc, x, y, w, h);
+     }
+}
+
 static void
 rectangle_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h)
 {
index 959336c..bb11c6b 100644 (file)
@@ -1,6 +1,33 @@
 #include "evas_common.h"
+#include "evas_private.h"
 
 EAPI void
 evas_common_scale_init(void)
 {
 }
+
+EAPI Eina_Bool
+evas_common_scale_rgba_in_to_out_clip_prepare(Cutout_Rects *reuse, const RGBA_Image *src __UNUSED__,
+                                             const RGBA_Image *dst,
+                                             RGBA_Draw_Context *dc,
+                                             int dst_region_x, int dst_region_y,
+                                             int dst_region_w, int dst_region_h)
+{
+   /* handle cutouts here! */
+   if ((dst_region_w <= 0) || (dst_region_h <= 0)) return EINA_FALSE;
+   if (!(RECTS_INTERSECT(dst_region_x, dst_region_y, dst_region_w, dst_region_h,
+                        0, 0, dst->cache_entry.w, dst->cache_entry.h)))
+     return EINA_FALSE;
+   /* no cutouts - cut right to the chase */
+   if (!dc->cutout.rects) return EINA_TRUE;
+
+   evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h);
+   evas_common_draw_context_clip_clip(dc, dst_region_x, dst_region_y, dst_region_w, dst_region_h);
+   /* our clip is 0 size.. abort */
+   if ((dc->clip.w <= 0) || (dc->clip.h <= 0))
+     return EINA_FALSE;
+   reuse = evas_common_draw_context_apply_cutouts(dc, reuse);
+
+   return EINA_TRUE;
+}
+
index eafd9d2..e2ef8fa 100644 (file)
@@ -10,4 +10,9 @@ EAPI void evas_common_scale_rgba_in_to_out_clip_sample      (RGBA_Image *src, RG
 
 EAPI void evas_common_rgba_image_scalecache_dump(void);
 
+EAPI void evas_common_scale_rgba_in_to_out_clip_sample_do   (const Cutout_Rects *reuse, const Eina_Rectangle *clip, RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, 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_scale_rgba_in_to_out_clip_smooth_do   (const Cutout_Rects *reuse, const Eina_Rectangle *clip, RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, 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 Eina_Bool evas_common_scale_rgba_in_to_out_clip_prepare     (Cutout_Rects *reuse, const RGBA_Image *src, const RGBA_Image *dst, RGBA_Draw_Context *dc, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h);
+
+
 #endif /* _EVAS_SCALE_MAIN_H */
index 3b23221..ea10618 100644 (file)
@@ -1,11 +1,28 @@
 #include "evas_common.h"
 #include "evas_blend_private.h"
 
-void scale_rgba_in_to_out_clip_sample_internal(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, 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);
+static void scale_rgba_in_to_out_clip_sample_internal(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, 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);
 
 #ifndef BUILD_SCALE_SMOOTH
 #ifdef BUILD_SCALE_SAMPLE
 EAPI void
+evas_common_scale_rgba_in_to_out_clip_smooth_do(const Cutout_Rects *reuse,
+                                                const Eina_Rectangle *clip,
+                                                RGBA_Image *src, RGBA_Image *dst,
+                                                RGBA_Draw_Context *dc,
+                                                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)
+{
+   evas_common_scale_rgba_in_to_out_clip_sample_do(reuse, clip, src, dst, dc,
+                                   src_region_x, src_region_y,
+                                   src_region_w, src_region_h,
+                                   dst_region_x, dst_region_y,
+                                   dst_region_w, dst_region_h);
+}
+
+EAPI void
 evas_common_scale_rgba_in_to_out_clip_smooth(RGBA_Image *src, RGBA_Image *dst,
                                 RGBA_Draw_Context *dc,
                                 int src_region_x, int src_region_y,
@@ -31,7 +48,7 @@ evas_common_scale_rgba_in_to_out_clip_sample(RGBA_Image *src, RGBA_Image *dst,
                                 int dst_region_x, int dst_region_y,
                                 int dst_region_w, int dst_region_h)
 {
-   Cutout_Rects *rects;
+   static Cutout_Rects *rects = NULL;
    Cutout_Rect  *r;
    int          c, cx, cy, cw, ch;
    int          i;
@@ -60,7 +77,7 @@ evas_common_scale_rgba_in_to_out_clip_sample(RGBA_Image *src, RGBA_Image *dst,
        dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
        return;
      }
-   rects = evas_common_draw_context_apply_cutouts(dc);
+   rects = evas_common_draw_context_apply_cutouts(dc, rects);
    for (i = 0; i < rects->active; ++i)
      {
        r = rects->rects + i;
@@ -72,12 +89,51 @@ evas_common_scale_rgba_in_to_out_clip_sample(RGBA_Image *src, RGBA_Image *dst,
                                                  dst_region_w, dst_region_h);
 
      }
-   evas_common_draw_context_apply_clear_cutouts(rects);
    /* restore clip info */
    dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
 }
 
-void
+EAPI void
+evas_common_scale_rgba_in_to_out_clip_sample_do(const Cutout_Rects *reuse,
+                                                const Eina_Rectangle *clip,
+                                                RGBA_Image *src, RGBA_Image *dst,
+                                                RGBA_Draw_Context *dc,
+                                                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)
+{
+   Eina_Rectangle area;
+   Cutout_Rect *r;
+   int i;
+
+   if (!reuse)
+     {
+        evas_common_draw_context_set_clip(dc, clip->x, clip->y, clip->w, clip->h);
+        scale_rgba_in_to_out_clip_sample_internal(src, dst, dc,
+                                                  src_region_x, src_region_y,
+                                                  src_region_w, src_region_h,
+                                                  dst_region_x, dst_region_y,
+                                                  dst_region_w, dst_region_h);
+        return;
+     }
+
+   for (i = 0; i < reuse->active; ++i)
+     {
+        r = reuse->rects + i;
+
+        EINA_RECTANGLE_SET(&area, r->x, r->y, r->w, r->h);
+        if (!eina_rectangle_intersection(&area, clip)) continue ;
+        evas_common_draw_context_set_clip(dc, area.x, area.y, area.w, area.h);
+        scale_rgba_in_to_out_clip_sample_internal(src, dst, dc,
+                                                  src_region_x, src_region_y,
+                                                  src_region_w, src_region_h,
+                                                  dst_region_x, dst_region_y,
+                                                  dst_region_w, dst_region_h);
+     }
+}
+
+static void
 scale_rgba_in_to_out_clip_sample_internal(RGBA_Image *src, RGBA_Image *dst,
                                          RGBA_Draw_Context *dc,
                                          int src_region_x, int src_region_y,
@@ -403,5 +459,22 @@ evas_common_scale_rgba_in_to_out_clip_sample(RGBA_Image *src, RGBA_Image *dst,
                                    dst_region_x, dst_region_y,
                                    dst_region_w, dst_region_h);
 }
+
+EAPI void
+evas_common_scale_rgba_in_to_out_clip_sample_do(const Cutout_Rects *reuse,
+                                                const Eina_Rectangle *clip,
+                                                RGBA_Image *src, RGBA_Image *dst,
+                                                RGBA_Draw_Context *dc,
+                                                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)
+{
+   evas_common_scale_rgba_in_to_out_clip_smooth_do(reuse, clip, src, dst, dc,
+                                   src_region_x, src_region_y,
+                                   src_region_w, src_region_h,
+                                   dst_region_x, dst_region_y,
+                                   dst_region_w, dst_region_h);
+}
 #endif
 #endif
index d3aada6..ca85203 100644 (file)
@@ -460,7 +460,7 @@ evas_common_scale_rgba_in_to_out_clip_smooth(RGBA_Image *src, RGBA_Image *dst,
 # ifdef BUILD_MMX
    int mmx, sse, sse2;
 # endif
-   Cutout_Rects *rects;
+   static Cutout_Rects *rects = NULL;
    Cutout_Rect  *r;
    int          c, cx, cy, cw, ch;
    int          i;
@@ -503,7 +503,7 @@ evas_common_scale_rgba_in_to_out_clip_smooth(RGBA_Image *src, RGBA_Image *dst,
        dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
        return;
      }
-   rects = evas_common_draw_context_apply_cutouts(dc);
+   rects = evas_common_draw_context_apply_cutouts(dc, rects);
    for (i = 0; i < rects->active; ++i)
      {
        r = rects->rects + i;
@@ -525,8 +525,76 @@ evas_common_scale_rgba_in_to_out_clip_smooth(RGBA_Image *src, RGBA_Image *dst,
                                             dst_region_w, dst_region_h);
 # endif
      }
-   evas_common_draw_context_apply_clear_cutouts(rects);
    /* restore clip info */
    dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
 }
+
+EAPI void
+evas_common_scale_rgba_in_to_out_clip_smooth_do(const Cutout_Rects *reuse,
+                                               const Eina_Rectangle *clip,
+                                               RGBA_Image *src, RGBA_Image *dst,
+                                               RGBA_Draw_Context *dc,
+                                               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)
+{
+# ifdef BUILD_MMX
+   int mmx, sse, sse2;
+# endif
+   Eina_Rectangle area;
+   Cutout_Rect *r;
+   int i;
+
+# ifdef BUILD_MMX
+   evas_common_cpu_can_do(&mmx, &sse, &sse2);
+# endif
+   if (!reuse)
+     {
+        evas_common_draw_context_set_clip(dc, clip->x, clip->y, clip->w, clip->h);
+# ifdef BUILD_MMX
+       if (mmx)
+         evas_common_scale_rgba_in_to_out_clip_smooth_mmx(src, dst, dc,
+                                              src_region_x, src_region_y,
+                                              src_region_w, src_region_h,
+                                              dst_region_x, dst_region_y,
+                                              dst_region_w, dst_region_h);
+       else
+# endif
+# ifdef BUILD_C
+         evas_common_scale_rgba_in_to_out_clip_smooth_c(src, dst, dc,
+                                            src_region_x, src_region_y,
+                                            src_region_w, src_region_h,
+                                            dst_region_x, dst_region_y,
+                                            dst_region_w, dst_region_h);
+# endif
+        return ;
+     }
+
+   for (i = 0; i < reuse->active; ++i)
+     {
+        r = reuse->rects + i;
+
+        EINA_RECTANGLE_SET(&area, r->x, r->y, r->w, r->h);
+        if (!eina_rectangle_intersection(&area, clip)) continue ;
+        evas_common_draw_context_set_clip(dc, area.x, area.y, area.w, area.h);
+# ifdef BUILD_MMX
+       if (mmx)
+         evas_common_scale_rgba_in_to_out_clip_smooth_mmx(src, dst, dc,
+                                              src_region_x, src_region_y,
+                                              src_region_w, src_region_h,
+                                              dst_region_x, dst_region_y,
+                                              dst_region_w, dst_region_h);
+       else
+# endif
+# ifdef BUILD_C
+         evas_common_scale_rgba_in_to_out_clip_smooth_c(src, dst, dc,
+                                            src_region_x, src_region_y,
+                                            src_region_w, src_region_h,
+                                            dst_region_x, dst_region_y,
+                                            dst_region_w, dst_region_h);
+# endif
+     }
+}
+
 #endif
index c1c1a23..acdcc00 100644 (file)
@@ -36,6 +36,8 @@ evas_common_text_props_content_copy_and_ref(Evas_Text_Props *dst,
       const Evas_Text_Props *src)
 {
    memcpy(dst, src, sizeof(Evas_Text_Props));
+   dst->glyphs = NULL;
+   dst->glyphs_length = 0;
    evas_common_text_props_content_ref(dst);
 }
 
@@ -66,11 +68,9 @@ evas_common_text_props_content_unref(Evas_Text_Props *props)
    
    if (--(props->info->refcount) == 0)
      {
-        if (props->bin)
-          {
-             eina_binbuf_free(props->bin);
-             props->bin = NULL;
-          }
+        free(props->glyphs);
+        props->glyphs = NULL;
+        props->glyphs_length = 0;
 
         if (props->info->glyph)
           free(props->info->glyph);
index a10ce7d..675df6c 100644 (file)
@@ -18,6 +18,8 @@ typedef enum
 /* Used for showing "malformed" or missing chars */
 #define REPLACEMENT_CHAR 0xFFFD
 
+typedef struct _Evas_Glyph Evas_Glyph;
+
 struct _Evas_Text_Props
 {
    /* Start and len represent the start offset and the length in the
@@ -31,7 +33,8 @@ struct _Evas_Text_Props
    Evas_Text_Props_Info *info;
    void *font_instance;
 
-   Eina_Binbuf *bin;
+   Evas_Glyph *glyphs;
+   int glyphs_length;
 
    int generation;
    Eina_Bool changed : 1;
index 6028744..5258b7d 100644 (file)
@@ -474,8 +474,8 @@ evas_common_soft16_image_draw(Soft16_Image *src, Soft16_Image *dst,
                  int dst_region_w, int dst_region_h,
                  int smooth __UNUSED__)
 {
+   static Cutout_Rects *rects = NULL;
    Eina_Rectangle sr, dr;
-   Cutout_Rects *rects;
    Cutout_Rect  *r;
    struct RGBA_Draw_Context_clip clip_bkp;
    int i;
@@ -510,14 +510,13 @@ evas_common_soft16_image_draw(Soft16_Image *src, Soft16_Image *dst,
        dc->clip = clip_bkp;
        return;
      }
-   rects = evas_common_draw_context_apply_cutouts(dc);
+   rects = evas_common_draw_context_apply_cutouts(dc, rects);
    for (i = 0; i < rects->active; i++)
      {
        r = rects->rects + i;
        evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
        _soft16_image_draw_sampled_int(src, dst, dc, sr, dr);
      }
-   evas_common_draw_context_apply_clear_cutouts(rects);
    dc->clip = clip_bkp;
 }
 
index bd38fce..ac6aa46 100644 (file)
@@ -78,8 +78,8 @@ void
 evas_common_soft16_rectangle_draw(Soft16_Image *dst, RGBA_Draw_Context *dc,
                       int x, int y, int w, int h)
 {
+   static Cutout_Rects *rects = NULL;
    Eina_Rectangle dr;
-   Cutout_Rects *rects;
    Cutout_Rect  *r;
    struct RGBA_Draw_Context_clip c_bkp;
    int i;
@@ -108,14 +108,13 @@ evas_common_soft16_rectangle_draw(Soft16_Image *dst, RGBA_Draw_Context *dc,
        dc->clip = c_bkp;
        return;
      }
-   rects = evas_common_draw_context_apply_cutouts(dc);
+   rects = evas_common_draw_context_apply_cutouts(dc, rects);
    for (i = 0; i < rects->active; ++i)
      {
        r = rects->rects + i;
        evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
         _soft16_rectangle_draw_int(dst, dc, dr);
      }
-   evas_common_draw_context_apply_clear_cutouts(rects);
    dc->clip = c_bkp;
 }
 
index cc4ce25..02282b8 100644 (file)
@@ -523,8 +523,8 @@ evas_common_soft8_image_draw(Soft8_Image * src, Soft8_Image * dst,
                  int dst_region_w, int dst_region_h,
                  int smooth __UNUSED__)
 {
+   static Cutout_Rects *rects = NULL;
    Eina_Rectangle sr, dr;
-   Cutout_Rects *rects;
    Cutout_Rect *r;
    struct RGBA_Draw_Context_clip clip_bkp;
    int i;
@@ -569,14 +569,13 @@ evas_common_soft8_image_draw(Soft8_Image * src, Soft8_Image * dst,
         dc->clip = clip_bkp;
         return;
      }
-   rects = evas_common_draw_context_apply_cutouts(dc);
+   rects = evas_common_draw_context_apply_cutouts(dc, rects);
    for (i = 0; i < rects->active; i++)
      {
         r = rects->rects + i;
         evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
         _soft8_image_draw_sampled_int(src, dst, dc, sr, dr);
      }
-   evas_common_draw_context_apply_clear_cutouts(rects);
    dc->clip = clip_bkp;
 }
 
index 150f262..98a053b 100644 (file)
@@ -79,8 +79,8 @@ void
 evas_common_soft8_rectangle_draw(Soft8_Image * dst, RGBA_Draw_Context * dc,
                      int x, int y, int w, int h)
 {
+   static Cutout_Rects *rects = NULL;
    Eina_Rectangle dr;
-   Cutout_Rects *rects;
    Cutout_Rect *r;
    struct RGBA_Draw_Context_clip c_bkp;
    int i;
@@ -113,13 +113,12 @@ evas_common_soft8_rectangle_draw(Soft8_Image * dst, RGBA_Draw_Context * dc,
         dc->clip = c_bkp;
         return;
      }
-   rects = evas_common_draw_context_apply_cutouts(dc);
+   rects = evas_common_draw_context_apply_cutouts(dc, rects);
    for (i = 0; i < rects->active; ++i)
      {
         r = rects->rects + i;
         evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
         _soft8_rectangle_draw_int(dst, dc, dr);
      }
-   evas_common_draw_context_apply_clear_cutouts(rects);
    dc->clip = c_bkp;
 }
index c9a9511..eba2039 100644 (file)
@@ -728,8 +728,10 @@ struct _RGBA_Draw_Context
 struct _RGBA_Pipe_Op
 {
    RGBA_Draw_Context         context;
+   Eina_Bool               (*prepare_func) (void *data, RGBA_Image *dst, RGBA_Pipe_Op *op);
    void                    (*op_func) (RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA_Pipe_Thread_Info *info);
    void                    (*free_func) (RGBA_Pipe_Op *op);
+   Cutout_Rects             *rects;
 
    union {
       struct {
@@ -739,11 +741,13 @@ struct _RGBA_Pipe_Op
         int                 x0, y0, x1, y1;
       } line;
       struct {
+         int                 x, y;
         RGBA_Polygon_Point *points;
       } poly;
       struct {
         int                 x, y;
          Evas_Text_Props    *intl_props;
+         RGBA_Gfx_Func       func;
       } text;
       struct {
         RGBA_Image         *src;
@@ -753,12 +757,14 @@ struct _RGBA_Pipe_Op
       } image;
       struct {
         RGBA_Image         *src;
-        RGBA_Map_Point     *p;
+        RGBA_Map           *m;
         int                 npoints;
         int                 smooth;
         int                 level;
       } map;
    } op;
+
+   Eina_Bool                 render : 1;
 };
 
 #define PIPE_LEN 256
@@ -773,8 +779,7 @@ struct _RGBA_Pipe
 struct _RGBA_Pipe_Thread_Info
 {
    EINA_INLIST;
-   RGBA_Image *im;
-   int         x, y, w, h;
+   Eina_Rectangle area;
 };
 #endif
 
index d21ab0a..86dab87 100644 (file)
@@ -834,9 +834,10 @@ struct _Evas_Func
    int  (*image_scale_hint_get)            (void *data, void *image);
    int  (*font_last_up_to_pos)             (void *data, Evas_Font_Set *font, const Evas_Text_Props *intl_props, int x, int y);
 
-   void (*image_map_draw)                  (void *data, void *context, void *surface, void *image, int npoints, RGBA_Map_Point *p, int smooth, int level);
+   void (*image_map_draw)                  (void *data, void *context, void *surface, void *image, RGBA_Map *m, int smooth, int level);
    void *(*image_map_surface_new)          (void *data, int w, int h, int alpha);
    void (*image_map_surface_free)          (void *data, void *surface);
+   void (*image_map_clean)                 (void *data, RGBA_Map *m);
 
    void (*image_content_hint_set)          (void *data, void *surface, int hint);
    int  (*image_content_hint_get)          (void *data, void *surface);
index b107982..41386b2 100644 (file)
@@ -404,10 +404,10 @@ typedef void (*_cb_for_each_cutout_t)(IDirectFBSurface *surface, RGBA_Draw_Conte
 static void
 _dfb_surface_for_each_cutout(IDirectFBSurface *surface, RGBA_Draw_Context *dc, _cb_for_each_cutout_t cb, void *data)
 {
-   Cutout_Rects *rects;
+   static Cutout_Rects *rects = NULL;
    int i;
 
-   rects = evas_common_draw_context_apply_cutouts(dc);
+   rects = evas_common_draw_context_apply_cutouts(dc, rects);
    if (!rects)
      {
        DFBRegion cr;
@@ -435,7 +435,6 @@ _dfb_surface_for_each_cutout(IDirectFBSurface *surface, RGBA_Draw_Context *dc, _
        surface->SetClip(surface, &cr);
        cb(surface, dc, &cr, data);
      }
-   evas_common_draw_context_apply_clear_cutouts(rects);
 }
 
 static void
index 2676062..78eddc6 100644 (file)
@@ -103,7 +103,7 @@ evas_gl_font_texture_draw(void *context, void *surface __UNUSED__, void *draw_co
    Evas_Engine_GL_Context *gc = context;
    RGBA_Draw_Context *dc = draw_context;
    Evas_GL_Texture *tex;
-   Cutout_Rects *rects;
+   static Cutout_Rects *rects = NULL;
    Cutout_Rect  *rct;
    int r, g, b, a;
    double ssx, ssy, ssw, ssh;
@@ -171,7 +171,7 @@ evas_gl_font_texture_draw(void *context, void *surface __UNUSED__, void *draw_co
         gc->dc->clip.use = c; gc->dc->clip.x = cx; gc->dc->clip.y = cy; gc->dc->clip.w = cw; gc->dc->clip.h = ch;
         return;
      }
-   rects = evas_common_draw_context_apply_cutouts(dc);
+   rects = evas_common_draw_context_apply_cutouts(dc, rects);
    for (i = 0; i < rects->active; ++i)
      {
         int nx, ny, nw, nh;
@@ -198,7 +198,6 @@ evas_gl_font_texture_draw(void *context, void *surface __UNUSED__, void *draw_co
                                          nx, ny, nw, nh,
                                          r, g, b, a);
      }
-   evas_common_draw_context_apply_clear_cutouts(rects);
    /* restore clip info */
    gc->dc->clip.use = c; gc->dc->clip.x = cx; gc->dc->clip.y = cy; gc->dc->clip.w = cw; gc->dc->clip.h = ch;
 }
index 39f16bb..79e33e7 100644 (file)
@@ -690,12 +690,12 @@ evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
 void
 evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, int smooth)
 {
+   static Cutout_Rects *rects = NULL;
    RGBA_Draw_Context *dc;
    Evas_GL_Image *imm;
    int r, g, b, a;
    double ssx, ssy, ssw, ssh;
    double mssx, mssy, mssw, mssh;
-   Cutout_Rects *rects;
    Cutout_Rect  *rct;
    int c, cx, cy, cw, ch;
    int i;
@@ -888,7 +888,7 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
         gc->dc->clip.use = c; gc->dc->clip.x = cx; gc->dc->clip.y = cy; gc->dc->clip.w = cw; gc->dc->clip.h = ch;
         return;
      }
-   rects = evas_common_draw_context_apply_cutouts(dc);
+   rects = evas_common_draw_context_apply_cutouts(dc, rects);
    for (i = 0; i < rects->active; ++i)
      {
         int nx, ny, nw, nh;
@@ -962,7 +962,6 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
                                             r, g, b, a,
                                             smooth, im->tex_only);
      }
-   evas_common_draw_context_apply_clear_cutouts(rects);
    /* restore clip info */
    gc->dc->clip.use = c; gc->dc->clip.x = cx; gc->dc->clip.y = cy; gc->dc->clip.w = cw; gc->dc->clip.h = ch;
 }
index bc111bd..81f041e 100644 (file)
@@ -122,7 +122,7 @@ polygon_edge_sorter(const void *a, const void *b)
 void
 evas_gl_common_poly_draw(Evas_Engine_GL_Context *gc, Evas_GL_Polygon *poly, int dx, int dy)
 {
-   Cutout_Rects *rects;
+   static Cutout_Rects *rects = NULL;
    Cutout_Rect  *r;
    int c, cx, cy, cw, ch, cr, cg, cb, ca, i;
    int x = 0, y = 0, w = 0, h = 0;
@@ -272,7 +272,7 @@ evas_gl_common_poly_draw(Evas_Engine_GL_Context *gc, Evas_GL_Polygon *poly, int
              /* our clip is 0 size.. abort */
              if ((gc->dc->clip.w > 0) && (gc->dc->clip.h > 0))
                {
-                  rects = evas_common_draw_context_apply_cutouts(gc->dc);
+                rects = evas_common_draw_context_apply_cutouts(gc->dc, rects);
                   for (i = 0; i < rects->active; ++i)
                     {
                        r = rects->rects + i;
@@ -290,7 +290,6 @@ evas_gl_common_poly_draw(Evas_Engine_GL_Context *gc, Evas_GL_Polygon *poly, int
                               }
                          }
                     }
-                  evas_common_draw_context_apply_clear_cutouts(rects);
                }
           }
         while (spans)
index 6254d87..d95b5a2 100644 (file)
@@ -3,7 +3,7 @@
 void
 evas_gl_common_rect_draw(Evas_Engine_GL_Context *gc, int x, int y, int w, int h)
 {
-   Cutout_Rects *rects;
+   static Cutout_Rects *rects = NULL;
    Cutout_Rect  *r;
    int          c, cx, cy, cw, ch, cr, cg, cb, ca, i;
 
@@ -37,7 +37,7 @@ evas_gl_common_rect_draw(Evas_Engine_GL_Context *gc, int x, int y, int w, int h)
         /* our clip is 0 size.. abort */
         if ((gc->dc->clip.w > 0) && (gc->dc->clip.h > 0))
           {
-             rects = evas_common_draw_context_apply_cutouts(gc->dc);
+             rects = evas_common_draw_context_apply_cutouts(gc->dc, rects);
              for (i = 0; i < rects->active; ++i)
                {
                   r = rects->rects + i;
@@ -46,7 +46,6 @@ evas_gl_common_rect_draw(Evas_Engine_GL_Context *gc, int x, int y, int w, int h)
                        evas_gl_common_context_rectangle_push(gc, r->x, r->y, r->w, r->h, cr, cg, cb, ca);
                     }
                }
-             evas_common_draw_context_apply_clear_cutouts(rects);
           }
      }
    /* restore clip info */
index 9fa5dcb..f0494e2 100644 (file)
@@ -2747,7 +2747,7 @@ eng_image_scale_hint_get(void *data __UNUSED__, void *image)
 }
 
 static void
-eng_image_map_draw(void *data, void *context, void *surface, void *image, int npoints, RGBA_Map_Point *p, int smooth, int level)
+eng_image_map_draw(void *data, void *context, void *surface, void *image, RGBA_Map *m, int smooth, int level)
 {
    Evas_GL_Image *gim = image;
    Render_Engine *re;
@@ -2757,46 +2757,51 @@ eng_image_map_draw(void *data, void *context, void *surface, void *image, int np
    eng_window_use(re->win);
    evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
    re->win->gl_context->dc = context;
-   if (npoints != 4)
+   if (m->count != 4)
      {
         // FIXME: nash - you didn't fix this
         abort();
      }
-   if ((p[0].x == p[3].x) &&
-       (p[1].x == p[2].x) &&
-       (p[0].y == p[1].y) &&
-       (p[3].y == p[2].y) &&
-       (p[0].x <= p[1].x) &&
-       (p[0].y <= p[2].y) &&
-       (p[0].u == 0) &&
-       (p[0].v == 0) &&
-       (p[1].u == (gim->w << FP)) &&
-       (p[1].v == 0) &&
-       (p[2].u == (gim->w << FP)) &&
-       (p[2].v == (gim->h << FP)) &&
-       (p[3].u == 0) &&
-       (p[3].v == (gim->h << FP)) &&
-       (p[0].col == 0xffffffff) &&
-       (p[1].col == 0xffffffff) &&
-       (p[2].col == 0xffffffff) &&
-       (p[3].col == 0xffffffff))
+   if ((m->pts[0].x == m->pts[3].x) &&
+       (m->pts[1].x == m->pts[2].x) &&
+       (m->pts[0].y == m->pts[1].y) &&
+       (m->pts[3].y == m->pts[2].y) &&
+       (m->pts[0].x <= m->pts[1].x) &&
+       (m->pts[0].y <= m->pts[2].y) &&
+       (m->pts[0].u == 0) &&
+       (m->pts[0].v == 0) &&
+       (m->pts[1].u == (gim->w << FP)) &&
+       (m->pts[1].v == 0) &&
+       (m->pts[2].u == (gim->w << FP)) &&
+       (m->pts[2].v == (gim->h << FP)) &&
+       (m->pts[3].u == 0) &&
+       (m->pts[3].v == (gim->h << FP)) &&
+       (m->pts[0].col == 0xffffffff) &&
+       (m->pts[1].col == 0xffffffff) &&
+       (m->pts[2].col == 0xffffffff) &&
+       (m->pts[3].col == 0xffffffff))
      {
         int dx, dy, dw, dh;
 
-        dx = p[0].x >> FP;
-        dy = p[0].y >> FP;
-        dw = (p[2].x >> FP) - dx;
-        dh = (p[2].y >> FP) - dy;
+        dx = m->pts[0].x >> FP;
+        dy = m->pts[0].y >> FP;
+        dw = (m->pts[2].x >> FP) - dx;
+        dh = (m->pts[2].y >> FP) - dy;
         eng_image_draw(data, context, surface, image,
                        0, 0, gim->w, gim->h, dx, dy, dw, dh, smooth);
      }
    else
      {
-        evas_gl_common_image_map_draw(re->win->gl_context, image, npoints, p,
+        evas_gl_common_image_map_draw(re->win->gl_context, image, m->count, &m->pts[0],
                                       smooth, level);
      }
 }
 
+static void
+eng_image_map_clean(void *data, RGBA_Map *m)
+{
+}
+
 static void *
 eng_image_map_surface_new(void *data, int w, int h, int alpha)
 {
@@ -4955,6 +4960,7 @@ module_open(Evas_Module *em)
    ORD(image_map_draw);
    ORD(image_map_surface_new);
    ORD(image_map_surface_free);
+   ORD(image_map_clean);
 
    ORD(image_content_hint_set);
    ORD(image_content_hint_get);
index 43e4727..bfb061c 100644 (file)
@@ -939,41 +939,37 @@ image_loaded:
 }
 
 static void
-eng_image_map_draw(void *data __UNUSED__, void *context, void *surface, void *image, int npoints, RGBA_Map_Point *p, int smooth, int level)
-{
-   RGBA_Image *im;
-
-   if (!image) return;
-   if (npoints < 3) return;
-   im = image;
-
-   if ((p[0].x == p[3].x) &&
-       (p[1].x == p[2].x) &&
-       (p[0].y == p[1].y) &&
-       (p[3].y == p[2].y) &&
-       (p[0].x <= p[1].x) &&
-       (p[0].y <= p[2].y) &&
-       (p[0].u == 0) &&
-       (p[0].v == 0) &&
-       (p[1].u == (int)(im->cache_entry.w << FP)) &&
-       (p[1].v == 0) &&
-       (p[2].u == (int)(im->cache_entry.w << FP)) &&
-       (p[2].v == (int)(im->cache_entry.h << FP)) &&
-       (p[3].u == 0) &&
-       (p[3].v == (int)(im->cache_entry.h << FP)) &&
-       (p[0].col == 0xffffffff) &&
-       (p[1].col == 0xffffffff) &&
-       (p[2].col == 0xffffffff) &&
-       (p[3].col == 0xffffffff))
+evas_software_image_map_draw(void *data, void *context, RGBA_Image *surface, RGBA_Image *im, RGBA_Map *m, int smooth, int level, int offset)
+{
+   if (m->count - offset < 3) return;
+
+   if ((m->pts[0 + offset].x == m->pts[3 + offset].x) &&
+       (m->pts[1 + offset].x == m->pts[2 + offset].x) &&
+       (m->pts[0 + offset].y == m->pts[1 + offset].y) &&
+       (m->pts[3 + offset].y == m->pts[2 + offset].y) &&
+       (m->pts[0 + offset].x <= m->pts[1 + offset].x) &&
+       (m->pts[0 + offset].y <= m->pts[2 + offset].y) &&
+       (m->pts[0 + offset].u == 0) &&
+       (m->pts[0 + offset].v == 0) &&
+       (m->pts[1 + offset].u == (int)(im->cache_entry.w << FP)) &&
+       (m->pts[1 + offset].v == 0) &&
+       (m->pts[2 + offset].u == (int)(im->cache_entry.w << FP)) &&
+       (m->pts[2 + offset].v == (int)(im->cache_entry.h << FP)) &&
+       (m->pts[3 + offset].u == 0) &&
+       (m->pts[3 + offset].v == (int)(im->cache_entry.h << FP)) &&
+       (m->pts[0 + offset].col == 0xffffffff) &&
+       (m->pts[1 + offset].col == 0xffffffff) &&
+       (m->pts[2 + offset].col == 0xffffffff) &&
+       (m->pts[3 + offset].col == 0xffffffff))
      {
         int dx, dy, dw, dh;
 
-        dx = p[0].x >> FP;
-        dy = p[0].y >> FP;
-        dw = (p[2].x >> FP) - dx;
-        dh = (p[2].y >> FP) - dy;
+        dx = m->pts[0 + offset].x >> FP;
+        dy = m->pts[0 + offset].y >> FP;
+        dw = (m->pts[2 + offset].x >> FP) - dx;
+        dh = (m->pts[2 + offset].y >> FP) - dy;
         eng_image_draw
-          (data, context, surface, image,
+          (data, context, surface, im,
            0, 0, im->cache_entry.w, im->cache_entry.h,
            dx, dy, dw, dh, smooth);
      }
@@ -981,20 +977,39 @@ eng_image_map_draw(void *data __UNUSED__, void *context, void *surface, void *im
      {
 #ifdef BUILD_PIPE_RENDER
         if ((cpunum > 1))
-          evas_common_pipe_map_draw(im, surface, context, npoints, p, smooth, level);
+         {
+             evas_common_pipe_map_draw(im, surface, context, m, smooth, level);
+             return ;
+          }
         else
 #endif
-          evas_common_map_rgba(im, surface, context, npoints, p, smooth, level);
+          {
+             evas_common_map_rgba(im, surface, context, m->count - offset, &m->pts[offset], smooth, level);
+          }
      }
    evas_common_cpu_end_opt();
 
-   if (npoints > 4)
+   if (m->count > 4)
      {
-        eng_image_map_draw(data, context, surface, image, npoints - 2, p + 2,
-                           smooth, level);
+        evas_software_image_map_draw(data, context, surface, im, m, smooth, level, offset + 2);
      }
 }
 
+static void
+eng_image_map_draw(void *data, void *context, void *surface, void *image, RGBA_Map *m, int smooth, int level)
+{
+   if (!image) return;
+   if (m->count < 3) return;
+
+   evas_software_image_map_draw(data, context, surface, image, m, smooth, level, 0);
+}
+
+static void
+eng_image_map_clean(void *data __UNUSED__, RGBA_Map *m)
+{
+   evas_common_map_rgba_clean(m);
+}
+
 static void *
 eng_image_map_surface_new(void *data __UNUSED__, int w, int h, int alpha)
 {
@@ -1843,6 +1858,7 @@ static Evas_Func func =
      eng_image_map_draw,
      eng_image_map_surface_new,
      eng_image_map_surface_free,
+     eng_image_map_clean,
      NULL, // eng_image_content_hint_set - software doesn't use it
      NULL, // eng_image_content_hint_get - software doesn't use it
      eng_font_pen_coords_get,
@@ -2873,6 +2889,7 @@ module_open(Evas_Module *em)
      }
 
    init_gl();
+   evas_common_pipe_init();
 
    em->functions = (void *)(&func);
    cpunum = eina_cpu_count();
index ce60ea7..73a62bc 100644 (file)
@@ -111,7 +111,7 @@ struct _Outbuf
 
         /* 1 big buffer for updates - flush on idle_flush */
         RGBA_Image *onebuf;
-        Eina_List *onebuf_regions;
+        Eina_Array  onebuf_regions;
 
         /* a list of pending regions to write to the target */
         Eina_List *pending_writes;
index c788147..ab4e777 100644 (file)
@@ -181,6 +181,7 @@ evas_software_xlib_outbuf_free(Outbuf *buf)
    if (buf->priv.pal)
       evas_software_xlib_x_color_deallocate(buf->priv.x11.xlib.disp, buf->priv.x11.xlib.cmap,
                                           buf->priv.x11.xlib.vis, buf->priv.pal);
+   eina_array_flush(&buf->priv.onebuf_regions);
    free(buf);
    _clear_xob(0);
 }
@@ -211,6 +212,8 @@ evas_software_xlib_outbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth,
    buf->priv.mask_dither = shape_dither;
    buf->priv.destination_alpha = destination_alpha;
 
+   eina_array_step_set(&buf->priv.onebuf_regions, sizeof (Eina_Array), 8);
+
    {
       Gfx_Func_Convert    conv_func;
       X_Output_Buffer    *xob;
@@ -379,8 +382,7 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
              return NULL;
           }
 
-       buf->priv.onebuf_regions = eina_list_append(buf->priv.onebuf_regions, rect);
-       if (buf->priv.onebuf)
+        if (!eina_array_push(&buf->priv.onebuf_regions, rect))
          {
             *cx = x;
             *cy = y;
@@ -708,20 +710,20 @@ evas_software_xlib_outbuf_flush(Outbuf *buf)
    RGBA_Image *im;
    Outbuf_Region *obr;
 
-   if ((buf->priv.onebuf) && (buf->priv.onebuf_regions))
+   if ((buf->priv.onebuf) && eina_array_count(&buf->priv.onebuf_regions))
      {
+        Eina_Rectangle *rect;
+        Eina_Array_Iterator it;
+        unsigned int i;
        Region tmpr;
 
        im = buf->priv.onebuf;
        obr = im->extended_info;
        tmpr = XCreateRegion();
-       while (buf->priv.onebuf_regions)
+        EINA_ARRAY_ITER_NEXT(&buf->priv.onebuf_regions, i, rect, it)
          {
-            Eina_Rectangle *rect;
             XRectangle xr;
 
-            rect = buf->priv.onebuf_regions->data;
-            buf->priv.onebuf_regions = eina_list_remove_list(buf->priv.onebuf_regions, buf->priv.onebuf_regions);
              if (buf->rot == 0)
                {
                   xr.x = rect->x;
@@ -756,6 +758,7 @@ evas_software_xlib_outbuf_flush(Outbuf *buf)
                                                      xr.x, xr.y, xr.width, xr.height);
             eina_rectangle_free(rect);
          }
+        eina_array_clean(&buf->priv.onebuf_regions);
        XSetRegion(buf->priv.x11.xlib.disp, buf->priv.x11.xlib.gc, tmpr);
         if (obr->xob)
            evas_software_xlib_x_output_buffer_paste(obr->xob, buf->priv.x11.xlib.win,
@@ -1025,7 +1028,7 @@ evas_software_xlib_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, i
 #if 1
 #else
    /* XX async push */
-   if (!((buf->priv.onebuf) && (buf->priv.onebuf_regions)))
+   if (!((buf->priv.onebuf) && eina_array_count(&buf->priv.onebuf_regions)))
      {
        if (buf->priv.debug)
          evas_software_xlib_outbuf_debug_show(buf, buf->priv.x11.xlib.win,
@@ -1076,7 +1079,7 @@ evas_software_xlib_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, i
 #if 1
 #else
        /* XX async push */
-       if (!((buf->priv.onebuf) && (buf->priv.onebuf_regions)))
+       if (!((buf->priv.onebuf) && eina_array_count(&buf->priv.onebuf_regions)))
          evas_software_xlib_x_output_buffer_paste(obr->mxob,
                                                  buf->priv.x11.xlib.mask,
                                                  buf->priv.x11.xlib.gcm,