evas: cache conversion from Evas_Map to RGBA_Map.
authorcedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 14 Jun 2012 09:58:16 +0000 (09:58 +0000)
committercedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 14 Jun 2012 09:58:16 +0000 (09:58 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@72119 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

ChangeLog
NEWS
src/lib/canvas/evas_map.c
src/lib/canvas/evas_object_image.c
src/lib/canvas/evas_render.c
src/lib/include/evas_common.h
src/lib/include/evas_inline.x
src/lib/include/evas_private.h

index 3949dec..cb1005e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
 
         * Fix crash in evas_object_image_add() when called prior to setting an engine
           for the given canvas.
+
+2012-06-14  Cedric Bail
+
+       * Cache convertion from Evas_Map to RGBA_Map.
diff --git a/NEWS b/NEWS
index 33eb364..3c3cdc9 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,7 @@ Improvements:
    * Reduce cost of propagating event by limiting the object we explore by using a bouncing box.
    * 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.
 
 Fixes:
    * Add missing files in the tarball.
index 0f2ccf7..2b0591b 100644 (file)
@@ -174,6 +174,13 @@ _evas_map_free(Evas_Object *obj, Evas_Map *m)
      }
    m->magic = 0;
    free(m);
+
+   if (obj->spans)
+     {
+        // FIXME: destroy engine side spans
+        free(obj->spans);
+        obj->spans = NULL;
+     }      
 }
 
 /****************************************************************************/
@@ -1021,3 +1028,84 @@ evas_map_util_clockwise_get(Evas_Map *m)
    if (count > 0) return EINA_TRUE;
    return EINA_FALSE;
 }
+
+void
+evas_object_map_update(Evas_Object *obj,
+                       int x, int y,
+                       int imagew, int imageh,
+                       int uvw, int uvh)
+{
+   const Evas_Map_Point *p, *p_end;
+   RGBA_Map_Point *pts, *pt;
+
+   if (obj->spans)
+     {
+        if (obj->spans->x != x || obj->spans->y != y ||
+            obj->spans->image.w != imagew || obj->spans->image.h != imageh ||
+            obj->spans->uv.w != uvw || obj->spans->uv.h != uvh)
+          obj->changed_map = EINA_TRUE;
+     }
+
+   if (!obj->changed_map) return ;
+
+   if (obj->cur.map && obj->spans && obj->cur.map->count != obj->spans->count)
+     {
+        if (obj->spans)
+          {
+             // Destroy engine side spans
+             free(obj->spans);
+          }
+        obj->spans = NULL;
+     }
+
+   if (!((obj->cur.map) && (obj->cur.map->count > 3) && (obj->cur.usemap)))
+     return ;
+
+   if (!obj->spans)
+     obj->spans = calloc(1, sizeof (RGBA_Map) +
+                         sizeof (RGBA_Map_Point) * (obj->cur.map->count - 1));
+
+   if (!obj->spans) return ;
+
+   obj->spans->count = obj->cur.map->count;
+   obj->spans->x = x;
+   obj->spans->y = y;
+   obj->spans->uv.w = uvw;
+   obj->spans->uv.h = uvh;
+   obj->spans->image.w = imagew;
+   obj->spans->image.h = imageh;
+
+   pts = obj->spans->pts;
+
+   p = obj->cur.map->points;
+   p_end = p + obj->cur.map->count;
+   pt = pts;
+             
+   pts[0].px = obj->cur.map->persp.px << FP;
+   pts[0].py = obj->cur.map->persp.py << FP;
+   pts[0].foc = obj->cur.map->persp.foc << FP;
+   pts[0].z0 = obj->cur.map->persp.z0 << FP;
+   // draw geom +x +y
+   for (; p < p_end; p++, pt++)
+     {
+        pt->x = (lround(p->x) + x) * FP1;
+        pt->y = (lround(p->y) + y) * FP1;
+        pt->z = (lround(p->z)    ) * FP1;
+        pt->fx = p->px;
+        pt->fy = p->py;
+        pt->fz = p->z;
+        pt->u = ((lround(p->u) * imagew) / uvw) * FP1;
+        pt->v = ((lround(p->v) * imageh) / uvh) * FP1;
+        if      (pt->u < 0) pt->u = 0;
+        else if (pt->u > (imagew * FP1)) pt->u = (imagew * FP1);
+        if      (pt->v < 0) pt->v = 0;
+        else if (pt->v > (imageh * FP1)) pt->v = (imageh * FP1);
+        pt->col = ARGB_JOIN(p->a, p->r, p->g, p->b);
+     }
+   if (obj->cur.map->count & 0x1)
+     {
+        pts[obj->cur.map->count] = pts[obj->cur.map->count -1];
+     }
+
+   // Request engine to update it's point
+}
index aa7efd8..1d974d8 100644 (file)
@@ -2933,38 +2933,10 @@ 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))
           {
-            const Evas_Map_Point *p, *p_end;
-             RGBA_Map_Point pts[obj->cur.map->count], *pt;
+             RGBA_Map_Point *pts;
 
-            p = obj->cur.map->points;
-            p_end = p + obj->cur.map->count;
-            pt = pts;
-             
-             pts[0].px = obj->cur.map->persp.px << FP;
-             pts[0].py = obj->cur.map->persp.py << FP;
-             pts[0].foc = obj->cur.map->persp.foc << FP;
-             pts[0].z0 = obj->cur.map->persp.z0 << FP;
-             // draw geom +x +y
-             for (; p < p_end; p++, pt++)
-               {
-                  pt->x = (lround(p->x) + x) * FP1;
-                  pt->y = (lround(p->y) + y) * FP1;
-                  pt->z = (lround(p->z)    ) * FP1;
-                  pt->fx = p->px;
-                  pt->fy = p->py;
-                  pt->fz = p->z;
-                  pt->u = ((lround(p->u) * imagew) / uvw) * FP1;
-                  pt->v = ((lround(p->v) * imageh) / uvh) * FP1;
-                  if      (pt->u < 0) pt->u = 0;
-                  else if (pt->u > (imagew * FP1)) pt->u = (imagew * FP1);
-                  if      (pt->v < 0) pt->v = 0;
-                  else if (pt->v > (imageh * FP1)) pt->v = (imageh * FP1);
-                  pt->col = ARGB_JOIN(p->a, p->r, p->g, p->b);
-              }
-            if (obj->cur.map->count & 0x1)
-              {
-                 pts[obj->cur.map->count] = pts[obj->cur.map->count -1];
-              }
+             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,
index 70fbffa..7957003 100644 (file)
@@ -92,14 +92,6 @@ evas_obscured_clear(Evas *e)
 }
 
 static Eina_Bool
