efl: move Evas_Object map data to there own Eina_Cow pointer.
authorCedric BAIL <cedric.bail@free.fr>
Tue, 22 Jan 2013 03:56:00 +0000 (03:56 +0000)
committerCedric BAIL <cedric.bail@free.fr>
Tue, 22 Jan 2013 03:56:00 +0000 (03:56 +0000)
NOTE: Overall speedup of 7%. No benchmark on memory consumption yet
as they are still running ask me directly to get the number later
today.

SVN revision: 83052

src/lib/evas/canvas/evas_clip.c
src/lib/evas/canvas/evas_events.c
src/lib/evas/canvas/evas_main.c
src/lib/evas/canvas/evas_map.c
src/lib/evas/canvas/evas_object_image.c
src/lib/evas/canvas/evas_object_main.c
src/lib/evas/canvas/evas_object_rectangle.c
src/lib/evas/canvas/evas_render.c
src/lib/evas/include/evas_inline.x
src/lib/evas/include/evas_private.h

index cee2178..69c5321 100644 (file)
@@ -88,9 +88,12 @@ static void
 evas_object_child_map_across_mark(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, Evas_Object *map_obj, Eina_Bool force)
 {
 #ifdef MAP_ACROSS
-   if ((obj->map.cur.map_parent != map_obj) || force)
+   if ((obj->map->cur.map_parent != map_obj) || force)
      {
-        obj->map.cur.map_parent = map_obj;
+        EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
+          map_write->cur.map_parent = map_obj;
+        EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
+
         obj->cur.cache.clip.dirty = 1;
         evas_object_clip_recalc(eo_obj, obj);
         if (obj->is_smart)
@@ -100,7 +103,7 @@ evas_object_child_map_across_mark(Evas_Object *eo_obj, Evas_Object_Protected_Dat
              EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(eo_obj), obj2)
                {
                   // if obj has its own map - skip it. already done
-                  if ((obj2->map.cur.map) && (obj2->map.cur.usemap)) continue;
+                  if ((obj2->map->cur.map) && (obj2->map->cur.usemap)) continue;
                   Evas_Object *eo_obj2 = obj2->object;
                   evas_object_child_map_across_mark(eo_obj2, obj2, map_obj, force);
                }
@@ -125,8 +128,8 @@ evas_object_clip_across_check(Evas_Object *eo_obj, Evas_Object_Protected_Data *o
 {
 #ifdef MAP_ACROSS
    if (!obj->cur.clipper) return;
-   if (obj->cur.clipper->map.cur.map_parent != obj->map.cur.map_parent)
-      evas_object_child_map_across_mark(eo_obj, obj, obj->map.cur.map_parent, 1);
+   if (obj->cur.clipper->map->cur.map_parent != obj->map->cur.map_parent)
+      evas_object_child_map_across_mark(eo_obj, obj, obj->map->cur.map_parent, 1);
 #endif
 }
 
@@ -139,9 +142,9 @@ evas_object_clip_across_clippees_check(Evas_Object *eo_obj, Evas_Object_Protecte
 
    if (!obj->clip.clipees) return;
 // schloooooooooooow:
-//   evas_object_child_map_across_mark(eo_obj, obj->map.cur.map_parent, 1);
+//   evas_object_child_map_across_mark(eo_obj, obj->map->cur.map_parent, 1);
 // buggy:
-   evas_object_child_map_across_mark(eo_obj, obj, obj->map.cur.map_parent, 0);
+   evas_object_child_map_across_mark(eo_obj, obj, obj->map->cur.map_parent, 0);
    if (obj->cur.cache.clip.dirty)
      {
        EINA_LIST_FOREACH(obj->clip.clipees, l, eo_obj2)
@@ -161,7 +164,7 @@ void
 evas_object_mapped_clip_across_mark(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
 {
 #ifdef MAP_ACROSS
-   if ((obj->map.cur.map) && (obj->map.cur.usemap))
+   if ((obj->map->cur.map) && (obj->map->cur.usemap))
       evas_object_child_map_across_mark(eo_obj, obj, eo_obj, 0);
    else
      {
@@ -170,7 +173,7 @@ evas_object_mapped_clip_across_mark(Evas_Object *eo_obj, Evas_Object_Protected_D
              Evas_Object_Protected_Data *smart_parent_obj =
                 eo_data_get(obj->smart.parent, EVAS_OBJ_CLASS);
              evas_object_child_map_across_mark
-                (eo_obj, obj, smart_parent_obj->map.cur.map_parent, 0);
+                (eo_obj, obj, smart_parent_obj->map->cur.map_parent, 0);
           }
         else
            evas_object_child_map_across_mark(eo_obj, obj, NULL, 0);
@@ -300,7 +303,7 @@ _clip_set(Eo *eo_obj, void *_pd, va_list *list)
    evas_object_clip_dirty(eo_obj, obj);
    evas_object_recalc_clippees(eo_obj, obj);
    if ((!obj->is_smart) &&
-       (!((obj->map.cur.map) && (obj->map.cur.usemap))))
+       (!((obj->map->cur.map) && (obj->map->cur.usemap))))
      {
         if (evas_object_is_in_output_rect(eo_obj, obj,
                                           obj->layer->evas->pointer.x,
@@ -375,7 +378,7 @@ _clip_unset(Eo *eo_obj, void *_pd, va_list *list EINA_UNUSED)
    evas_object_clip_dirty(eo_obj, obj);
    evas_object_recalc_clippees(eo_obj, obj);
    if ((!obj->is_smart) &&
-       (!((obj->map.cur.map) && (obj->map.cur.usemap))))
+       (!((obj->map->cur.map) && (obj->map->cur.usemap))))
      {
         if (evas_object_is_in_output_rect(eo_obj, obj,
                                           obj->layer->evas->pointer.x,
index a2a3954..0c905cc 100644 (file)
@@ -19,12 +19,12 @@ _evas_event_havemap_adjust(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Protecte
         _evas_event_havemap_adjust(obj->smart.parent, smart_parent_obj, x, y, mouse_grabbed);
      }
 
-   if ((!obj->map.cur.usemap) || (!obj->map.cur.map) || (!obj->map.cur.map->count == 4))
+   if ((!obj->map->cur.usemap) || (!obj->map->cur.map) || (!obj->map->cur.map->count == 4))
       return;
 
    //FIXME: Unless map_coords_get() supports grab mode and extrapolate coords
    //outside map, this should check the return value for outside case.
-   if (evas_map_coords_get(obj->map.cur.map, *x, *y, x, y, mouse_grabbed))
+   if (evas_map_coords_get(obj->map->cur.map, *x, *y, x, y, mouse_grabbed))
      {
         *x += obj->cur.geometry.x;
         *y += obj->cur.geometry.y;
@@ -80,15 +80,15 @@ _evas_event_object_list_raw_in_get(Evas *eo_e, Eina_List *in,
                {
                   int norep = 0;
 
-                  if ((obj->map.cur.usemap) && (obj->map.cur.map) &&
-                      (obj->map.cur.map->count == 4))
+                  if ((obj->map->cur.usemap) && (obj->map->cur.map) &&
+                      (obj->map->cur.map->count == 4))
                     {
                        inside = evas_object_is_in_output_rect(eo_obj, obj, x, y, 1, 1);
                        if (inside)
                          {
-                            if (!evas_map_coords_get(obj->map.cur.map, x, y,
-                                                     &(obj->map.cur.map->mx),
-                                                     &(obj->map.cur.map->my), 0))
+                            if (!evas_map_coords_get(obj->map->cur.map, x, y,
+                                                     &(obj->map->cur.map->mx),
+                                                     &(obj->map->cur.map->my), 0))
                               {
                                  inside = 0;
                               }
@@ -98,8 +98,8 @@ _evas_event_object_list_raw_in_get(Evas *eo_e, Eina_List *in,
                                     (eo_e, in,
                                      evas_object_smart_members_get_direct(eo_obj),
                                      stop,
-                                     obj->cur.geometry.x + obj->map.cur.map->mx,
-                                     obj->cur.geometry.y + obj->map.cur.map->my,
+                                     obj->cur.geometry.x + obj->map->cur.map->mx,
+                                     obj->cur.geometry.y + obj->map->cur.map->my,
                                      &norep, source);
                               }
                          }
@@ -136,12 +136,12 @@ _evas_event_object_list_raw_in_get(Evas *eo_e, Eina_List *in,
 
                   if (inside)
                     {
-                       if ((obj->map.cur.usemap) && (obj->map.cur.map) &&
-                           (obj->map.cur.map->count == 4))
+                       if ((obj->map->cur.usemap) && (obj->map->cur.map) &&
+                           (obj->map->cur.map->count == 4))
                          {
-                            if (!evas_map_coords_get(obj->map.cur.map, x, y,
-                                                     &(obj->map.cur.map->mx),
-                                                     &(obj->map.cur.map->my), 0))
+                            if (!evas_map_coords_get(obj->map->cur.map, x, y,
+                                                     &(obj->map->cur.map->mx),
+                                                     &(obj->map->cur.map->my), 0))
                               {
                                  inside = 0;
                               }
index 3d961c4..ec38b80 100644 (file)
@@ -87,6 +87,7 @@ evas_shutdown(void)
      return _evas_init_count;
 
    eina_cow_del(evas_object_proxy_cow);
+   eina_cow_del(evas_object_map_cow);
    evas_object_proxy_cow = NULL;
 
    evas_thread_shutdown();
index 71a59ab..3f5b406 100644 (file)
@@ -39,28 +39,32 @@ _evas_map_calc_map_geometry(Evas_Object *eo_obj)
 
    Evas_Object_Protected_Data *obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS);
    if (!obj) return;
-   if (!obj->map.cur.map) return;
+   if (!obj->map->cur.map) return;
    // WARN: Do not merge below code to SLP until it is fixed.
    // It has an infinite loop bug.
-   if (obj->map.prev.map)
+   if (obj->map->prev.map)
      {
-        if (obj->map.prev.map != obj->map.cur.map)
+        if (obj->map->prev.map != obj->map->cur.map)
           {
              // FIXME: this causes an infinite loop somewhere... hard to debug
-             if (obj->map.prev.map->count == obj->map.cur.map->count)
+             if (obj->map->prev.map->count == obj->map->cur.map->count)
                {
                   const Evas_Map_Point *p2;
                   
-                  p = obj->map.cur.map->points;
-                  p2 = obj->map.prev.map->points;
+                  p = obj->map->cur.map->points;
+                  p2 = obj->map->prev.map->points;
                   if (memcmp(p, p2, sizeof(Evas_Map_Point) * 
-                             obj->map.prev.map->count) != 0)
+                             obj->map->prev.map->count) != 0)
                     ch = EINA_TRUE;
                   if (!ch)
                     {
-                       if (obj->map.cache_map) evas_map_free(obj->map.cache_map); 
-                       obj->map.cache_map = obj->map.cur.map;
-                       obj->map.cur.map = obj->map.prev.map;
+                       EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
+                         {
+                            if (map_write->cache_map) evas_map_free(map_write->cache_map); 
+                            map_write->cache_map = map_write->cur.map;
+                            map_write->cur.map = map_write->prev.map;
+                         }
+                       EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
                     }
                }
              else
@@ -70,8 +74,8 @@ _evas_map_calc_map_geometry(Evas_Object *eo_obj)
    else
       ch = EINA_TRUE;
    
-   p = obj->map.cur.map->points;
-   p_end = p + obj->map.cur.map->count;
+   p = obj->map->cur.map->points;
+   p_end = p + obj->map->cur.map->count;
    x1 = x2 = lround(p->x);
    yy1 = yy2 = lround(p->y);
    p++;
@@ -90,14 +94,14 @@ _evas_map_calc_map_geometry(Evas_Object *eo_obj)
 //   // add 1 pixel of fuzz around the map region to ensure updates are correct
 //   x1 -= 1; yy1 -= 1;
 //   x2 += 1; yy2 += 1;
-   if (obj->map.cur.map->normal_geometry.x != x1) ch = 1;
-   if (obj->map.cur.map->normal_geometry.y != yy1) ch = 1;
-   if (obj->map.cur.map->normal_geometry.w != (x2 - x1)) ch = 1;
-   if (obj->map.cur.map->normal_geometry.h != (yy2 - yy1)) ch = 1;
-   obj->map.cur.map->normal_geometry.x = x1;
-   obj->map.cur.map->normal_geometry.y = yy1;
-   obj->map.cur.map->normal_geometry.w = (x2 - x1);
-   obj->map.cur.map->normal_geometry.h = (yy2 - yy1);
+   if (obj->map->cur.map->normal_geometry.x != x1) ch = 1;
+   if (obj->map->cur.map->normal_geometry.y != yy1) ch = 1;
+   if (obj->map->cur.map->normal_geometry.w != (x2 - x1)) ch = 1;
+   if (obj->map->cur.map->normal_geometry.h != (yy2 - yy1)) ch = 1;
+   obj->map->cur.map->normal_geometry.x = x1;
+   obj->map->cur.map->normal_geometry.y = yy1;
+   obj->map->cur.map->normal_geometry.w = (x2 - x1);
+   obj->map->cur.map->normal_geometry.h = (yy2 - yy1);
    obj->changed_map = ch;
    // This shouldn't really be needed, but without it we do have case
    // where the clip is wrong when a map doesn't change, so always forcing
@@ -170,11 +174,15 @@ _evas_map_free(Evas_Object *eo_obj, Evas_Map *m)
    if (eo_obj)
      {
         Evas_Object_Protected_Data *obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS);
-        if ((obj) && (obj->map.spans))
+        if ((obj) && (obj->map->spans))
           {
-             obj->layer->evas->engine.func->image_map_clean(obj->layer->evas->engine.data.output, obj->map.spans);
-             free(obj->map.spans);
-             obj->map.spans = NULL;
+             obj->layer->evas->engine.func->image_map_clean(obj->layer->evas->engine.data.output, obj->map->spans);
+             EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
+               {
+                  free(map_write->spans);
+                  map_write->spans = NULL;
+               }
+             EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
           }      
      }
    m->magic = 0;
@@ -412,7 +420,7 @@ _evas_object_map_parent_check(Evas_Object *eo_parent)
    if (!parent) return EINA_FALSE;
    list = evas_object_smart_members_get_direct(parent->smart.parent);
    EINA_INLIST_FOREACH(list, o)
-     if (o->map.cur.usemap) break ;
+     if (o->map->cur.usemap) break ;
    if (o) return EINA_FALSE; /* Still some child have a map enable */
    parent->child_has_map = EINA_FALSE;
    _evas_object_map_parent_check(parent->smart.parent);
@@ -437,26 +445,38 @@ _map_enable_set(Eo *eo_obj, void *_pd, va_list *list)
    Eina_Bool pchange = EINA_FALSE;
 
    enabled = !!enabled;
-   if (obj->map.cur.usemap == enabled) return;
+   if (obj->map->cur.usemap == enabled) return;
    pchange = obj->changed;
-   obj->map.cur.usemap = enabled;
+
+   EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
+     map_write->cur.usemap = enabled;
+   EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
+
    if (enabled)
      {
-        if (!obj->map.cur.map)
-          obj->map.cur.map = _evas_map_new(4);
+        if (!obj->map->cur.map)
+          {
+             EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
+               map_write->cur.map = _evas_map_new(4);
+             EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
+          }
         evas_object_mapped_clip_across_mark(eo_obj, obj);
-//        obj->map.cur.map->normal_geometry = obj->cur.geometry;
+        //        obj->map->cur.map->normal_geometry = obj->cur.geometry;
      }
    else
      {
-        if (obj->map.surface)
+        if (obj->map->surface)
           {
-             obj->layer->evas->engine.func->image_map_surface_free
-               (obj->layer->evas->engine.data.output,
-                   obj->map.surface);
-             obj->map.surface = NULL;
+             EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
+               {
+                  obj->layer->evas->engine.func->image_map_surface_free
+                    (obj->layer->evas->engine.data.output,
+                     map_write->surface);
+                  map_write->surface = NULL;
+               }
+             EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
           }
-        if (obj->map.cur.map)
+        if (obj->map->cur.map)
           {
              _evas_map_calc_geom_change(eo_obj);
              evas_object_mapped_clip_across_mark(eo_obj, obj);
@@ -503,7 +523,7 @@ _map_enable_get(Eo *eo_obj EINA_UNUSED, void *_pd, va_list *list)
 {
    Eina_Bool *enabled = va_arg(*list, Eina_Bool *);
    const Evas_Object_Protected_Data *obj = _pd;
-   *enabled = obj->map.cur.usemap;
+   *enabled = obj->map->cur.usemap;
 }
 
 EAPI void
@@ -523,62 +543,80 @@ _map_set(Eo *eo_obj, void *_pd, va_list *list)
 
    if ((!map) || (map->count < 4))
      {
-        if (obj->map.surface)
+        if (obj->map->surface)
           {
-             obj->layer->evas->engine.func->image_map_surface_free
-               (obj->layer->evas->engine.data.output,
-                   obj->map.surface);
-             obj->map.surface = NULL;
+             EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
+               {
+                  obj->layer->evas->engine.func->image_map_surface_free
+                    (obj->layer->evas->engine.data.output,
+                     map_write->surface);
+                  map_write->surface = NULL;
+               }
+             EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
           }
-        if (obj->map.cur.map)
+        if (obj->map->cur.map)
           {
              obj->changed_map = EINA_TRUE;
-             obj->prev.geometry = obj->map.cur.map->normal_geometry;
+             obj->prev.geometry = obj->map->cur.map->normal_geometry;
 
-             if (obj->map.prev.map == obj->map.cur.map)
-               obj->map.cur.map = NULL;
-             else if (!obj->map.cache_map)
+             EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
                {
-                  obj->map.cache_map = obj->map.cur.map;
-                  obj->map.cur.map = NULL;
-               }
-             else
-               {
-                  _evas_map_free(eo_obj, obj->map.cur.map);
-                  obj->map.cur.map = NULL;
+                  if (map_write->prev.map == map_write->cur.map)
+                    map_write->cur.map = NULL;
+                  else if (!map_write->cache_map)
+                    {
+                       map_write->cache_map = map_write->cur.map;
+                       map_write->cur.map = NULL;
+                    }
+                  else
+                    {
+                       _evas_map_free(eo_obj, map_write->cur.map);
+                       map_write->cur.map = NULL;
+                    }
                }
+             EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
 
-             if (!obj->map.prev.map)
+             if (!obj->map->prev.map)
                {
                   evas_object_mapped_clip_across_mark(eo_obj, obj);
                   return;
                }
 
-             if (!obj->map.cur.usemap) _evas_map_calc_geom_change(eo_obj);
+             if (!obj->map->cur.usemap) _evas_map_calc_geom_change(eo_obj);
              else _evas_map_calc_map_geometry(eo_obj);
-             if (obj->map.cur.usemap)
+             if (obj->map->cur.usemap)
                evas_object_mapped_clip_across_mark(eo_obj, obj);
           }
         return;
      }
 
-   if (obj->map.prev.map == obj->map.cur.map)
-     obj->map.cur.map = NULL;
+   if (obj->map->prev.map == obj->map->cur.map)
+     {
+        EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
+          map_write->cur.map = NULL;
+        EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
+     }
 
-   if (!obj->map.cur.map)
+   if (!obj->map->cur.map)
      {
-        obj->map.cur.map = obj->map.cache_map;
-        obj->map.cache_map = NULL;
+        EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
+          {
+             map_write->cur.map = map_write->cache_map;
+             map_write->cache_map = NULL;
+          }
+        EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
      }
 
    // We do have the same exact count of point in this map, so just copy it
-   if ((obj->map.cur.map) && (obj->map.cur.map->count == map->count))
-     _evas_map_copy(obj->map.cur.map, map);
+   if ((obj->map->cur.map) && (obj->map->cur.map->count == map->count))
+     _evas_map_copy(obj->map->cur.map, map);
    else
      {
-        if (obj->map.cur.map) _evas_map_free(eo_obj, obj->map.cur.map);
-        obj->map.cur.map = _evas_map_dup(map);
-        if (obj->map.cur.usemap)
+        if (obj->map->cur.map) _evas_map_free(eo_obj, obj->map->cur.map);
+        EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
+          map_write->cur.map = _evas_map_dup(map);
+        EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
+        if (obj->map->cur.usemap)
            evas_object_mapped_clip_across_mark(eo_obj, obj);
      }
 
@@ -602,7 +640,7 @@ _map_get(Eo *eo_obj EINA_UNUSED, void *_pd, va_list *list)
    const Evas_Map **map = va_arg(*list, const Evas_Map **);
    const Evas_Object_Protected_Data *obj = _pd;
 
-   *map = obj->map.cur.map;
+   *map = obj->map->cur.map;
 }
 
 EAPI Evas_Map *
@@ -1184,11 +1222,11 @@ evas_object_map_update(Evas_Object *eo_obj,
    RGBA_Map_Point *pts, *pt;
 
    if (!obj) return;
-   if (obj->map.spans)
+   if (obj->map->spans)
      {
-        if (obj->map.spans->x != x || obj->map.spans->y != y ||
-            obj->map.spans->image.w != imagew || obj->map.spans->image.h != imageh ||
-            obj->map.spans->uv.w != uvw || obj->map.spans->uv.h != uvh)
+        if (obj->map->spans->x != x || obj->map->spans->y != y ||
+            obj->map->spans->image.w != imagew || obj->map->spans->image.h != imageh ||
+            obj->map->spans->uv.w != uvw || obj->map->spans->uv.h != uvh)
           obj->changed_map = EINA_TRUE;
      }
    else
@@ -1198,40 +1236,52 @@ evas_object_map_update(Evas_Object *eo_obj,
 
    if (!obj->changed_map) return ;
 
-   if (obj->map.cur.map && obj->map.spans && obj->map.cur.map->count != obj->map.spans->count)
+   if (obj->map->cur.map && obj->map->spans && obj->map->cur.map->count != obj->map->spans->count)
      {
-        if (obj->map.spans)
+        EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
           {
-             // Destroy engine side spans
-             free(obj->map.spans);
+             if (map_write->spans)
+               {
+                  // Destroy engine side spans
+                  free(map_write->spans);
+               }
+             map_write->spans = NULL;
           }
-        obj->map.spans = NULL;
+        EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
      }
 
-   if (!obj->map.spans)
-     obj->map.spans = calloc(1, sizeof (RGBA_Map) +
-                         sizeof (RGBA_Map_Point) * (obj->map.cur.map->count - 1));
-
-   if (!obj->map.spans) return ;
-
-   obj->map.spans->count = obj->map.cur.map->count;
-   obj->map.spans->x = x;
-   obj->map.spans->y = y;
-   obj->map.spans->uv.w = uvw;
-   obj->map.spans->uv.h = uvh;
-   obj->map.spans->image.w = imagew;
-   obj->map.spans->image.h = imageh;
+   if (!obj->map->spans)
+     {
+        EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
+          map_write->spans = calloc(1, sizeof (RGBA_Map) +
+                                    sizeof (RGBA_Map_Point) * (map_write->cur.map->count - 1));
+        EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
+     }
 
-   pts = obj->map.spans->pts;
+   if (!obj->map->spans) return ;
 
-   p = obj->map.cur.map->points;
-   p_end = p + obj->map.cur.map->count;
-   pt = pts;
+   EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
+     {
+        map_write->spans->count = obj->map->cur.map->count;
+        map_write->spans->x = x;
+        map_write->spans->y = y;
+        map_write->spans->uv.w = uvw;
+        map_write->spans->uv.h = uvh;
+        map_write->spans->image.w = imagew;
+        map_write->spans->image.h = imageh;
+
+        pts = obj->map->spans->pts;
+
+        p = obj->map->cur.map->points;
+        p_end = p + obj->map->cur.map->count;
+        pt = pts;
+     }
+   EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
 
-   pts[0].px = obj->map.cur.map->persp.px << FP;
-   pts[0].py = obj->map.cur.map->persp.py << FP;
-   pts[0].foc = obj->map.cur.map->persp.foc << FP;
-   pts[0].z0 = obj->map.cur.map->persp.z0 << FP;
+   pts[0].px = obj->map->cur.map->persp.px << FP;
+   pts[0].py = obj->map->cur.map->persp.py << FP;
+   pts[0].foc = obj->map->cur.map->persp.foc << FP;
+   pts[0].z0 = obj->map->cur.map->persp.z0 << FP;
    // draw geom +x +y
    for (; p < p_end; p++, pt++)
      {
@@ -1251,9 +1301,9 @@ evas_object_map_update(Evas_Object *eo_obj,
         else if (pt->v > (imageh * FP1)) pt->v = (imageh * FP1);
         pt->col = ARGB_JOIN(p->a, p->r, p->g, p->b);
      }
-   if (obj->map.cur.map->count & 0x1)
+   if (obj->map->cur.map->count & 0x1)
      {
-        pts[obj->map.cur.map->count] = pts[obj->map.cur.map->count -1];
+        pts[obj->map->cur.map->count] = pts[obj->map->cur.map->count -1];
      }
 
    // Request engine to update it's point
index 4b50d64..529a718 100644 (file)
@@ -3351,7 +3351,7 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v
                        (obj->cur.color.g == 255) &&
                        (obj->cur.color.b == 255) &&
                        (obj->cur.color.a == 255) &&
-                       (!obj->map.cur.map) )
+                       (!obj->map->cur.map) )
                     {
                        if (obj->layer->evas->engine.func->gl_img_obj_set)
                          {
@@ -3369,13 +3369,13 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v
                }
              o->dirty_pixels = EINA_FALSE;
           }
-        if ((obj->map.cur.map) && (obj->map.cur.map->count > 3) && (obj->map.cur.usemap))
+        if ((obj->map->cur.map) && (obj->map->cur.map->count > 3) && (obj->map->cur.usemap))
           {
              evas_object_map_update(eo_obj, x, y, imagew, imageh, uvw, uvh);
 
              evas_draw_image_map_async_check(
-                 obj, output, context, surface, pixels, obj->map.spans,
-                 o->cur.smooth_scale | obj->map.cur.map->smooth, 0, do_async);
+                 obj, output, context, surface, pixels, obj->map->spans,
+                 o->cur.smooth_scale | obj->map->cur.map->smooth, 0, do_async);
           }
         else
           {
@@ -3798,7 +3798,7 @@ evas_object_image_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *ob
                  (o->cur.border.b == 0) &&
                  (o->cur.image.w > 0) &&
                  (o->cur.image.h > 0) &&
-                 (!((obj->map.cur.map) && (obj->map.cur.usemap))))
+                 (!((obj->map->cur.map) && (obj->map->cur.usemap))))
                {
                   Eina_Rectangle *rr;
 
@@ -3969,9 +3969,9 @@ evas_object_image_is_opaque(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
         obj->cur.opaque = 1;
      }
 
-   if ((obj->map.cur.map) && (obj->map.cur.usemap))
+   if ((obj->map->cur.map) && (obj->map->cur.usemap))
      {
-        Evas_Map *m = obj->map.cur.map;
+        Evas_Map *m = obj->map->cur.map;
 
         if ((m->points[0].a == 255) &&
             (m->points[1].a == 255) &&
@@ -4042,9 +4042,9 @@ evas_object_image_was_opaque(Evas_Object *eo_obj, Evas_Object_Protected_Data *ob
 
         obj->prev.opaque = 1;
      }
-   if (obj->map.prev.usemap)
+   if (obj->map->prev.usemap)
      {
-        Evas_Map *m = obj->map.prev.map;
+        Evas_Map *m = obj->map->prev.map;
 
         if ((m->points[0].a == 255) &&
             (m->points[1].a == 255) &&
@@ -4229,7 +4229,7 @@ evas_object_image_is_inside(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
           }
 
         /* TODO: not handling map, need to apply map to point */
-        if ((obj->map.cur.map) && (obj->map.cur.map->count > 3) && (obj->map.cur.usemap))
+        if ((obj->map->cur.map) && (obj->map->cur.map->count > 3) && (obj->map->cur.usemap))
           {
              evas_object_map_update(eo_obj, 0, 0, imagew, imageh, uvw, uvh);
 
@@ -4489,7 +4489,7 @@ evas_object_image_has_opaque_rect(Evas_Object *eo_obj, Evas_Object_Protected_Dat
 {
    Evas_Object_Image *o = eo_data_get(eo_obj, MY_CLASS);
 
-   if ((obj->map.cur.map) && (obj->map.cur.usemap)) return 0;
+   if ((obj->map->cur.map) && (obj->map->cur.usemap)) return 0;
    if (((o->cur.border.l | o->cur.border.r | o->cur.border.t | o->cur.border.b) != 0) &&
        (o->cur.border.fill == EVAS_BORDER_FILL_SOLID) &&
        (obj->cur.render_op == EVAS_RENDER_BLEND) &&
index fa105a5..2b780ce 100644 (file)
@@ -27,8 +27,33 @@ get_layer_objects(Evas_Layer *l)
 static const Evas_Object_Proxy_Data default_proxy = {
   NULL, NULL, 0, 0, NULL, 0, 0, 0, 0
 };
+static const Evas_Object_Map_Data default_map = {
+  { NULL, NULL, 0, 0 }, { NULL, NULL, 0, 0 }, NULL, 0, 0, NULL, NULL
+};
 
 Eina_Cow *evas_object_proxy_cow = NULL;
+Eina_Cow *evas_object_map_cow = NULL;
+
+static Eina_Bool
+_init_cow(void)
+{
+   static Eina_Bool inited_cow = EINA_FALSE;
+
+   if (inited_cow) return inited_cow;
+
+   evas_object_proxy_cow = eina_cow_add("Evas Object Proxy", sizeof (Evas_Object_Proxy_Data), 8, &default_proxy);
+   evas_object_map_cow = eina_cow_add("Evas Object Map", sizeof (Evas_Object_Map_Data), 8, &default_map);
+
+   if (!(evas_object_map_cow && evas_object_proxy_cow))
+     {
+        eina_cow_del(evas_object_proxy_cow);
+        eina_cow_del(evas_object_map_cow);
+        return EINA_FALSE;
+     }
+
+   inited_cow = EINA_TRUE;
+   return EINA_TRUE;
+}
 
 static void
 _constructor(Eo *eo_obj, void *_pd, va_list *list EINA_UNUSED)
@@ -40,15 +65,7 @@ _constructor(Eo *eo_obj, void *_pd, va_list *list EINA_UNUSED)
    eo_manual_free_set(eo_obj, EINA_TRUE);
 
    obj = _pd;
-   if (!obj)
-     {
-        eo_error_set(eo_obj);
-        return;
-     }
-
-   if (!evas_object_proxy_cow)
-     evas_object_proxy_cow = eina_cow_add("Evas Proxy", sizeof (Evas_Object_Proxy_Data), 8, &default_proxy);
-   if (!evas_object_proxy_cow)
+   if (!obj || !_init_cow())
      {
         eo_error_set(eo_obj);
         return;
@@ -59,6 +76,7 @@ _constructor(Eo *eo_obj, void *_pd, va_list *list EINA_UNUSED)
    obj->is_frame = EINA_FALSE;
    obj->object = eo_obj;
    obj->proxy = eina_cow_alloc(evas_object_proxy_cow);
+   obj->map = eina_cow_alloc(evas_object_map_cow);
 }
 
 void
@@ -79,21 +97,34 @@ evas_object_cur_prev(Evas_Object *eo_obj)
 {
    Evas_Object_Protected_Data *obj = eo_data_get(eo_obj, MY_CLASS);
    if (!obj) return;
-   if (!obj->map.prev.valid_map)
+   if (!obj->map->prev.valid_map && obj->map->prev.map)
      {
-        if (obj->map.prev.map != obj->map.cur.map)
-          evas_map_free(obj->map.prev.map);
-        if (obj->map.cache_map == obj->map.prev.map)
-          obj->map.cache_map = NULL;
-        obj->map.prev.map = NULL;
+        EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
+          {
+             if (map_write->prev.map != map_write->cur.map)
+               evas_map_free(map_write->prev.map);
+             if (map_write->cache_map == map_write->prev.map)
+               map_write->cache_map = NULL;
+             map_write->prev.map = NULL;
+          }
+        EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
      }
 
-   if (obj->map.cur.map != obj->map.prev.map)
+   if (obj->map->cur.map != obj->map->prev.map)
      {
-        if (obj->map.cache_map) evas_map_free(obj->map.cache_map);
-        obj->map.cache_map = obj->map.prev.map;
+        EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
+          {
+             if (map_write->cache_map) evas_map_free(map_write->cache_map);
+             map_write->cache_map = map_write->prev.map;
+          }
+        EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
+     }
+   if (memcmp(&obj->map->prev, &obj->map->cur, sizeof (obj->map->cur)))
+     {
+        EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
+          map_write->prev = map_write->cur;
+        EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
      }
-   obj->map.prev = obj->map.cur;
    obj->prev = obj->cur;
 }
 
@@ -108,17 +139,19 @@ evas_object_free(Evas_Object *eo_obj, int clean_layer)
 
    if (!strcmp(obj->type, "image")) evas_object_image_video_surface_set(eo_obj, NULL);
    evas_object_map_set(eo_obj, NULL);
-   if (obj->map.prev.map) evas_map_free(obj->map.prev.map);
-   if (obj->map.cache_map) evas_map_free(obj->map.cache_map);
-   if (obj->map.surface)
+   if (obj->map->prev.map) evas_map_free(obj->map->prev.map);
+   if (obj->map->cache_map) evas_map_free(obj->map->cache_map);
+   if (obj->map->surface)
      {
         if (obj->layer)
           {
              obj->layer->evas->engine.func->image_map_surface_free
                (obj->layer->evas->engine.data.output,
-                   obj->map.surface);
+                   obj->map->surface);
           }
-        obj->map.surface = NULL;
+        EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
+          map_write->surface = NULL;
+        EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
      }
    evas_object_grabs_cleanup(eo_obj, obj);
    evas_object_intercept_cleanup(eo_obj);
@@ -134,16 +167,21 @@ evas_object_free(Evas_Object *eo_obj, int clean_layer)
    evas_object_clip_changes_clean(eo_obj);
    evas_object_event_callback_all_del(eo_obj);
    evas_object_event_callback_cleanup(eo_obj);
-   if (obj->map.spans)
+   if (obj->map->spans)
      {
-        free(obj->map.spans);
-        obj->map.spans = NULL;
+        EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
+          {
+             free(map_write->spans);
+             map_write->spans = NULL;
+          }
+        EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
      }
    if (obj->size_hints)
      {
        EVAS_MEMPOOL_FREE(_mp_sh, obj->size_hints);
      }
    eina_cow_free(evas_object_proxy_cow, obj->proxy);
+   eina_cow_free(evas_object_map_cow, obj->map);
    eo_manual_free(eo_obj);
 }
 
@@ -419,7 +457,7 @@ evas_object_render_pre_effect_updates(Eina_Array *rects, Evas_Object *eo_obj, in
 int
 evas_object_was_in_output_rect(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj, int x, int y, int w, int h)
 {
-   if (obj->is_smart && !obj->map.prev.map && !obj->map.prev.usemap) return 0;
+   if (obj->is_smart && !obj->map->prev.map && !obj->map->prev.usemap) return 0;
    /* assumes coords have been recalced */
    if ((RECTS_INTERSECT(x, y, w, h,
                         obj->prev.cache.clip.x,
@@ -1488,7 +1526,7 @@ _hide(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
             (!evas_object_is_source_invisible(eo_obj, obj)))
           {
              if ((!obj->is_smart) ||
-                 ((obj->map.cur.map) && (obj->map.cur.map->count == 4) && (obj->map.cur.usemap)))
+                 ((obj->map->cur.map) && (obj->map->cur.map->count == 4) && (obj->map->cur.usemap)))
                {
                   if (!obj->mouse_grabbed)
                     {
index 1b5dfbf..41aaec6 100644 (file)
@@ -271,7 +271,7 @@ evas_object_rectangle_is_opaque(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Pro
 {
    /* this returns 1 if the internal object data implies that the object is */
    /* currently fully opaque over the entire rectangle it occupies */
-   if ((obj->map.cur.map) && (obj->map.cur.usemap)) return 0;
+   if ((obj->map->cur.map) && (obj->map->cur.usemap)) return 0;
    if (obj->cur.render_op == EVAS_RENDER_COPY)
        return 1;
    if (obj->cur.render_op != EVAS_RENDER_BLEND)
index be8201f..57409a6 100644 (file)
@@ -198,8 +198,8 @@ _evas_clip_changes_free(const void *container EINA_UNUSED, void *data, void *fda
 static Eina_Bool
 _evas_render_had_map(Evas_Object_Protected_Data *obj)
 {
-   return ((obj->map.prev.map) && (obj->map.prev.usemap));
-   //   return ((!obj->map.cur.map) && (obj->prev.usemap));
+   return ((obj->map->prev.map) && (obj->map->prev.usemap));
+   //   return ((!obj->map->cur.map) && (obj->prev.usemap));
 }
 
 static Eina_Bool
@@ -317,8 +317,8 @@ _evas_render_phase1_direct(Evas_Public_Data *e,
              RD("      pre-render-done smart:%p|%p  [%p, %i] | [%p, %i] has_map:%i had_map:%i\n",
                 obj->smart.smart,
                 evas_object_smart_members_get_direct(eo_obj),
-                obj->map.cur.map, obj->map.cur.usemap,
-                obj->map.prev.map, obj->prev.usemap,
+                obj->map->cur.map, obj->map->cur.usemap,
+                obj->map->prev.map, obj->prev.usemap,
                 _evas_render_has_map(eo_obj, obj),
                 _evas_render_had_map(obj));
              if ((obj->is_smart) &&
@@ -460,7 +460,7 @@ _evas_render_phase1_object_process(Evas_Public_Data *e, Evas_Object *eo_obj,
           {
              if (!map)
                {
-                  if ((obj->map.cur.map) && (obj->map.cur.usemap)) map = EINA_TRUE;
+                  if ((obj->map->cur.map) && (obj->map->cur.usemap)) map = EINA_TRUE;
                }
              if (map != hmap)
                {
@@ -978,7 +978,7 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
    obj->pre_render_done = EINA_TRUE;
    RD("          Hasmap: %p (%d) %p %d -> %d\n",obj->func->can_map,
       obj->func->can_map ? obj->func->can_map(eo_obj): -1,
-      obj->map.cur.map, obj->map.cur.usemap,
+      obj->map->cur.map, obj->map->cur.usemap,
       _evas_render_has_map(eo_obj, obj));
    if (_evas_render_has_map(eo_obj, obj))
      {
@@ -999,28 +999,37 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
           }
         evas_object_map_update(eo_obj, off_x, off_y, sw, sh, sw, sh);
 
-        if (obj->map.surface)
+        if (obj->map->surface)
           {
-             if ((obj->map.surface_w != sw) ||
-                 (obj->map.surface_h != sh))
+             if ((obj->map->surface_w != sw) ||
+                 (obj->map->surface_h != sh))
                {
                   RDI(level);
                   RD("        new surf: %ix%i\n", sw, sh);
-                  obj->layer->evas->engine.func->image_map_surface_free
-                     (e->engine.data.output, obj->map.surface);
-                  obj->map.surface = NULL;
+                 EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
+                   {
+                     obj->layer->evas->engine.func->image_map_surface_free
+                       (e->engine.data.output, map_write->surface);
+                     map_write->surface = NULL;
+                   }
+                 EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
                }
           }
-        if (!obj->map.surface)
+        if (!obj->map->surface)
           {
-             obj->map.surface_w = sw;
-             obj->map.surface_h = sh;
-
-             obj->map.surface =
-                obj->layer->evas->engine.func->image_map_surface_new
-                (e->engine.data.output, obj->map.surface_w,
-                 obj->map.surface_h,
-                 obj->map.cur.map->alpha);
+             EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
+               {
+                  map_write->surface_w = sw;
+                  map_write->surface_h = sh;
+
+                  map_write->surface =
+                    obj->layer->evas->engine.func->image_map_surface_new
+                    (e->engine.data.output, map_write->surface_w,
+                     map_write->surface_h,
+                     map_write->cur.map->alpha);
+               }
+             EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
+
              RDI(level);
              RD("        fisrt surf: %ix%i\n", sw, sh);
              changed = EINA_TRUE;
@@ -1055,11 +1064,15 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
 
         /* mark the old map as invalid, so later we don't reuse it as a
          * cache. */
-        if (changed && obj->map.prev.map)
-           obj->map.prev.valid_map = EINA_FALSE;
+        if (changed && obj->map->prev.map)
+          {
+             EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
+               map_write->prev.valid_map = EINA_FALSE;
+             EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
+          }
 
         // clear surface before re-render
-        if ((changed) && (obj->map.surface))
+        if ((changed) && (obj->map->surface))
           {
              int off_x2, off_y2;
 
@@ -1067,7 +1080,7 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
              RD("        children redraw\n");
              // FIXME: calculate "changes" within map surface and only clear
              // and re-render those
-             if (obj->map.cur.map->alpha)
+             if (obj->map->cur.map->alpha)
                {
                   ctx = e->engine.func->context_new(e->engine.data.output);
                   e->engine.func->context_color_set
@@ -1076,10 +1089,10 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
                      (e->engine.data.output, ctx, EVAS_RENDER_COPY);
                   e->engine.func->rectangle_draw(e->engine.data.output,
                                                  ctx,
-                                                 obj->map.surface,
+                                                 obj->map->surface,
                                                  0, 0,
-                                                 obj->map.surface_w,
-                                                 obj->map.surface_h,
+                                                 obj->map->surface_w,
+                                                 obj->map->surface_h,
                                                  EINA_FALSE);
                   e->engine.func->context_free(e->engine.data.output, ctx);
                }
@@ -1093,7 +1106,7 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
                        {
                           clean_them |= evas_render_mapped(e, obj2->object,
                                                            obj2, ctx,
-                                                           obj->map.surface,
+                                                           obj->map->surface,
                                                            off_x2, off_y2, 1,
                                                            ecx, ecy, ecw, ech,
                                                            proxy_render
@@ -1107,8 +1120,8 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
                {
                   int x = 0, y = 0, w = 0, h = 0;
 
-                  w = obj->map.surface_w;
-                  h = obj->map.surface_h;
+                  w = obj->map->surface_w;
+                  h = obj->map->surface_h;
                   RECTS_CLIP_TO_RECT(x, y, w, h,
                                      obj->cur.geometry.x + off_x2,
                                      obj->cur.geometry.y + off_y2,
@@ -1118,7 +1131,7 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
                   e->engine.func->context_clip_set(e->engine.data.output,
                                                    ctx, x, y, w, h);
                   obj->func->render(eo_obj, obj, e->engine.data.output, ctx,
-                                    obj->map.surface, off_x2, off_y2,
+                                    obj->map->surface, off_x2, off_y2,
                                     EINA_FALSE);
                }
              e->engine.func->context_free(e->engine.data.output, ctx);
@@ -1130,14 +1143,19 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
 
         if (rendered)
           {
-             obj->map.surface = e->engine.func->image_dirty_region
-                (e->engine.data.output, obj->map.surface,
-                 0, 0, obj->map.surface_w, obj->map.surface_h);
-             obj->map.cur.valid_map = EINA_TRUE;
+             EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
+               {
+                  map_write->surface = e->engine.func->image_dirty_region
+                    (e->engine.data.output, map_write->surface,
+                     0, 0, map_write->surface_w, map_write->surface_h);
+
+                  map_write->cur.valid_map = EINA_TRUE;
+               }
+             EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
           }
         e->engine.func->context_clip_unset(e->engine.data.output,
                                            context);
-        if (obj->map.surface)
+        if (obj->map->surface)
           {
              if (obj->cur.clipper)
                {
@@ -1154,9 +1172,14 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
                        Evas_Object *tobj;
 
                        obj->cur.cache.clip.dirty = EINA_TRUE;
-                       tobj = obj->map.cur.map_parent;
-                       obj->map.cur.map_parent = obj->cur.clipper->map.cur.map_parent;
-                       obj->map.cur.map_parent = tobj;
+
+                       EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
+                         {
+                            tobj = map_write->cur.map_parent;
+                            map_write->cur.map_parent = obj->cur.clipper->map->cur.map_parent;
+                            map_write->cur.map_parent = tobj;
+                         }
+                       EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
                     }
 
                   RECTS_CLIP_TO_RECT(x, y, w, h,
@@ -1180,14 +1203,14 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
                (e->engine.data.output, context);
              evas_draw_image_map_async_check
                (obj, e->engine.data.output, context, surface,
-                obj->map.surface, obj->map.spans,
-                obj->map.cur.map->smooth, 0, do_async);
+                obj->map->surface, obj->map->spans,
+                obj->map->cur.map->smooth, 0, do_async);
           }
         // FIXME: needs to cache these maps and
         // keep them only rendering updates
         //        obj->layer->evas->engine.func->image_map_surface_free
-        //          (e->engine.data.output, obj->map.surface);
-        //        obj->map.surface = NULL;
+        //          (e->engine.data.output, obj->map->surface);
+        //        obj->map->surface = NULL;
      }
    else
      {
@@ -1315,7 +1338,7 @@ _evas_render_cutout_add(Evas *eo_e, Evas_Object *eo_obj, int off_x, int off_y)
         coy = obj->cur.cache.clip.y;
         cow = obj->cur.cache.clip.w;
         coh = obj->cur.cache.clip.h;
-        if ((obj->map.cur.map) && (obj->map.cur.usemap))
+        if ((obj->map->cur.map) && (obj->map->cur.usemap))
           {
              Evas_Object *eo_oo;
              Evas_Object_Protected_Data *oo;
@@ -1324,9 +1347,9 @@ _evas_render_cutout_add(Evas *eo_e, Evas_Object *eo_obj, int off_x, int off_y)
              oo = eo_data_get(eo_oo, EVAS_OBJ_CLASS);
              while (oo->cur.clipper)
                {
-                  if ((oo->cur.clipper->map.cur.map_parent
-                       != oo->map.cur.map_parent) &&
-                      (!((oo->map.cur.map) && (oo->map.cur.usemap))))
+                  if ((oo->cur.clipper->map->cur.map_parent
+                       != oo->map->cur.map_parent) &&
+                      (!((oo->map->cur.map) && (oo->map->cur.usemap))))
                     break;
                   RECTS_CLIP_TO_RECT(cox, coy, cow, coh,
                                      oo->cur.geometry.x,
@@ -2171,11 +2194,13 @@ void
 _evas_render_dump_map_surfaces(Evas_Object *eo_obj)
 {
    Evas_Object_Protected_Data *obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS);
-   if ((obj->map.cur.map) && obj->map.surface)
+   if ((obj->map->cur.map) && obj->map->surface)
      {
         obj->layer->evas->engine.func->image_map_surface_free
-           (obj->layer->evas->engine.data.output, obj->map.surface);
-        obj->map.surface = NULL;
+           (obj->layer->evas->engine.data.output, obj->map->surface);
+        EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
+          map_write->surface = NULL;
+        EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
      }
 
    if (obj->is_smart)
index b7396b3..c291f1c 100644 (file)
@@ -5,8 +5,8 @@ static inline Eina_Bool
 _evas_render_has_map(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
 {
    return ((!((obj->func->can_map) && (obj->func->can_map(eo_obj)))) &&
-           ((obj->map.cur.map) && (obj->map.cur.usemap)));
-   //   return ((obj->map.cur.map) && (obj->map.cur.usemap));
+           ((obj->map->cur.map) && (obj->map->cur.usemap)));
+   //   return ((obj->map->cur.map) && (obj->map->cur.usemap));
 }
 
 static inline void
@@ -171,7 +171,7 @@ evas_object_is_active(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
         if (obj->is_smart)
           {
              int mapsmt = 0;
-             if (obj->map.cur.map && obj->map.cur.usemap) mapsmt = 1;
+             if (obj->map->cur.map && obj->map->cur.usemap) mapsmt = 1;
              if (!mapsmt) return 1;
              if (evas_object_is_in_output_rect(eo_obj, obj, 0, 0, obj->layer->evas->output.w,
                                                obj->layer->evas->output.h) ||
@@ -231,12 +231,12 @@ evas_object_clip_recalc(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
 
    evas_object_coords_recalc(eo_obj, obj);
 
-   if ((obj->map.cur.map) && (obj->map.cur.usemap))
+   if ((obj->map->cur.map) && (obj->map->cur.usemap))
      {
-        cx = obj->map.cur.map->normal_geometry.x;
-        cy = obj->map.cur.map->normal_geometry.y;
-        cw = obj->map.cur.map->normal_geometry.w;
-        ch = obj->map.cur.map->normal_geometry.h;
+        cx = obj->map->cur.map->normal_geometry.x;
+        cy = obj->map->cur.map->normal_geometry.y;
+        cw = obj->map->cur.map->normal_geometry.w;
+        ch = obj->map->cur.map->normal_geometry.h;
      }
    else
      {
@@ -262,7 +262,7 @@ evas_object_clip_recalc(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
         // I don't know why this test was here in the first place. As I have
         // no issue showing up due to this, I keep it and move color out of it.
         // breaks cliping of mapped images!!!
-        if (clipper->map.cur.map_parent == obj->map.cur.map_parent)
+        if (clipper->map->cur.map_parent == obj->map->cur.map_parent)
           {
              nx = clipper->cur.cache.clip.x;
              ny = clipper->cur.cache.clip.y;
index 3dcda99..e563042 100644 (file)
@@ -48,6 +48,7 @@ typedef struct _Evas_Smart_Interfaces_Array Evas_Smart_Interfaces_Array;
 typedef struct _Evas_Post_Callback          Evas_Post_Callback;
 typedef struct _Evas_Coord_Touch_Point      Evas_Coord_Touch_Point;
 typedef struct _Evas_Object_Proxy_Data      Evas_Object_Proxy_Data;
+typedef struct _Evas_Object_Map_Data        Evas_Object_Map_Data;
 
 enum _Evas_Font_Style
 {
@@ -511,6 +512,22 @@ struct _Evas_Object_Proxy_Data
    Eina_Bool                src_events: 1;
 };
 
+struct _Evas_Object_Map_Data
+{
+   struct { 
+      Evas_Map             *map;
+      Evas_Object          *map_parent;
+
+      Eina_Bool             usemap : 1;
+      Eina_Bool             valid_map : 1;
+   } cur, prev;
+   void                 *surface; // surface holding map if needed
+   int                   surface_w, surface_h; // current surface w & h alloc
+
+   Evas_Map             *cache_map;
+   RGBA_Map             *spans;
+};
+
 struct _Evas_Object_Protected_Data
 {
    EINA_INLIST;
@@ -549,21 +566,6 @@ struct _Evas_Object_Protected_Data
       Eina_Bool             opaque : 1;
    } cur, prev;
 
-   struct {
-      struct { 
-         Evas_Map             *map;
-         Evas_Object          *map_parent;
-        
-         Eina_Bool             usemap : 1;
-         Eina_Bool             valid_map : 1;
-      } cur, prev;
-      void                 *surface; // surface holding map if needed
-      int                   surface_w, surface_h; // current surface w & h alloc
-
-      Evas_Map             *cache_map;
-      RGBA_Map             *spans;
-   } map;
-
    char                       *name;
 
    Evas_Intercept_Func        *interceptors;
@@ -584,7 +586,9 @@ struct _Evas_Object_Protected_Data
       Evas_Object             *parent;
    } smart;
 
+   // Eina_Cow pointer be careful when writing to it
    const Evas_Object_Proxy_Data *proxy;
+   const Evas_Object_Map_Data *map;
 
    // Pointer to the Evas_Object itself
    Evas_Object                *object;
@@ -1250,6 +1254,7 @@ void _evas_device_ref(Evas_Device *dev);
 void _evas_device_unref(Evas_Device *dev);
        
 extern Eina_Cow *evas_object_proxy_cow;
+extern Eina_Cow *evas_object_map_cow;
 
 /****************************************************************************/
 /*****************************************/