-_evas_render_has_map(Evas_Object *obj)
-{
-   return ((!((obj->func->can_map) && (obj->func->can_map(obj)))) &&
-           ((obj->cur.map) && (obj->cur.usemap)));
-   //   return ((obj->cur.map) && (obj->cur.usemap));
-}
-
-static Eina_Bool
 _evas_render_had_map(Evas_Object *obj)
 {
    return ((obj->prev.map) && (obj->prev.usemap));
@@ -830,8 +822,7 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
       _evas_render_has_map(obj));
    if (_evas_render_has_map(obj))
      {
-        const Evas_Map_Point *p, *p_end;
-        RGBA_Map_Point pts[4], *pt;
+       RGBA_Map_Point *pts;
         int sw, sh;
         Eina_Bool changed = EINA_FALSE, rendered = EINA_FALSE;
 
@@ -848,36 +839,8 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
              return clean_them;
           }
 
-        pts[0].px = obj->cur.map->persp.px << FP;
-        pts[0].py = obj->cur.map->persp.py << FP;
-        pts[0].foc = obj->cur.map->persp.foc << FP;
-        pts[0].z0 = obj->cur.map->persp.z0 << FP;
-
-        p = obj->cur.map->points;
-        p_end = p + obj->cur.map->count;
-        pt = pts;
-        for (; p < p_end; p++, pt++)
-          {
-             pt->x = (lround(p->x) + off_x) * FP1;
-             pt->y = (lround(p->y) + off_y) * FP1;
-             pt->z = (lround(p->z)        ) * FP1;
-             pt->fx = p->px;
-             pt->fy = p->py;
-             pt->fz = p->z;
-             pt->u = lround(p->u) * FP1;
-             pt->v = lround(p->v) * FP1;
-             if      (pt->u < 0) pt->u = 0;
-             else if (pt->u > (sw * FP1)) pt->u = (sw * FP1);
-             if      (pt->v < 0) pt->v = 0;
-             else if (pt->v > (sh * FP1)) pt->v = (sh * FP1);
-             pt->col = ARGB_JOIN(p->a, p->r, p->g, p->b);
-          }
-        /* Copy last for software engine */
-        if (obj->cur.map->count & 0x1)
-          {
-             pts[obj->cur.map->count] = pts[obj->cur.map->count - 1];
-          }
-
+       evas_object_map_update(obj, off_x, off_y, sw, sh, sw, sh);
+       pts = obj->spans->pts;
 
         if (obj->cur.map->surface)
           {
@@ -1080,6 +1043,11 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
      }
    else
      {
+        if (0 && obj->cur.cached_surface)
+          fprintf(stderr, "We should cache '%s' [%i, %i, %i, %i]\n",
+                  evas_object_type_get(obj),
+                  obj->cur.bounding_box.x, obj->cur.bounding_box.x,
+                  obj->cur.bounding_box.w, obj->cur.bounding_box.h);
         if (mapped)
           {
              RDI(level);
index b60dde0..3ace2b6 100644 (file)
@@ -395,6 +395,7 @@ typedef struct _RGBA_Image_Span       RGBA_Image_Span;
 typedef struct _RGBA_Draw_Context     RGBA_Draw_Context;
 typedef struct _RGBA_Polygon_Point    RGBA_Polygon_Point;
 typedef struct _RGBA_Map_Point        RGBA_Map_Point;
+typedef struct _RGBA_Map              RGBA_Map;
 typedef struct _RGBA_Font             RGBA_Font;
 typedef struct _RGBA_Font_Int         RGBA_Font_Int;
 typedef struct _RGBA_Font_Source      RGBA_Font_Source;
@@ -852,6 +853,20 @@ struct _RGBA_Map_Point
    FPc px, py, z0, foc;
 };
 
+struct _RGBA_Map
+{
+   void *engine_data;
+
+   struct {
+      int w, h;
+   } image, uv;
+
+   int x, y;
+   int count;
+
+   RGBA_Map_Point pts[1];
+};
+
 #if 0 // filtering disabled
 struct _Filtered_Image
 {
index 43a41c4..535bb7a 100644 (file)
@@ -1,6 +1,14 @@
 #ifndef EVAS_INLINE_H
 #define EVAS_INLINE_H
 
+static inline Eina_Bool
+_evas_render_has_map(Evas_Object *obj)
+{
+   return ((!((obj->func->can_map) && (obj->func->can_map(obj)))) &&
+           ((obj->cur.map) && (obj->cur.usemap)));
+   //   return ((obj->cur.map) && (obj->cur.usemap));
+}
+
 static inline void
 _evas_object_event_new(void)
 {
index c45ea86..162bf87 100644 (file)
@@ -530,6 +530,8 @@ struct _Evas_Object
       Evas_Render_Op        render_op : 4;
 
       Eina_Bool             valid_bounding_box : 1;
+      Eina_Bool             cached_surface : 1;
+      Eina_Bool             parent_cached_surface : 1;
    } cur, prev;
 
    char                       *name;
@@ -571,6 +573,8 @@ struct _Evas_Object
 
    Evas_Size_Hints            *size_hints;
 
+   RGBA_Map                   *spans;
+
    int                         last_mouse_down_counter;
    int                         last_mouse_up_counter;
    int                         mouse_grabbed;
@@ -1051,6 +1055,7 @@ void evas_render_object_recalc(Evas_Object *obj);
 
 Eina_Bool evas_map_inside_get(const Evas_Map *m, Evas_Coord x, Evas_Coord y);
 Eina_Bool evas_map_coords_get(const Evas_Map *m, Evas_Coord x, Evas_Coord y, Evas_Coord *mx, Evas_Coord *my, int grab);
+void evas_object_map_update(Evas_Object *obj, int x, int y, int imagew, int imageh, int uvw, int uvh);
 
 Eina_List *evas_module_engine_list(void);