evas: use Eina_Cow a lot more and we are closer to the memory size of 1.7.
authorCedric BAIL <cedric.bail@samsung.com>
Tue, 12 Mar 2013 12:58:19 +0000 (21:58 +0900)
committerCedric BAIL <cedric.bail@samsung.com>
Wed, 13 Mar 2013 05:35:25 +0000 (14:35 +0900)
19 files changed:
src/lib/evas/canvas/evas_clip.c
src/lib/evas/canvas/evas_events.c
src/lib/evas/canvas/evas_layer.c
src/lib/evas/canvas/evas_map.c
src/lib/evas/canvas/evas_object_image.c
src/lib/evas/canvas/evas_object_line.c
src/lib/evas/canvas/evas_object_main.c
src/lib/evas/canvas/evas_object_polygon.c
src/lib/evas/canvas/evas_object_rectangle.c
src/lib/evas/canvas/evas_object_smart.c
src/lib/evas/canvas/evas_object_smart_clipped.c
src/lib/evas/canvas/evas_object_text.c
src/lib/evas/canvas/evas_object_textblock.c
src/lib/evas/canvas/evas_object_textgrid.c
src/lib/evas/canvas/evas_render.c
src/lib/evas/canvas/evas_stack.c
src/lib/evas/include/evas_inline.x
src/lib/evas/include/evas_private.h
src/modules/evas/engines/gl_common/evas_gl_api.c

index 69c5321..8b4eef1 100644 (file)
@@ -6,11 +6,16 @@ evas_object_clip_dirty(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Protected_Da
 {
    Eina_List *l;
    Evas_Object *data;
+   Evas_Object_Protected_Data *clipee = NULL;
 
-   if (obj->cur.cache.clip.dirty) return;
+   if (obj->cur->cache.clip.dirty) return;
+
+   EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+     {
+       state_write->cache.clip.dirty = EINA_TRUE;
+     }
+   EINA_COW_STATE_WRITE_END(obj, state_write, cur);
 
-   obj->cur.cache.clip.dirty = EINA_TRUE;
-   Evas_Object_Protected_Data *clipee = NULL;
    EINA_LIST_FOREACH(obj->clip.clipees, l, data)
      {
         clipee = eo_data_get(data, EVAS_OBJ_CLASS);
@@ -24,7 +29,7 @@ evas_object_recalc_clippees(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
    Eina_List *l;
    Evas_Object *data;
 
-   if (obj->cur.cache.clip.dirty)
+   if (obj->cur->cache.clip.dirty)
      {
         evas_object_clip_recalc(eo_obj, obj);
         EINA_LIST_FOREACH(obj->clip.clipees, l, data)
@@ -38,11 +43,11 @@ evas_object_recalc_clippees(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
 int
 evas_object_clippers_was_visible(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj)
 {
-   if (obj->prev.visible)
+   if (obj->prev->visible)
      {
-       if (obj->prev.clipper)
+       if (obj->prev->clipper)
           {
-             return evas_object_clippers_is_visible(obj->prev.eo_clipper, obj->prev.clipper);
+             return evas_object_clippers_is_visible(obj->prev->eo_clipper, obj->prev->clipper);
           }
        return 1;
      }
@@ -94,7 +99,12 @@ evas_object_child_map_across_mark(Evas_Object *eo_obj, Evas_Object_Protected_Dat
           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;
+       EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+         {
+           state_write->cache.clip.dirty = 1;
+         }
+       EINA_COW_STATE_WRITE_END(obj, state_write, cur);
+
         evas_object_clip_recalc(eo_obj, obj);
         if (obj->is_smart)
           {
@@ -127,8 +137,8 @@ void
 evas_object_clip_across_check(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
 {
 #ifdef MAP_ACROSS
-   if (!obj->cur.clipper) return;
-   if (obj->cur.clipper->map->cur.map_parent != obj->map->cur.map_parent)
+   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);
 #endif
 }
@@ -145,7 +155,7 @@ evas_object_clip_across_clippees_check(Evas_Object *eo_obj, Evas_Object_Protecte
 //   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);
-   if (obj->cur.cache.clip.dirty)
+   if (obj->cur->cache.clip.dirty)
      {
        EINA_LIST_FOREACH(obj->clip.clipees, l, eo_obj2)
           {
@@ -213,7 +223,7 @@ _clip_set(Eo *eo_obj, void *_pd, va_list *list)
    MAGIC_CHECK_END();
 
    clip = eo_data_get(eo_clip, EVAS_OBJ_CLASS);
-   if (obj->cur.eo_clipper == eo_clip) return;
+   if (obj->cur->eo_clipper == eo_clip) return;
    if (eo_obj == eo_clip)
      {
         CRIT("Setting clip %p on itself", eo_obj);
@@ -252,41 +262,61 @@ _clip_set(Eo *eo_obj, void *_pd, va_list *list)
      {
         eo_do(eo_obj, evas_obj_smart_clip_set(eo_clip));
      }
-   if (obj->cur.clipper)
+   if (obj->cur->clipper)
      {
        /* unclip */
-        obj->cur.clipper->clip.clipees = eina_list_remove(obj->cur.clipper->clip.clipees, eo_obj);
-        if (!obj->cur.clipper->clip.clipees)
+        obj->cur->clipper->clip.clipees = eina_list_remove(obj->cur->clipper->clip.clipees, eo_obj);
+        if (!obj->cur->clipper->clip.clipees)
           {
-             obj->cur.clipper->cur.have_clipees = 0;
-             if (obj->cur.clipper->cur.visible)
-               evas_damage_rectangle_add(obj->cur.clipper->layer->evas->evas,
-                                         obj->cur.clipper->cur.geometry.x,
-                                         obj->cur.clipper->cur.geometry.y,
-                                         obj->cur.clipper->cur.geometry.w,
-                                         obj->cur.clipper->cur.geometry.h);
+             EINA_COW_STATE_WRITE_BEGIN(obj->cur->clipper, state_write, cur)
+               {
+                  state_write->have_clipees = 0;
+               }
+             EINA_COW_STATE_WRITE_END(obj->cur->clipper, state_write, cur);
+
+             if (obj->cur->clipper->cur->visible)
+               evas_damage_rectangle_add(obj->cur->clipper->layer->evas->evas,
+                                         obj->cur->clipper->cur->geometry.x,
+                                         obj->cur->clipper->cur->geometry.y,
+                                         obj->cur->clipper->cur->geometry.w,
+                                         obj->cur->clipper->cur->geometry.h);
           }
-        evas_object_change(obj->cur.eo_clipper, obj->cur.clipper);
+        evas_object_change(obj->cur->eo_clipper, obj->cur->clipper);
         evas_object_change(eo_obj, obj);
-        obj->cur.clipper = NULL;
-       obj->cur.eo_clipper = NULL;     
+
+        EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+          {
+             state_write->clipper = NULL;
+             state_write->eo_clipper = NULL;
+          }
+        EINA_COW_STATE_WRITE_END(obj, state_write, cur);
      }
    /* clip me */
-   if ((!clip->clip.clipees) && (clip->cur.visible))
+   if ((!clip->clip.clipees) && (clip->cur->visible))
      {
         /* Basically it just went invisible */
         clip->changed = 1;
         clip->layer->evas->changed = 1;
         evas_damage_rectangle_add(clip->layer->evas->evas,
-                                  clip->cur.geometry.x, clip->cur.geometry.y,
-                                  clip->cur.geometry.w, clip->cur.geometry.h);
+                                  clip->cur->geometry.x, clip->cur->geometry.y,
+                                  clip->cur->geometry.w, clip->cur->geometry.h);
      }
-   obj->cur.eo_clipper = eo_clip;
-   obj->cur.clipper = clip;
+   EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+     {
+        state_write->eo_clipper = eo_clip;
+        state_write->clipper = clip;
+     }
+   EINA_COW_STATE_WRITE_END(obj, state_write, cur);
+
    clip->clip.clipees = eina_list_append(clip->clip.clipees, eo_obj);
    if (clip->clip.clipees)
      {
-        clip->cur.have_clipees = 1;
+        EINA_COW_STATE_WRITE_BEGIN(clip, state_write, cur)
+          {
+             state_write->have_clipees = 1;
+          }
+        EINA_COW_STATE_WRITE_END(clip, state_write, cur);
+
         if (clip->changed)
           evas_object_update_bounding_box(eo_clip, clip);
      }
@@ -333,7 +363,7 @@ _clip_get(Eo *eo_obj EINA_UNUSED, void *_pd, va_list *list)
 {
    Evas_Object **clip = va_arg(*list, Evas_Object **);
    const Evas_Object_Protected_Data *obj = _pd;
-   *clip = obj->cur.eo_clipper;
+   *clip = obj->cur->eo_clipper;
 }
 
 EAPI void
@@ -350,30 +380,40 @@ _clip_unset(Eo *eo_obj, void *_pd, va_list *list EINA_UNUSED)
 {
    Evas_Object_Protected_Data *obj = _pd;
 
-   if (!obj->cur.clipper) return;
+   if (!obj->cur->clipper) return;
    /* unclip */
    if (evas_object_intercept_call_clip_unset(eo_obj)) return;
    if (obj->is_smart)
      {
         eo_do(eo_obj, evas_obj_smart_clip_unset());
      }
-   if (obj->cur.clipper)
+   if (obj->cur->clipper)
      {
-        obj->cur.clipper->clip.clipees = eina_list_remove(obj->cur.clipper->clip.clipees, eo_obj);
-        if (!obj->cur.clipper->clip.clipees)
+        obj->cur->clipper->clip.clipees = eina_list_remove(obj->cur->clipper->clip.clipees, eo_obj);
+        if (!obj->cur->clipper->clip.clipees)
           {
-             obj->cur.clipper->cur.have_clipees = 0;
-             if (obj->cur.clipper->cur.visible)
-                evas_damage_rectangle_add(obj->cur.clipper->layer->evas->evas,
-                                         obj->cur.clipper->cur.geometry.x,
-                                         obj->cur.clipper->cur.geometry.y,
-                                         obj->cur.clipper->cur.geometry.w,
-                                         obj->cur.clipper->cur.geometry.h);
+             EINA_COW_STATE_WRITE_BEGIN(obj->cur->clipper, state_write, cur)
+               {
+                  state_write->have_clipees = 0;
+               }
+             EINA_COW_STATE_WRITE_END(obj->cur->clipper, state_write, cur);
+
+             if (obj->cur->clipper->cur->visible)
+                evas_damage_rectangle_add(obj->cur->clipper->layer->evas->evas,
+                                         obj->cur->clipper->cur->geometry.x,
+                                         obj->cur->clipper->cur->geometry.y,
+                                         obj->cur->clipper->cur->geometry.w,
+                                         obj->cur->clipper->cur->geometry.h);
           }
-       evas_object_change(obj->cur.eo_clipper, obj->cur.clipper);
+       evas_object_change(obj->cur->eo_clipper, obj->cur->clipper);
      }
-   obj->cur.clipper = NULL;
-   obj->cur.eo_clipper = NULL;
+   EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+     {
+        state_write->clipper = NULL;
+        state_write->eo_clipper = NULL;
+     }
+   EINA_COW_STATE_WRITE_END(obj, state_write, cur);
+
    evas_object_change(eo_obj, obj);
    evas_object_clip_dirty(eo_obj, obj);
    evas_object_recalc_clippees(eo_obj, obj);
index 3b6c0b6..e5cba7c 100644 (file)
@@ -26,8 +26,8 @@ _evas_event_havemap_adjust(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Protecte
    //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))
      {
-        *x += obj->cur.geometry.x;
-        *y += obj->cur.geometry.y;
+        *x += obj->cur->geometry.x;
+        *y += obj->cur->geometry.y;
      }
 }
 
@@ -73,7 +73,7 @@ _evas_event_object_list_raw_in_get(Evas *eo_e, Eina_List *in,
              if (evas_object_is_source_invisible(eo_obj, obj)) continue;
           }
         if ((obj->delete_me == 0) &&
-            ((source) || ((obj->cur.visible) && (!obj->clip.clipees) &&
+            ((source) || ((obj->cur->visible) && (!obj->clip.clipees) &&
              evas_object_clippers_is_visible(eo_obj, obj))))
           {
              if (obj->is_smart)
@@ -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);
                               }
                          }
@@ -109,14 +109,14 @@ _evas_event_object_list_raw_in_get(Evas *eo_e, Eina_List *in,
                        if (!obj->child_has_map)
                          evas_object_smart_bounding_box_update(eo_obj, obj);
                        if (obj->child_has_map ||
-                           (obj->cur.bounding_box.x <= x &&
-                            obj->cur.bounding_box.x + obj->cur.bounding_box.w >= x &&
-                            obj->cur.bounding_box.y <= y &&
-                            obj->cur.bounding_box.y + obj->cur.bounding_box.h >= y) ||
-                           (obj->cur.geometry.x <= x &&
-                            obj->cur.geometry.y + obj->cur.geometry.w >= x &&
-                            obj->cur.geometry.y <= y &&
-                            obj->cur.geometry.y + obj->cur.geometry.h >= y))
+                           (obj->cur->bounding_box.x <= x &&
+                            obj->cur->bounding_box.x + obj->cur->bounding_box.w >= x &&
+                            obj->cur->bounding_box.y <= y &&
+                            obj->cur->bounding_box.y + obj->cur->bounding_box.h >= y) ||
+                           (obj->cur->geometry.x <= x &&
+                            obj->cur->geometry.y + obj->cur->geometry.w >= x &&
+                            obj->cur->geometry.y <= y &&
+                            obj->cur->geometry.y + obj->cur->geometry.h >= y))
                          in = _evas_event_object_list_in_get
                             (eo_e, in, evas_object_smart_members_get_direct(eo_obj),
                             stop, x, y, &norep, source);
@@ -168,21 +168,21 @@ _evas_event_object_list_raw_in_get(Evas *eo_e, Eina_List *in,
 static void
 _transform_to_src_space(Evas_Object_Protected_Data *obj, Evas_Object_Protected_Data *src, Evas_Coord *x, Evas_Coord *y)
 {
-   Evas_Coord obj_w = obj->cur.geometry.w, obj_h = obj->cur.geometry.h;
-   Evas_Coord src_w = src->cur.geometry.w, src_h = src->cur.geometry.h;
+   Evas_Coord obj_w = obj->cur->geometry.w, obj_h = obj->cur->geometry.h;
+   Evas_Coord src_w = src->cur->geometry.w, src_h = src->cur->geometry.h;
    Evas_Coord tmp_x = *x;
    Evas_Coord tmp_y = *y;
 
-   tmp_x -= obj->cur.geometry.x;
-   tmp_y -= obj->cur.geometry.y;
+   tmp_x -= obj->cur->geometry.x;
+   tmp_y -= obj->cur->geometry.y;
 
    if (obj_w != src_w)
      tmp_x = (Evas_Coord) ((float)tmp_x * ((float)src_w / (float)obj_w));
    if (obj_h != src_h)
      tmp_y = (Evas_Coord) ((float)tmp_y * ((float)src_h / (float)obj_h));
 
-   tmp_x += src->cur.geometry.x;
-   tmp_y += src->cur.geometry.y;
+   tmp_x += src->cur->geometry.x;
+   tmp_y += src->cur->geometry.y;
    *x = tmp_x;
    *y = tmp_y;
 }
index ef13547..38a0c9e 100644 (file)
@@ -11,11 +11,11 @@ evas_object_inject(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *
    if (!obj) return;
    if (!e) return;
    if (obj->in_layer) return;
-   lay = evas_layer_find(e, obj->cur.layer);
+   lay = evas_layer_find(e, obj->cur->layer);
    if (!lay)
      {
         lay = evas_layer_new(e);
-        lay->layer = obj->cur.layer;
+        lay->layer = obj->cur->layer;
         evas_layer_add(lay);
      }
    lay->objects = (Evas_Object_Protected_Data *)eina_inlist_append(EINA_INLIST_GET(lay->objects), EINA_INLIST_GET(obj));
@@ -145,9 +145,14 @@ _evas_object_layer_set_child(Evas_Object *eo_obj, Evas_Object *par, short l)
    Evas_Object_Protected_Data *par_obj = eo_data_get(par, EVAS_OBJ_CLASS);
 
    if (obj->delete_me) return;
-   if (obj->cur.layer == l) return;
+   if (obj->cur->layer == l) return;
    evas_object_release(eo_obj, obj, 1);
-   obj->cur.layer = l;
+   EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+     {
+       state_write->layer = l;
+     }
+   EINA_COW_STATE_WRITE_END(obj, state_write, cur);
+
    obj->layer = par_obj->layer;
    obj->layer->usage++;
    if (obj->is_smart)
@@ -185,14 +190,19 @@ _layer_set(Eo *eo_obj, void *_obj, va_list *list)
    if (obj->delete_me) return;
    if (evas_object_intercept_call_layer_set(eo_obj, l)) return;
    if (obj->smart.parent) return;
-   if (obj->cur.layer == l)
+   if (obj->cur->layer == l)
      {
         evas_object_raise(eo_obj);
         return;
      }
    eo_e = obj->layer->evas->evas;
    evas_object_release(eo_obj, obj, 1);
-   obj->cur.layer = l;
+   EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+     {
+       state_write->layer = l;
+     }
+   EINA_COW_STATE_WRITE_END(obj, state_write, cur);
+
    evas_object_inject(eo_obj, obj, eo_e);
    obj->restack = 1;
    evas_object_change(eo_obj, obj);
@@ -207,7 +217,7 @@ _layer_set(Eo *eo_obj, void *_obj, va_list *list)
         if (evas_object_is_in_output_rect(eo_obj, obj,
                                           obj->layer->evas->pointer.x,
                                           obj->layer->evas->pointer.y, 1, 1) &&
-            obj->cur.visible)
+            obj->cur->visible)
           if (eina_list_data_find(obj->layer->evas->pointer.object.in, obj))
             evas_event_feed_mouse_move(obj->layer->evas->evas,
                                        obj->layer->evas->pointer.x,
@@ -248,7 +258,7 @@ _layer_get(Eo *eo_obj EINA_UNUSED, void *_obj, va_list *list)
    if (obj->smart.parent)
      {
         Evas_Object_Protected_Data *smart_parent_obj = eo_data_get(obj->smart.parent, EVAS_OBJ_CLASS);
-        *layer = smart_parent_obj->cur.layer;
+        *layer = smart_parent_obj->cur->layer;
      }
-   *layer = obj->cur.layer;
+   *layer = obj->cur->layer;
 }
index 05efdd9..5f05263 100644 (file)
@@ -18,7 +18,7 @@ _evas_map_calc_geom_change(Evas_Object *eo_obj)
              is = evas_object_is_in_output_rect(eo_obj, obj,
                                                 obj->layer->evas->pointer.x,
                                                 obj->layer->evas->pointer.y, 1, 1);
-             if ((is ^ was) && obj->cur.visible)
+             if ((is ^ was) && obj->cur->visible)
                evas_event_feed_mouse_move(obj->layer->evas->evas,
                                           obj->layer->evas->pointer.x,
                                           obj->layer->evas->pointer.y,
@@ -461,7 +461,7 @@ _map_enable_set(Eo *eo_obj, void *_pd, va_list *list)
              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
      {
@@ -557,7 +557,12 @@ _map_set(Eo *eo_obj, void *_pd, va_list *list)
         if (obj->map->cur.map)
           {
              obj->changed_map = EINA_TRUE;
-             obj->prev.geometry = obj->map->cur.map->normal_geometry;
+
+            EINA_COW_STATE_WRITE_BEGIN(obj, state_write, prev)
+              {
+                state_write->geometry = obj->map->cur.map->normal_geometry;
+              }
+            EINA_COW_STATE_WRITE_END(obj, state_write, prev);
 
              EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
                {
@@ -847,8 +852,8 @@ evas_map_util_points_populate_from_object_full(Evas_Map *m, const Evas_Object *e
         ERR("map has count=%d where 4 was expected.", m->count);
         return;
      }
-   _evas_map_util_points_populate(m, obj->cur.geometry.x, obj->cur.geometry.y,
-                                  obj->cur.geometry.w, obj->cur.geometry.h, z);
+   _evas_map_util_points_populate(m, obj->cur->geometry.x, obj->cur->geometry.y,
+                                  obj->cur->geometry.w, obj->cur->geometry.h, z);
 }
 
 EAPI void
@@ -869,8 +874,8 @@ evas_map_util_points_populate_from_object(Evas_Map *m, const Evas_Object *eo_obj
         ERR("map has count=%d where 4 was expected.", m->count);
         return;
      }
-   _evas_map_util_points_populate(m, obj->cur.geometry.x, obj->cur.geometry.y,
-                                  obj->cur.geometry.w, obj->cur.geometry.h, 0);
+   _evas_map_util_points_populate(m, obj->cur->geometry.x, obj->cur->geometry.y,
+                                  obj->cur->geometry.w, obj->cur->geometry.h, 0);
 }
 
 EAPI void
index f80570c..d0cde1b 100644 (file)
@@ -71,26 +71,28 @@ struct _Evas_Object_Image_Pixels
 
 struct _Evas_Object_Image_State
 {
-      Evas_Coord_Rectangle fill;
-      struct {
-           short         w, h, stride;
-      } image;
-      struct {
-           short         l, r, t, b;
-           unsigned char fill;
-           double        scale;
-      } border;
-
-      Evas_Object   *source;
-      Evas_Map      *defmap;
-      const char    *file;
-      const char    *key;
-      int            frame;
-      Evas_Colorspace cspace;
-      int             spread;
-
-      Eina_Bool      smooth_scale : 1;
-      Eina_Bool      has_alpha :1;
+   Evas_Coord_Rectangle fill;
+   struct {
+      short         w, h, stride;
+   } image;
+   struct {
+      short         l, r, t, b;
+      unsigned char fill;
+      double        scale;
+   } border;
+
+   Evas_Object   *source;
+   Evas_Map      *defmap;
+   const char    *file;
+   const char    *key;
+   int            frame;
+   Evas_Colorspace cspace;
+   int             spread;
+
+   Eina_Bool      smooth_scale : 1;
+   Eina_Bool      has_alpha :1;
+   Eina_Bool      opaque_valid : 1;
+   Eina_Bool      opaque : 1;
 };
 
 struct _Evas_Object_Image
@@ -196,7 +198,7 @@ static const Evas_Object_Image_State default_state = {
   EVAS_COLORSPACE_ARGB8888,
   EVAS_TEXTURE_REPEAT,
 
-  EINA_TRUE, 0
+  EINA_TRUE, EINA_FALSE, EINA_FALSE
 };
 
 Eina_Cow *evas_object_image_load_opts_cow = NULL;
@@ -216,28 +218,33 @@ Eina_Cow *evas_object_image_state_cow = NULL;
 # define EINA_COW_LOAD_OPTS_WRITE_END(Obj, Write) \
   EINA_COW_WRITE_END(evas_object_image_load_opts_cow, Obj->load_opts, Write)
 
-# define EINA_COW_STATE_WRITE_BEGIN(Obj, Write) \
+# define EINA_COW_IMAGE_STATE_WRITE_BEGIN(Obj, Write) \
   EINA_COW_WRITE_BEGIN(evas_object_image_state_cow, Obj->cur, Evas_Object_Image_State, Write)
 
-# define EINA_COW_STATE_WRITE_END(Obj, Write) \
+# define EINA_COW_IMAGE_STATE_WRITE_END(Obj, Write) \
   EINA_COW_WRITE_END(evas_object_image_state_cow, Obj->cur, Write)
 
 # define EVAS_OBJECT_WRITE_IMAGE_FREE_FILE_AND_KEY(Obj) \
   if (Obj->cur->file || Obj->cur->key)                  \
     {                                                   \
-       EINA_COW_STATE_WRITE_BEGIN(Obj, cur_write)                       \
+       EINA_COW_IMAGE_STATE_WRITE_BEGIN(Obj, cur_write)                       \
          {                                                              \
             EINA_COW_WRITE_BEGIN(evas_object_image_state_cow, Obj->prev, Evas_Object_Image_State, prev_write) \
               EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(cur_write, prev_write); \
             EINA_COW_WRITE_END(evas_object_image_state_cow, Obj->prev, prev_write); \
          }                                                              \
-       EINA_COW_STATE_WRITE_END(Obj, cur_write);                        \
+       EINA_COW_IMAGE_STATE_WRITE_END(Obj, cur_write);                        \
     }
 
 static void
 _evas_object_image_cleanup(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, Evas_Object_Image *o)
 {
-   obj->cur.opaque_valid = 0;
+   EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
+     {
+        state_write->opaque_valid = 0;
+     }
+   EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
+
    if ((o->preloading) && (o->engine_data))
      {
         o->preloading = EINA_FALSE;
@@ -305,9 +312,9 @@ _constructor(Eo *eo_obj, void *class_data, va_list *list EINA_UNUSED)
 
    if (cspace != o->cur->cspace)
      {
-        EINA_COW_STATE_WRITE_BEGIN(o, state_write)
+        EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
           state_write->cspace = cspace;
-        EINA_COW_STATE_WRITE_END(o, state_write);
+        EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
      }
 }
 
@@ -506,7 +513,7 @@ _image_file_set(Eo *eo_obj, void *_pd, va_list *list)
  */
    if (o->cur->source) _proxy_unset(eo_obj);
 
-   EINA_COW_STATE_WRITE_BEGIN(o, state_write)
+   EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
      {
         if (o->cur->file) eina_stringshare_del(state_write->file);
         if (o->cur->key) eina_stringshare_del(o->cur->key);
@@ -515,7 +522,7 @@ _image_file_set(Eo *eo_obj, void *_pd, va_list *list)
         if (key) state_write->key = eina_stringshare_add(key);
         else state_write->key = NULL;
      }
-   EINA_COW_STATE_WRITE_END(o, state_write);
+   EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
 
    EINA_COW_WRITE_BEGIN(evas_object_image_state_cow, o->prev, Evas_Object_Image_State, state_write)
      {
@@ -566,7 +573,7 @@ _image_file_set(Eo *eo_obj, void *_pd, va_list *list)
           obj->layer->evas->engine.func->image_stride_get(obj->layer->evas->engine.data.output, o->engine_data, &stride);
         else
           stride = w * 4;
-        EINA_COW_STATE_WRITE_BEGIN(o, state_write)
+        EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
           {
              state_write->has_alpha = obj->layer->evas->engine.func->image_alpha_get(obj->layer->evas->engine.data.output, o->engine_data);
              state_write->cspace = obj->layer->evas->engine.func->image_colorspace_get(obj->layer->evas->engine.data.output, o->engine_data);
@@ -578,14 +585,14 @@ _image_file_set(Eo *eo_obj, void *_pd, va_list *list)
              state_write->image.h = h;
              state_write->image.stride = stride;
           }
-        EINA_COW_STATE_WRITE_END(o, state_write);
+        EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
      }
    else
      {
         if (o->load_error == EVAS_LOAD_ERROR_NONE)
           o->load_error = EVAS_LOAD_ERROR_GENERIC;
 
-        EINA_COW_STATE_WRITE_BEGIN(o, state_write)
+        EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
           {
              state_write->has_alpha = EINA_TRUE;
              state_write->cspace = EVAS_COLORSPACE_ARGB8888;
@@ -597,7 +604,7 @@ _image_file_set(Eo *eo_obj, void *_pd, va_list *list)
              state_write->image.h = 0;
              state_write->image.stride = 0;
           }
-        EINA_COW_STATE_WRITE_END(o, state_write);
+        EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
      }
 
    o->changed = EINA_TRUE;
@@ -887,14 +894,14 @@ _image_border_set(Eo *eo_obj, void *_pd, va_list *list)
        (o->cur->border.t == t) &&
        (o->cur->border.b == b)) return;
 
-   EINA_COW_STATE_WRITE_BEGIN(o, state_write)
+   EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
      {
         state_write->border.l = l;
         state_write->border.r = r;
         state_write->border.t = t;
         state_write->border.b = b;
      }
-   EINA_COW_STATE_WRITE_END(o, state_write);
+   EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
    o->changed = EINA_TRUE;
    evas_object_change(eo_obj, obj);
 }
@@ -941,9 +948,9 @@ _image_border_center_fill_set(Eo *eo_obj, void *_pd, va_list *list)
    Evas_Border_Fill_Mode fill = va_arg(*list, Evas_Border_Fill_Mode);
    Evas_Object_Image *o = _pd;
    if (fill == o->cur->border.fill) return;
-   EINA_COW_STATE_WRITE_BEGIN(o, state_write)
+   EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
      state_write->border.fill = fill;
-   EINA_COW_STATE_WRITE_END(o, state_write);
+   EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
 
    o->changed = EINA_TRUE;
    Evas_Object_Protected_Data *obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS);
@@ -1041,9 +1048,9 @@ _image_border_scale_set(Eo *eo_obj, void *_pd, va_list *list)
    double scale = va_arg(*list, double);
 
    if (scale == o->cur->border.scale) return;
-   EINA_COW_STATE_WRITE_BEGIN(o, state_write)
+   EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
      state_write->border.scale = scale;
-   EINA_COW_STATE_WRITE_END(o, state_write);
+   EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
 
    o->changed = EINA_TRUE;
    obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS);
@@ -1099,18 +1106,18 @@ _image_fill_set(Eo *eo_obj, void *_pd, va_list *list)
        (o->cur->fill.w == w) &&
        (o->cur->fill.h == h)) return;
 
-   EINA_COW_STATE_WRITE_BEGIN(o, state_write)
+   EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
      {
         state_write->fill.x = x;
         state_write->fill.y = y;
         state_write->fill.w = w;
         state_write->fill.h = h;
+        state_write->opaque_valid = 0;
      }
-   EINA_COW_STATE_WRITE_END(o, state_write);
+   EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
 
    o->changed = EINA_TRUE;
    obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS);
-   obj->cur.opaque_valid = 0;
    evas_object_change(eo_obj, obj);
 }
 
@@ -1162,9 +1169,9 @@ _image_fill_spread_set(Eo *eo_obj, void *_pd, va_list *list)
 
    if (spread == (Evas_Fill_Spread)o->cur->spread) return;
 
-   EINA_COW_STATE_WRITE_BEGIN(o, state_write)
+   EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
      state_write->spread = spread;
-   EINA_COW_STATE_WRITE_END(o, state_write);
+   EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
 
    o->changed = EINA_TRUE;
    obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS);
@@ -1217,12 +1224,12 @@ _image_size_set(Eo *eo_obj, void *_pd, va_list *list)
    if ((w == o->cur->image.w) &&
        (h == o->cur->image.h)) return;
 
-   EINA_COW_STATE_WRITE_BEGIN(o, state_write)
+   EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
      {
         state_write->image.w = w;
         state_write->image.h = h;
      }
-   EINA_COW_STATE_WRITE_END(o, state_write);
+   EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
 
    if (o->engine_data)
       o->engine_data = obj->layer->evas->engine.func->image_size_set(obj->layer->evas->engine.data.output, o->engine_data, w, h);
@@ -1250,7 +1257,7 @@ _image_size_set(Eo *eo_obj, void *_pd, va_list *list)
      }
    else
       stride = w * 4;
-   EINA_COW_STATE_WRITE_BEGIN(o, cur_write)
+   EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, cur_write)
      {
         cur_write->image.stride = stride;
 
@@ -1264,7 +1271,7 @@ _image_size_set(Eo *eo_obj, void *_pd, va_list *list)
           EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(cur_write, prev_write);
         EINA_COW_WRITE_END(evas_object_image_state_cow, o->prev, prev_write);
      }
-   EINA_COW_STATE_WRITE_END(o, cur_write);
+   EINA_COW_IMAGE_STATE_WRITE_END(o, cur_write);
 
    o->changed = EINA_TRUE;
    evas_object_inform_call_image_resize(eo_obj);
@@ -1435,9 +1442,9 @@ _image_data_set(Eo *eo_obj, void *_pd, va_list *list)
 
              if (o->cur->image.stride != stride)
                {
-                  EINA_COW_STATE_WRITE_BEGIN(o, state_write)
+                  EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
                     state_write->image.stride = stride;
-                  EINA_COW_STATE_WRITE_END(o, state_write);
+                  EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
                }
          }
      }
@@ -1449,13 +1456,13 @@ _image_data_set(Eo *eo_obj, void *_pd, va_list *list)
         if ((o->cur->image.w != 0) || (o->cur->image.h != 0))
           resize_call = EINA_TRUE;
 
-        EINA_COW_STATE_WRITE_BEGIN(o, state_write)
+        EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
           {
              state_write->image.w = 0;
              state_write->image.h = 0;
              state_write->image.stride = 0;
           }
-        EINA_COW_STATE_WRITE_END(o, state_write);
+        EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
 
         o->engine_data = NULL;
      }
@@ -1536,9 +1543,9 @@ _image_data_get(Eo *eo_obj, void *_pd, va_list *list)
 
         if (o->cur->image.stride != stride)
           {
-             EINA_COW_STATE_WRITE_BEGIN(o, state_write)
+             EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
                state_write->image.stride = stride;
-             EINA_COW_STATE_WRITE_END(o, state_write);
+             EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
           }
      }
    o->pixels_checked_out++;
@@ -1651,9 +1658,9 @@ _image_data_copy_set(Eo *eo_obj, void *_pd, va_list *list)
 
         if (o->cur->image.stride != stride)
           {
-             EINA_COW_STATE_WRITE_BEGIN(o, state_write)
+             EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
                state_write->image.stride = stride;
-             EINA_COW_STATE_WRITE_END(o, state_write);
+             EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
           }
      }
    o->pixels_checked_out = 0;
@@ -1742,9 +1749,9 @@ _image_alpha_set(Eo *eo_obj, void *_pd, va_list *list)
      return;
    if (o->cur->has_alpha != has_alpha)
      {
-        EINA_COW_STATE_WRITE_BEGIN(o, state_write)
+        EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
           state_write->has_alpha = has_alpha;
-        EINA_COW_STATE_WRITE_END(o, state_write);
+        EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
      }
    if (o->engine_data)
      {
@@ -1770,9 +1777,9 @@ _image_alpha_set(Eo *eo_obj, void *_pd, va_list *list)
            stride = o->cur->image.w * 4;
         if (o->cur->image.stride != stride)
           {
-             EINA_COW_STATE_WRITE_BEGIN(o, state_write)
+             EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
                state_write->image.stride = stride;
-             EINA_COW_STATE_WRITE_END(o, state_write);
+             EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
           }
      }
    evas_object_image_data_update_add(eo_obj, 0, 0, o->cur->image.w, o->cur->image.h);
@@ -1818,9 +1825,9 @@ _image_smooth_scale_set(Eo *eo_obj, void *_pd, va_list *list)
    if (((smooth_scale) && (o->cur->smooth_scale)) ||
        ((!smooth_scale) && (!o->cur->smooth_scale)))
      return;
-   EINA_COW_STATE_WRITE_BEGIN(o, state_write)
+   EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
      state_write->smooth_scale = smooth_scale;
-   EINA_COW_STATE_WRITE_END(o, state_write);
+   EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
 
    o->changed = EINA_TRUE;
    obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS);
@@ -2398,9 +2405,9 @@ _image_colorspace_set(Eo *eo_obj, void *_pd, va_list *list)
 
    _evas_object_image_cleanup(eo_obj, obj, o);
 
-   EINA_COW_STATE_WRITE_BEGIN(o, state_write)
+   EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
      state_write->cspace = cspace;
-   EINA_COW_STATE_WRITE_END(o, state_write);
+   EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
 
    if (o->engine_data)
      obj->layer->evas->engine.func->image_colorspace_set(obj->layer->evas->engine.data.output, o->engine_data, cspace);
@@ -2598,9 +2605,9 @@ _image_scale_hint_set(Eo *eo_obj, void *_pd, va_list *list)
 
         if (o->cur->image.stride != stride)
           {
-             EINA_COW_STATE_WRITE_BEGIN(o, state_write)
+             EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
                state_write->image.stride = stride;
-             EINA_COW_STATE_WRITE_END(o, state_write);
+             EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
           }
      }
 }
@@ -2658,9 +2665,9 @@ _image_content_hint_set(Eo *eo_obj, void *_pd, va_list *list)
 
         if (o->cur->image.stride != stride)
           {
-             EINA_COW_STATE_WRITE_BEGIN(o, state_write)
+             EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
                state_write->image.stride = stride;
-             EINA_COW_STATE_WRITE_END(o, state_write);
+             EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
           }
      }
 }
@@ -2892,9 +2899,9 @@ _image_animated_frame_set(Eo *eo_obj, void *_pd, va_list *list)
      prev_write->frame = o->cur->frame;
    EINA_COW_WRITE_END(evas_object_image_state_cow, o->prev, prev_write);
 
-   EINA_COW_STATE_WRITE_BEGIN(o, state_write)
+   EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
      state_write->frame = frame_index;
-   EINA_COW_STATE_WRITE_END(o, state_write);
+   EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
 
    o->changed = EINA_TRUE;
    evas_object_change(eo_obj, obj);
@@ -3062,19 +3069,19 @@ _proxy_unset(Evas_Object *proxy)
 
    if (o->cur->source)
      {
-        EINA_COW_STATE_WRITE_BEGIN(o, state_write)
+        EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
           state_write->source = NULL;
-        EINA_COW_STATE_WRITE_END(o, state_write);
+        EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
      }
 
    if (o->cur->defmap)
      {
-        EINA_COW_STATE_WRITE_BEGIN(o, state_write)
+        EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
           {
              evas_map_free(state_write->defmap);
              state_write->defmap = NULL;
           }
-        EINA_COW_STATE_WRITE_END(o, state_write);
+        EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
      }
 
    EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, cur_source->proxy, Evas_Object_Proxy_Data, proxy_write)
@@ -3095,9 +3102,9 @@ _proxy_set(Evas_Object *eo_proxy, Evas_Object *eo_src)
      proxy_write->is_proxy = EINA_TRUE;
    EINA_COW_WRITE_END(evas_object_proxy_cow, proxy->proxy, proxy_write);
 
-   EINA_COW_STATE_WRITE_BEGIN(o, state_write)
+   EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
      state_write->source = eo_src;
-   EINA_COW_STATE_WRITE_END(o, state_write);
+   EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
    o->load_error = EVAS_LOAD_ERROR_NONE;
 
    EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, src->proxy, Evas_Object_Proxy_Data, proxy_src_write)
@@ -3129,11 +3136,11 @@ _proxy_error(Evas_Object *eo_proxy, void *context, void *output, void *surface,
    func = proxy->layer->evas->engine.func;
    func->context_color_set(output, context, r, g, b, 255);
    func->context_multiplier_unset(output, context);
-   func->context_render_op_set(output, context, proxy->cur.render_op);
-   func->rectangle_draw(output, context, surface, proxy->cur.geometry.x + x,
-                        proxy->cur.geometry.y + y,
-                        proxy->cur.geometry.w,
-                        proxy->cur.geometry.h,
+   func->context_render_op_set(output, context, proxy->cur->render_op);
+   func->rectangle_draw(output, context, surface, proxy->cur->geometry.x + x,
+                        proxy->cur->geometry.y + y,
+                        proxy->cur->geometry.w,
+                        proxy->cur->geometry.h,
                         do_async);
    return;
 }
@@ -3146,12 +3153,12 @@ _proxy_subrender_recurse(Evas_Object *eo_obj, Evas_Object *clip, void *output, v
    Evas *eo_e = obj->layer->evas;
    
    if (obj->clip.clipees) return;
-   if (!obj->cur.visible) return;
-   if ((!clip) || (clip != obj->cur.clipper))
+   if (!obj->cur->visible) return;
+   if ((!clip) || (clip != obj->cur->clipper))
      {
-        if (!obj->cur.cache.clip.visible) return;
-        if ((obj->cur.cache.clip.a == 0) &&
-            (obj->cur.render_op == EVAS_RENDER_BLEND)) return;
+        if (!obj->cur->cache.clip.visible) return;
+        if ((obj->cur->cache.clip.a == 0) &&
+            (obj->cur->render_op == EVAS_RENDER_BLEND)) return;
      }
    if ((obj->func->is_visible) && (!obj->func->is_visible(eo_obj))) return;
    
@@ -3190,8 +3197,8 @@ _proxy_subrender(Evas *eo_e, Evas_Object *eo_source, Eina_Bool do_async)
    if (!eo_source) return;
    source = eo_data_get(eo_source, EVAS_OBJ_CLASS);
 
-   w = source->cur.geometry.w;
-   h = source->cur.geometry.h;
+   w = source->cur->geometry.w;
+   h = source->cur->geometry.h;
 
    EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, source->proxy, Evas_Object_Proxy_Data, proxy_write)
      {
@@ -3227,8 +3234,8 @@ _proxy_subrender(Evas *eo_e, Evas_Object *eo_source, Eina_Bool do_async)
 
         ctx = e->engine.func->context_new(e->engine.data.output);
         evas_render_mapped(e, eo_source, source, ctx, proxy_write->surface,
-                           -source->cur.geometry.x,
-                           -source->cur.geometry.y,
+                           -source->cur->geometry.x,
+                           -source->cur->geometry.y,
                            1, 0, 0, e->output.w, e->output.h, EINA_TRUE
 #ifdef REND_DBG
                            , 1
@@ -3248,8 +3255,8 @@ _proxy_subrender(Evas *eo_e, Evas_Object *eo_source, Eina_Bool do_async)
              _proxy_subrender_recurse(obj2, clip, e->engine.data.output,
                                       proxy_write->surface,
                                       ctx,
-                                      -source->cur.geometry.x,
-                                      -source->cur.geometry.y);
+                                      -source->cur->geometry.x,
+                                      -source->cur->geometry.y);
           }
      }
    else
@@ -3258,8 +3265,8 @@ _proxy_subrender(Evas *eo_e, Evas_Object *eo_source, Eina_Bool do_async)
            source->func->render_pre(source);
         source->func->render(source, e->engine.data.output, ctx,
                              proxy_write->surface,
-                             -source->cur.geometry.x,
-                             -source->cur.geometry.y);
+                             -source->cur->geometry.x,
+                             -source->cur->geometry.y);
      }
    
    e->engine.func->context_free(e->engine.data.output, ctx);
@@ -3306,7 +3313,7 @@ evas_object_image_unload(Evas_Object *eo_obj, Eina_Bool dirty)
    o->engine_data = NULL;
    o->load_error = EVAS_LOAD_ERROR_NONE;
 
-   EINA_COW_STATE_WRITE_BEGIN(o, state_write)
+   EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
      {
         state_write->has_alpha = EINA_TRUE;
         state_write->cspace = EVAS_COLORSPACE_ARGB8888;
@@ -3315,7 +3322,7 @@ evas_object_image_unload(Evas_Object *eo_obj, Eina_Bool dirty)
         state_write->image.h = 0;
         state_write->image.stride = 0;
      }
-   EINA_COW_STATE_WRITE_END(o, state_write);
+   EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
    if (resize_call) evas_object_inform_call_image_resize(eo_obj);
 }
 
@@ -3367,7 +3374,7 @@ evas_object_image_load(Evas_Object *eo_obj)
         else
           stride = w * 4;
 
-        EINA_COW_STATE_WRITE_BEGIN(o, state_write)
+        EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
           {
              state_write->has_alpha = obj->layer->evas->engine.func->image_alpha_get
                (obj->layer->evas->engine.data.output,
@@ -3381,7 +3388,7 @@ evas_object_image_load(Evas_Object *eo_obj)
              state_write->image.h = h;
              state_write->image.stride = stride;
           }
-        EINA_COW_STATE_WRITE_END(o, state_write);
+        EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
         if (resize_call) evas_object_inform_call_image_resize(eo_obj);
      }
    else
@@ -3438,24 +3445,9 @@ static void
 evas_object_image_init(Evas_Object *eo_obj)
 {
    Evas_Object_Protected_Data *obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS);
-   /* set up default settings for this kind of object */
-   obj->cur.color.r = 255;
-   obj->cur.color.g = 255;
-   obj->cur.color.b = 255;
-   obj->cur.color.a = 255;
-   obj->cur.geometry.x = 0;
-   obj->cur.geometry.y = 0;
-   obj->cur.geometry.w = 0;
-   obj->cur.geometry.h = 0;
-   obj->cur.layer = 0;
-   obj->cur.anti_alias = 0;
-   obj->cur.render_op = EVAS_RENDER_BLEND;
-   /* set up object-specific settings */
-   obj->prev = obj->cur;
    /* set up methods (compulsory) */
    obj->func = &object_func;
    obj->type = o_type;
-   obj->cur.opaque_valid = 0;
 }
 
 static void
@@ -3613,10 +3605,10 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v
         obj->layer->evas->engine.func->rectangle_draw(output,
                                                       context,
                                                       surface,
-                                                      obj->cur.geometry.x + x,
-                                                      obj->cur.geometry.y + y,
-                                                      obj->cur.geometry.w,
-                                                      obj->cur.geometry.h,
+                                                      obj->cur->geometry.x + x,
+                                                      obj->cur->geometry.y + y,
+                                                      obj->cur->geometry.w,
+                                                      obj->cur->geometry.h,
                                                       do_async);
 
         return;
@@ -3626,10 +3618,10 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v
                                                     context,
                                                     255, 255, 255, 255);
 
-   if ((obj->cur.cache.clip.r == 255) &&
-       (obj->cur.cache.clip.g == 255) &&
-       (obj->cur.cache.clip.b == 255) &&
-       (obj->cur.cache.clip.a == 255))
+   if ((obj->cur->cache.clip.r == 255) &&
+       (obj->cur->cache.clip.g == 255) &&
+       (obj->cur->cache.clip.b == 255) &&
+       (obj->cur->cache.clip.a == 255))
      {
         obj->layer->evas->engine.func->context_multiplier_unset(output,
                                                                 context);
@@ -3637,13 +3629,13 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v
    else
      obj->layer->evas->engine.func->context_multiplier_set(output,
                                                            context,
-                                                           obj->cur.cache.clip.r,
-                                                           obj->cur.cache.clip.g,
-                                                           obj->cur.cache.clip.b,
-                                                           obj->cur.cache.clip.a);
+                                                           obj->cur->cache.clip.r,
+                                                           obj->cur->cache.clip.g,
+                                                           obj->cur->cache.clip.b,
+                                                           obj->cur->cache.clip.a);
 
    obj->layer->evas->engine.func->context_render_op_set(output, context,
-                                                        obj->cur.render_op);
+                                                        obj->cur->render_op);
 
    Evas_Object_Protected_Data *source =
       (o->cur->source ?
@@ -3673,8 +3665,8 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v
         pixels = oi->engine_data;
         imagew = oi->cur->image.w;
         imageh = oi->cur->image.h;
-        uvw = source->cur.geometry.w;
-        uvh = source->cur.geometry.h;
+        uvw = source->cur->geometry.w;
+        uvh = source->cur->geometry.h;
      }
    else
      {
@@ -3702,12 +3694,12 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v
                   // Check for image w/h against image geometry w/h
                   // Check for image color r,g,b,a = {255,255,255,255}
                   // Check and make sure that there are no maps.
-                  if ( (obj->cur.geometry.w == o->cur->image.w) &&
-                       (obj->cur.geometry.h == o->cur->image.h) &&
-                       (obj->cur.color.r == 255) &&
-                       (obj->cur.color.g == 255) &&
-                       (obj->cur.color.b == 255) &&
-                       (obj->cur.color.a == 255) &&
+                  if ( (obj->cur->geometry.w == o->cur->image.w) &&
+                       (obj->cur->geometry.h == o->cur->image.h) &&
+                       (obj->cur->color.r == 255) &&
+                       (obj->cur->color.g == 255) &&
+                       (obj->cur->color.b == 255) &&
+                       (obj->cur->color.a == 255) &&
                        (!obj->map->cur.map) )
                     {
                        if (obj->layer->evas->engine.func->gl_img_obj_set)
@@ -3751,30 +3743,30 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v
              if (idh < 1) idh = 1;
              if (idx > 0) idx -= idw;
              if (idy > 0) idy -= idh;
-             while ((int)idx < obj->cur.geometry.w)
+             while ((int)idx < obj->cur->geometry.w)
                {
                   Evas_Coord ydy;
                   int dobreak_w = 0;
 
                   ydy = idy;
                   ix = idx;
-                  if ((o->cur->fill.w == obj->cur.geometry.w) &&
+                  if ((o->cur->fill.w == obj->cur->geometry.w) &&
                       (o->cur->fill.x == 0))
                     {
                        dobreak_w = 1;
-                       iw = obj->cur.geometry.w;
+                       iw = obj->cur->geometry.w;
                     }
                   else
                     iw = ((int)(idx + idw)) - ix;
-                  while ((int)idy < obj->cur.geometry.h)
+                  while ((int)idy < obj->cur->geometry.h)
                     {
                        int dobreak_h = 0;
 
                        iy = idy;
-                       if ((o->cur->fill.h == obj->cur.geometry.h) &&
+                       if ((o->cur->fill.h == obj->cur->geometry.h) &&
                            (o->cur->fill.y == 0))
                          {
-                            ih = obj->cur.geometry.h;
+                            ih = obj->cur->geometry.h;
                             dobreak_h = 1;
                          }
                        else
@@ -3808,8 +3800,8 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v
                                    (obj, output, context, surface, data,
                                     0, 0,
                                     w, h,
-                                    obj->cur.geometry.x + ix + x,
-                                    obj->cur.geometry.y + iy + y,
+                                    obj->cur->geometry.x + ix + x,
+                                    obj->cur->geometry.y + iy + y,
                                     iw, ih,
                                     o->cur->smooth_scale,
                                     do_async);
@@ -3821,8 +3813,8 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v
                                    (obj, output, context, surface, pixels,
                                     0, 0,
                                     imagew, imageh,
-                                    obj->cur.geometry.x + ix + x,
-                                    obj->cur.geometry.y + iy + y,
+                                    obj->cur->geometry.x + ix + x,
+                                    obj->cur->geometry.y + iy + y,
                                     iw, ih,
                                     o->cur->smooth_scale,
                                     do_async);
@@ -3834,8 +3826,8 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v
                             int bl, br, bt, bb, bsl, bsr, bst, bsb;
                             int imw, imh, ox, oy;
 
-                            ox = obj->cur.geometry.x + ix + x;
-                            oy = obj->cur.geometry.y + iy + y;
+                            ox = obj->cur->geometry.x + ix + x;
+                            oy = obj->cur->geometry.y + iy + y;
                             imw = imagew;
                             imh = imageh;
                             bl = o->cur->border.l;
@@ -3910,14 +3902,14 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v
                                  outx = ox + bsl; outy = oy + bst;
                                  outw = iw - bsl - bsr; outh = ih - bst - bsb;
                                  if ((o->cur->border.fill == EVAS_BORDER_FILL_SOLID) &&
-                                     (obj->cur.cache.clip.a == 255) &&
-                                     (obj->cur.render_op == EVAS_RENDER_BLEND))
+                                     (obj->cur->cache.clip.a == 255) &&
+                                     (obj->cur->render_op == EVAS_RENDER_BLEND))
                                    {
                                       obj->layer->evas->engine.func->context_render_op_set(output, context,
                                                                                            EVAS_RENDER_COPY);
                                       _draw_image(obj, output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur->smooth_scale, do_async);
                                       obj->layer->evas->engine.func->context_render_op_set(output, context,
-                                                                                           obj->cur.render_op);
+                                                                                           obj->cur->render_op);
                                    }
                                  else
                                    _draw_image(obj, output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur->smooth_scale, do_async);
@@ -3996,11 +3988,11 @@ evas_object_image_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *ob
      }
 
    /* if someone is clipping this obj - go calculate the clipper */
-   if (obj->cur.clipper)
+   if (obj->cur->clipper)
      {
-       if (obj->cur.cache.clip.dirty)
-         evas_object_clip_recalc(obj->cur.eo_clipper, obj->cur.clipper);
-       obj->cur.clipper->func->render_pre(obj->cur.eo_clipper, obj->cur.clipper);
+       if (obj->cur->cache.clip.dirty)
+         evas_object_clip_recalc(obj->cur->eo_clipper, obj->cur->clipper);
+       obj->cur->clipper->func->render_pre(obj->cur->eo_clipper, obj->cur->clipper);
      }
    /* Proxy: Do it early */
    if (o->cur->source)
@@ -4039,22 +4031,22 @@ evas_object_image_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *ob
         if (!o->pixels->pixel_updates) goto done;
      }
    /* if it changed color */
-   if ((obj->cur.color.r != obj->prev.color.r) ||
-       (obj->cur.color.g != obj->prev.color.g) ||
-       (obj->cur.color.b != obj->prev.color.b) ||
-       (obj->cur.color.a != obj->prev.color.a))
+   if ((obj->cur->color.r != obj->prev->color.r) ||
+       (obj->cur->color.g != obj->prev->color.g) ||
+       (obj->cur->color.b != obj->prev->color.b) ||
+       (obj->cur->color.a != obj->prev->color.a))
      {
         evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj);
         if (!o->pixels->pixel_updates) goto done;
      }
    /* if it changed render op */
-   if (obj->cur.render_op != obj->prev.render_op)
+   if (obj->cur->render_op != obj->prev->render_op)
      {
         evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj);
         if (!o->pixels->pixel_updates) goto done;
      }
    /* if it changed anti_alias */
-   if (obj->cur.anti_alias != obj->prev.anti_alias)
+   if (obj->cur->anti_alias != obj->prev->anti_alias)
      {
         evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj);
         if (!o->pixels->pixel_updates) goto done;
@@ -4105,33 +4097,33 @@ evas_object_image_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *ob
    /* calculate differences since we have a constant color fill */
    /* we really only need to update the differences */
 #if 0 // XXX: maybe buggy?
-   if (((obj->cur.geometry.x != obj->prev.geometry.x) ||
-       (obj->cur.geometry.y != obj->prev.geometry.y) ||
-       (obj->cur.geometry.w != obj->prev.geometry.w) ||
-       (obj->cur.geometry.h != obj->prev.geometry.h)) &&
+   if (((obj->cur->geometry.x != obj->prev->geometry.x) ||
+       (obj->cur->geometry.y != obj->prev->geometry.y) ||
+       (obj->cur->geometry.w != obj->prev->geometry.w) ||
+       (obj->cur->geometry.h != obj->prev->geometry.h)) &&
        (o->cur->fill.w == o->prev->fill.w) &&
        (o->cur->fill.h == o->prev->fill.h) &&
-       ((o->cur->fill.x + obj->cur.geometry.x) == (o->prev->fill.x + obj->prev.geometry.x)) &&
-       ((o->cur->fill.y + obj->cur.geometry.y) == (o->prev->fill.y + obj->prev.geometry.y)) &&
+       ((o->cur->fill.x + obj->cur->geometry.x) == (o->prev->fill.x + obj->prev->geometry.x)) &&
+       ((o->cur->fill.y + obj->cur->geometry.y) == (o->prev->fill.y + obj->prev->geometry.y)) &&
        (!o->pixels->pixel_updates)
        )
      {
        evas_rects_return_difference_rects(&e->clip_changes,
-                                          obj->cur.geometry.x,
-                                          obj->cur.geometry.y,
-                                          obj->cur.geometry.w,
-                                          obj->cur.geometry.h,
-                                          obj->prev.geometry.x,
-                                          obj->prev.geometry.y,
-                                          obj->prev.geometry.w,
-                                          obj->prev.geometry.h);
+                                          obj->cur->geometry.x,
+                                          obj->cur->geometry.y,
+                                          obj->cur->geometry.w,
+                                          obj->cur->geometry.h,
+                                          obj->prev->geometry.x,
+                                          obj->prev->geometry.y,
+                                          obj->prev->geometry.w,
+                                          obj->prev->geometry.h);
        if (!o->pixels->pixel_updates) goto done;
      }
 #endif
-   if (((obj->cur.geometry.x != obj->prev.geometry.x) ||
-        (obj->cur.geometry.y != obj->prev.geometry.y) ||
-        (obj->cur.geometry.w != obj->prev.geometry.w) ||
-        (obj->cur.geometry.h != obj->prev.geometry.h))
+   if (((obj->cur->geometry.x != obj->prev->geometry.x) ||
+        (obj->cur->geometry.y != obj->prev->geometry.y) ||
+        (obj->cur->geometry.w != obj->prev->geometry.w) ||
+        (obj->cur->geometry.h != obj->prev->geometry.h))
       )
      {
         evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj);
@@ -4175,14 +4167,14 @@ evas_object_image_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *ob
                             if (idh < 1) idh = 1;
                             if (idx > 0) idx -= idw;
                             if (idy > 0) idy -= idh;
-                            while (idx < obj->cur.geometry.w)
+                            while (idx < obj->cur->geometry.w)
                               {
                                  Evas_Coord ydy;
 
                                  ydy = idy;
                                  x = idx;
                                  w = ((int)(idx + idw)) - x;
-                                 while (idy < obj->cur.geometry.h)
+                                 while (idy < obj->cur->geometry.h)
                                    {
                                       Eina_Rectangle r;
 
@@ -4193,11 +4185,11 @@ evas_object_image_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *ob
                                       r.y = (rr->y * h) / o->cur->image.h;
                                       r.w = ((rr->w * w) + (o->cur->image.w * 2) - 1) / o->cur->image.w;
                                       r.h = ((rr->h * h) + (o->cur->image.h * 2) - 1) / o->cur->image.h;
-                                      r.x += obj->cur.geometry.x + x;
-                                      r.y += obj->cur.geometry.y + y;
+                                      r.x += obj->cur->geometry.x + x;
+                                      r.y += obj->cur->geometry.y + y;
                                       RECTS_CLIP_TO_RECT(r.x, r.y, r.w, r.h,
-                                                         obj->cur.cache.clip.x, obj->cur.cache.clip.y,
-                                                         obj->cur.cache.clip.w, obj->cur.cache.clip.h);
+                                                         obj->cur->cache.clip.x, obj->cur->cache.clip.y,
+                                                         obj->cur->cache.clip.w, obj->cur->cache.clip.h);
                                       evas_add_rect(&e->clip_changes, r.x, r.y, r.w, r.h);
                                       idy += h;
                                    }
@@ -4235,17 +4227,17 @@ evas_object_image_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *ob
      {
         Evas_Coord x, y, w, h;
 
-        x = obj->cur.cache.clip.x;
-        y = obj->cur.cache.clip.y;
-        w = obj->cur.cache.clip.w;
-        h = obj->cur.cache.clip.h;
-        if (obj->cur.clipper)
+        x = obj->cur->cache.clip.x;
+        y = obj->cur->cache.clip.y;
+        w = obj->cur->cache.clip.w;
+        h = obj->cur->cache.clip.h;
+        if (obj->cur->clipper)
           {
              RECTS_CLIP_TO_RECT(x, y, w, h,
-                                obj->cur.clipper->cur.cache.clip.x,
-                                obj->cur.clipper->cur.cache.clip.y,
-                                obj->cur.clipper->cur.cache.clip.w,
-                                obj->cur.clipper->cur.cache.clip.h);
+                                obj->cur->clipper->cur->cache.clip.x,
+                                obj->cur->clipper->cur->cache.clip.y,
+                                obj->cur->clipper->cur->cache.clip.w,
+                                obj->cur->clipper->cur->cache.clip.h);
           }
         e->engine.func->output_redraws_rect_del(e->engine.data.output,
                                                 x, y, w, h);
@@ -4310,38 +4302,51 @@ evas_object_image_is_opaque(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
    /* currently fully opaque over the entire rectangle it occupies */
 /*  disable caching due tyo maps screwing with this
     o->cur.opaque_valid = 0;*/
-   if (obj->cur.opaque_valid)
+   Evas_Object_Image *o = eo_data_get(eo_obj, MY_CLASS);
+
+   if (o->cur->opaque_valid)
      {
-        if (!obj->cur.opaque) return 0;
+        if (!o->cur->opaque) return 0;
      }
    else
      {
-        Evas_Object_Image *o = eo_data_get(eo_obj, MY_CLASS);
+        EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
+          {
+             state_write->opaque = 0;
+             state_write->opaque_valid = 1;
+          }
+        EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
 
-        obj->cur.opaque = 0;
-        obj->cur.opaque_valid = 1;
         if ((o->cur->fill.w < 1) || (o->cur->fill.h < 1))
-          return obj->cur.opaque;
+          return o->cur->opaque;
         if (((o->cur->border.l != 0) ||
              (o->cur->border.r != 0) ||
              (o->cur->border.t != 0) ||
              (o->cur->border.b != 0)) &&
             (!o->cur->border.fill))
-          return obj->cur.opaque;
+          return o->cur->opaque;
         if (!o->engine_data)
-          return obj->cur.opaque;
+          return o->cur->opaque;
 
         // FIXME: use proxy
         if (o->cur->source)
           {
              Evas_Object_Protected_Data *cur_source = eo_data_get(o->cur->source, EVAS_OBJ_CLASS);
-             obj->cur.opaque = evas_object_is_opaque(o->cur->source, cur_source);
-             return obj->cur.opaque; /* FIXME: Should go poke at the object */
+             EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
+               {
+                  state_write->opaque = evas_object_is_opaque(o->cur->source, cur_source);
+               }
+             EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
+             return o->cur->opaque; /* FIXME: Should go poke at the object */
           }
         if (o->cur->has_alpha)
-          return obj->cur.opaque;
+          return o->cur->opaque;
 
-        obj->cur.opaque = 1;
+        EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
+          {
+             state_write->opaque = 1;
+          }
+        EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
      }
 
    if ((obj->map->cur.map) && (obj->map->cur.usemap))
@@ -4365,57 +4370,77 @@ evas_object_image_is_opaque(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
                      (m->points[1].y == m->points[2].y))
                 )
                {
-                  if ((m->points[0].x == obj->cur.geometry.x) &&
-                      (m->points[0].y == obj->cur.geometry.y) &&
-                      (m->points[2].x == (obj->cur.geometry.x + obj->cur.geometry.w)) &&
-                      (m->points[2].y == (obj->cur.geometry.y + obj->cur.geometry.h)))
-                    return obj->cur.opaque;
+                  if ((m->points[0].x == obj->cur->geometry.x) &&
+                      (m->points[0].y == obj->cur->geometry.y) &&
+                      (m->points[2].x == (obj->cur->geometry.x + obj->cur->geometry.w)) &&
+                      (m->points[2].y == (obj->cur->geometry.y + obj->cur->geometry.h)))
+                    return o->cur->opaque;
                }
           }
-        obj->cur.opaque = 0;
-        return obj->cur.opaque;
+
+        EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
+          {
+             state_write->opaque = 0;
+          }
+        EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
+
+        return o->cur->opaque;
      }
-   if (obj->cur.render_op == EVAS_RENDER_COPY)
+   if (obj->cur->render_op == EVAS_RENDER_COPY)
      {
-        obj->cur.opaque = 1;
-        return obj->cur.opaque;
+        EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
+          {
+             state_write->opaque = 1;
+          }
+        EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
+
+        return o->cur->opaque;
      }
-   return obj->cur.opaque;
+   return o->cur->opaque;
 }
 
 static int
 evas_object_image_was_opaque(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
 {
+   Evas_Object_Image *o = eo_data_get(eo_obj, MY_CLASS);
+
    /* this returns 1 if the internal object data implies that the object was */
    /* previously fully opaque over the entire rectangle it occupies */
-   if (obj->prev.opaque_valid)
+   if (o->prev->opaque_valid)
      {
-        if (!obj->prev.opaque) return 0;
+        if (!o->prev->opaque) return 0;
      }
    else
      {
-        Evas_Object_Image *o = eo_data_get(eo_obj, MY_CLASS);
+        EINA_COW_WRITE_BEGIN(evas_object_image_state_cow, o->prev, Evas_Object_Image_State, state_write)
+          {
+             state_write->opaque = 0;
+             state_write->opaque_valid = 1;
+          }
+        EINA_COW_WRITE_END(evas_object_image_state_cow, o->prev, state_write);
 
-        obj->prev.opaque = 0;
-        obj->prev.opaque_valid = 1;
         if ((o->prev->fill.w < 1) || (o->prev->fill.h < 1))
-          return obj->prev.opaque;
+          return o->prev->opaque;
         if (((o->prev->border.l != 0) ||
              (o->prev->border.r != 0) ||
              (o->prev->border.t != 0) ||
              (o->prev->border.b != 0)) &&
             (!o->prev->border.fill))
-          return obj->prev.opaque;
+          return o->prev->opaque;
         if (!o->engine_data)
-          return obj->prev.opaque;
+          return o->prev->opaque;
 
         // FIXME: use proxy
         if (o->prev->source)
-          return obj->prev.opaque; /* FIXME: Should go poke at the object */
+          return o->prev->opaque; /* FIXME: Should go poke at the object */
         if (o->prev->has_alpha)
-          return obj->prev.opaque;
+          return o->prev->opaque;
 
-        obj->prev.opaque = 1;
+        EINA_COW_WRITE_BEGIN(evas_object_image_state_cow, o->prev, Evas_Object_Image_State, state_write)
+          {
+             state_write->opaque = 1;
+          }
+        EINA_COW_WRITE_END(evas_object_image_state_cow, o->prev, state_write);
      }
    if (obj->map->prev.usemap)
      {
@@ -4438,28 +4463,43 @@ evas_object_image_was_opaque(Evas_Object *eo_obj, Evas_Object_Protected_Data *ob
                      (m->points[1].y == m->points[2].y))
                 )
                {
-                  if ((m->points[0].x == obj->prev.geometry.x) &&
-                      (m->points[0].y == obj->prev.geometry.y) &&
-                      (m->points[2].x == (obj->prev.geometry.x + obj->prev.geometry.w)) &&
-                      (m->points[2].y == (obj->prev.geometry.y + obj->prev.geometry.h)))
-                    return obj->prev.opaque;
+                  if ((m->points[0].x == obj->prev->geometry.x) &&
+                      (m->points[0].y == obj->prev->geometry.y) &&
+                      (m->points[2].x == (obj->prev->geometry.x + obj->prev->geometry.w)) &&
+                      (m->points[2].y == (obj->prev->geometry.y + obj->prev->geometry.h)))
+                    return o->prev->opaque;
                }
           }
 
-        obj->prev.opaque = 0;
-        return obj->prev.opaque;
+        EINA_COW_WRITE_BEGIN(evas_object_image_state_cow, o->prev, Evas_Object_Image_State, state_write)
+          {
+             state_write->opaque = 0;
+          }
+        EINA_COW_WRITE_END(evas_object_image_state_cow, o->prev, state_write);
+
+        return o->prev->opaque;
      }
-   if (obj->prev.render_op == EVAS_RENDER_COPY)
+   if (obj->prev->render_op == EVAS_RENDER_COPY)
      {
-        obj->prev.opaque = 1;
-        return obj->prev.opaque;
+        EINA_COW_WRITE_BEGIN(evas_object_image_state_cow, o->prev, Evas_Object_Image_State, state_write)
+          {
+             state_write->opaque = 1;
+          }
+        EINA_COW_WRITE_END(evas_object_image_state_cow, o->prev, state_write);
+
+        return o->prev->opaque;
      }
-   if (obj->prev.render_op != EVAS_RENDER_BLEND)
+   if (obj->prev->render_op != EVAS_RENDER_BLEND)
      {
-        obj->prev.opaque = 0;
-        return obj->prev.opaque;
+        EINA_COW_WRITE_BEGIN(evas_object_image_state_cow, o->prev, Evas_Object_Image_State, state_write)
+          {
+             state_write->opaque = 0;
+          }
+        EINA_COW_WRITE_END(evas_object_image_state_cow, o->prev, state_write);
+
+        return o->prev->opaque;
      }
-   return obj->prev.opaque;
+   return o->prev->opaque;
 }
 
 static int
@@ -4502,8 +4542,8 @@ evas_object_image_is_inside(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
         pixels = oi->engine_data;
         imagew = oi->cur->image.w;
         imageh = oi->cur->image.h;
-        uvw = source->cur.geometry.w;
-        uvh = source->cur.geometry.h;
+        uvw = source->cur->geometry.w;
+        uvh = source->cur->geometry.h;
      }
    else
      {
@@ -4561,29 +4601,29 @@ evas_object_image_is_inside(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
              if (idh < 1) idh = 1;
              if (idx > 0) idx -= idw;
              if (idy > 0) idy -= idh;
-             while ((int)idx < obj->cur.geometry.w)
+             while ((int)idx < obj->cur->geometry.w)
                {
                   Evas_Coord ydy;
                   int dobreak_w = 0;
                   ydy = idy;
                   ix = idx;
-                  if ((o->cur->fill.w == obj->cur.geometry.w) &&
+                  if ((o->cur->fill.w == obj->cur->geometry.w) &&
                       (o->cur->fill.x == 0))
                     {
                        dobreak_w = 1;
-                       iw = obj->cur.geometry.w;
+                       iw = obj->cur->geometry.w;
                     }
                   else
                     iw = ((int)(idx + idw)) - ix;
-                  while ((int)idy < obj->cur.geometry.h)
+                  while ((int)idy < obj->cur->geometry.h)
                     {
                        int dobreak_h = 0;
 
                        iy = idy;
-                       if ((o->cur->fill.h == obj->cur.geometry.h) &&
+                       if ((o->cur->fill.h == obj->cur->geometry.h) &&
                            (o->cur->fill.y == 0))
                          {
-                            ih = obj->cur.geometry.h;
+                            ih = obj->cur->geometry.h;
                             dobreak_h = 1;
                          }
                        else
@@ -4603,8 +4643,8 @@ evas_object_image_is_inside(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
                                  if (eng->pixel_alpha_get(pixels, px, py, &alpha,
                                                           0, 0,
                                                           imagew, imageh,
-                                                          obj->cur.geometry.x + ix,
-                                                          obj->cur.geometry.y + iy,
+                                                          obj->cur->geometry.x + ix,
+                                                          obj->cur->geometry.y + iy,
                                                           iw, ih))
                                    {
                                       is_inside = alpha > 0;
@@ -4621,8 +4661,8 @@ evas_object_image_is_inside(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
                             int imw, imh, ox, oy;
                             DATA8 alpha = 0;
 
-                            ox = obj->cur.geometry.x + ix;
-                            oy = obj->cur.geometry.y + iy;
+                            ox = obj->cur->geometry.x + ix;
+                            oy = obj->cur->geometry.y + iy;
                             imw = imagew;
                             imh = imageh;
                             bl = o->cur->border.l;
@@ -4822,12 +4862,12 @@ evas_object_image_has_opaque_rect(Evas_Object *eo_obj, Evas_Object_Protected_Dat
    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) &&
-       (obj->cur.cache.clip.a == 255) &&
+       (obj->cur->render_op == EVAS_RENDER_BLEND) &&
+       (obj->cur->cache.clip.a == 255) &&
        (o->cur->fill.x == 0) &&
        (o->cur->fill.y == 0) &&
-       (o->cur->fill.w == obj->cur.geometry.w) &&
-       (o->cur->fill.h == obj->cur.geometry.h)
+       (o->cur->fill.w == obj->cur->geometry.w) &&
+       (o->cur->fill.h == obj->cur->geometry.h)
        ) return 1;
    return 0;
 }
@@ -4839,20 +4879,20 @@ evas_object_image_get_opaque_rect(Evas_Object *eo_obj, Evas_Object_Protected_Dat
 
    if (o->cur->border.scale == 1.0)
      {
-        *x = obj->cur.geometry.x + o->cur->border.l;
-        *y = obj->cur.geometry.y + o->cur->border.t;
-        *w = obj->cur.geometry.w - (o->cur->border.l + o->cur->border.r);
+        *x = obj->cur->geometry.x + o->cur->border.l;
+        *y = obj->cur->geometry.y + o->cur->border.t;
+        *w = obj->cur->geometry.w - (o->cur->border.l + o->cur->border.r);
         if (*w < 0) *w = 0;
-        *h = obj->cur.geometry.h - (o->cur->border.t + o->cur->border.b);
+        *h = obj->cur->geometry.h - (o->cur->border.t + o->cur->border.b);
         if (*h < 0) *h = 0;
      }
    else
      {
-        *x = obj->cur.geometry.x + (o->cur->border.l * o->cur->border.scale);
-        *y = obj->cur.geometry.y + (o->cur->border.t * o->cur->border.scale);
-        *w = obj->cur.geometry.w - ((o->cur->border.l * o->cur->border.scale) + (o->cur->border.r * o->cur->border.scale));
+        *x = obj->cur->geometry.x + (o->cur->border.l * o->cur->border.scale);
+        *y = obj->cur->geometry.y + (o->cur->border.t * o->cur->border.scale);
+        *w = obj->cur->geometry.w - ((o->cur->border.l * o->cur->border.scale) + (o->cur->border.r * o->cur->border.scale));
         if (*w < 0) *w = 0;
-        *h = obj->cur.geometry.h - ((o->cur->border.t * o->cur->border.scale) + (o->cur->border.b * o->cur->border.scale));
+        *h = obj->cur->geometry.h - ((o->cur->border.t * o->cur->border.scale) + (o->cur->border.b * o->cur->border.scale));
         if (*h < 0) *h = 0;
      }
    return 1;
@@ -4975,14 +5015,14 @@ _evas_object_image_video_overlay_show(Evas_Object *eo_obj)
    Evas_Object_Protected_Data *obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS);
    Evas_Object_Image *o = eo_data_get(eo_obj, MY_CLASS);
 
-   if (obj->cur.cache.clip.x != obj->prev.cache.clip.x ||
-       obj->cur.cache.clip.y != obj->prev.cache.clip.y ||
+   if (obj->cur->cache.clip.x != obj->prev->cache.clip.x ||
+       obj->cur->cache.clip.y != obj->prev->cache.clip.y ||
        o->created || !o->video_visible)
-     o->pixels->video.move(o->pixels->video.data, eo_obj, &o->pixels->video, obj->cur.cache.clip.x, obj->cur.cache.clip.y);
-   if (obj->cur.cache.clip.w != obj->prev.cache.clip.w ||
-       obj->cur.cache.clip.h != obj->prev.cache.clip.h ||
+     o->pixels->video.move(o->pixels->video.data, eo_obj, &o->pixels->video, obj->cur->cache.clip.x, obj->cur->cache.clip.y);
+   if (obj->cur->cache.clip.w != obj->prev->cache.clip.w ||
+       obj->cur->cache.clip.h != obj->prev->cache.clip.h ||
        o->created || !o->video_visible)
-     o->pixels->video.resize(o->pixels->video.data, eo_obj, &o->pixels->video, obj->cur.cache.clip.w, obj->cur.cache.clip.h);
+     o->pixels->video.resize(o->pixels->video.data, eo_obj, &o->pixels->video, obj->cur->cache.clip.w, obj->cur->cache.clip.h);
    if (!o->video_visible || o->created)
      {
         o->pixels->video.show(o->pixels->video.data, eo_obj, &o->pixels->video);
index 97a0521..3d26765 100644 (file)
@@ -140,11 +140,17 @@ _line_xy_set(Eo *eo_obj, void *_pd, va_list *list)
         min_y = y2;
         max_y = y1;
      }
-   obj->cur.geometry.x = min_x;
-   obj->cur.geometry.y = min_y;
-   obj->cur.geometry.w = max_x - min_x + 2;
-   obj->cur.geometry.h = max_y - min_y + 2;
-////   obj->cur.cache.geometry.validity = 0;
+
+   EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+     {
+       state_write->geometry.x = min_x;
+       state_write->geometry.y = min_y;
+       state_write->geometry.w = max_x - min_x + 2;
+       state_write->geometry.h = max_y - min_y + 2;
+     }
+   EINA_COW_STATE_WRITE_END(obj, state_write, cur);
+
+////   obj->cur->cache.geometry.validity = 0;
    o->cur.x1 = x1 - min_x;
    o->cur.y1 = y1 - min_y;
    o->cur.x2 = x2 - min_x;
@@ -162,7 +168,7 @@ _line_xy_set(Eo *eo_obj, void *_pd, va_list *list)
             !evas_event_freezes_through(eo_obj, obj) &&
             !evas_object_is_source_invisible(eo_obj, obj))
           {
-             if ((is ^ was) && obj->cur.visible)
+             if ((is ^ was) && obj->cur->visible)
                evas_event_feed_mouse_move(obj->layer->evas->evas,
                                           obj->layer->evas->pointer.x,
                                           obj->layer->evas->pointer.y,
@@ -198,10 +204,10 @@ _line_xy_get(Eo *eo_obj, void *_pd, va_list *list)
    Evas_Coord *y2 = va_arg(*list, Evas_Coord *);
 
    Evas_Object_Protected_Data *obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS);
-   if (x1) *x1 = obj->cur.geometry.x + o->cur.x1;
-   if (y1) *y1 = obj->cur.geometry.y + o->cur.y1;
-   if (x2) *x2 = obj->cur.geometry.x + o->cur.x2;
-   if (y2) *y2 = obj->cur.geometry.y + o->cur.y2;
+   if (x1) *x1 = obj->cur->geometry.x + o->cur.x1;
+   if (y1) *y1 = obj->cur->geometry.y + o->cur.y1;
+   if (x2) *x2 = obj->cur->geometry.x + o->cur.x2;
+   if (y2) *y2 = obj->cur->geometry.y + o->cur.y2;
 }
 
 /* all nice and private */
@@ -209,20 +215,6 @@ static void
 evas_object_line_init(Evas_Object *eo_obj)
 {
    Evas_Object_Protected_Data *obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS);
-   /* set up default settings for this kind of object */
-   obj->cur.color.r = 255;
-   obj->cur.color.g = 255;
-   obj->cur.color.b = 255;
-   obj->cur.color.a = 255;
-   obj->cur.geometry.x = 0;
-   obj->cur.geometry.y = 0;
-   obj->cur.geometry.w = 0;
-   obj->cur.geometry.h = 0;
-   obj->cur.layer = 0;
-   obj->cur.anti_alias = EINA_TRUE;
-   obj->cur.render_op = EVAS_RENDER_BLEND;
-   /* set up object-specific settings */
-   obj->prev = obj->cur;
    /* set up methods (compulsory) */
    obj->func = &object_func;
    obj->type = o_type;
@@ -261,16 +253,16 @@ evas_object_line_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, vo
 
    obj->layer->evas->engine.func->context_color_set(output,
                                                     context,
-                                                    obj->cur.cache.clip.r,
-                                                    obj->cur.cache.clip.g,
-                                                    obj->cur.cache.clip.b,
-                                                    obj->cur.cache.clip.a);
+                                                    obj->cur->cache.clip.r,
+                                                    obj->cur->cache.clip.g,
+                                                    obj->cur->cache.clip.b,
+                                                    obj->cur->cache.clip.a);
    obj->layer->evas->engine.func->context_multiplier_unset(output,
                                                            context);
    obj->layer->evas->engine.func->context_anti_alias_set(output, context,
-                                                         obj->cur.anti_alias);
+                                                         obj->cur->anti_alias);
    obj->layer->evas->engine.func->context_render_op_set(output, context,
-                                                        obj->cur.render_op);
+                                                        obj->cur->render_op);
    obj->layer->evas->engine.func->line_draw(output,
                                             context,
                                             surface,
@@ -297,11 +289,11 @@ evas_object_line_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
    /* then when this is done the object needs to figure if it changed and */
    /* if so what and where and add the appropriate redraw lines */
    /* if someone is clipping this obj - go calculate the clipper */
-   if (obj->cur.clipper)
+   if (obj->cur->clipper)
      {
-       if (obj->cur.cache.clip.dirty)
-         evas_object_clip_recalc(obj->cur.eo_clipper, obj->cur.clipper);
-       obj->cur.clipper->func->render_pre(obj->cur.eo_clipper, obj->cur.clipper);
+       if (obj->cur->cache.clip.dirty)
+         evas_object_clip_recalc(obj->cur->eo_clipper, obj->cur->clipper);
+       obj->cur->clipper->func->render_pre(obj->cur->eo_clipper, obj->cur->clipper);
      }
    /* now figure what changed and add draw rects */
    /* if it just became visible or invisible */
@@ -323,10 +315,10 @@ evas_object_line_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
    /* clipper changed this is in addition to anything else for obj */
    evas_object_render_pre_clipper_change(&obj->layer->evas->clip_changes, eo_obj);
 
-   if ((obj->cur.color.r != obj->prev.color.r) ||
-       (obj->cur.color.g != obj->prev.color.g) ||
-       (obj->cur.color.b != obj->prev.color.b) ||
-       (obj->cur.color.a != obj->prev.color.a))
+   if ((obj->cur->color.r != obj->prev->color.r) ||
+       (obj->cur->color.g != obj->prev->color.g) ||
+       (obj->cur->color.b != obj->prev->color.b) ||
+       (obj->cur->color.a != obj->prev->color.a))
      changed_color = EINA_TRUE;
 
    /* if we restacked (layer or just within a layer) */
@@ -334,8 +326,8 @@ evas_object_line_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
    /* or if ii changed render op */
    /* or if it changed color */
    if ((obj->restack) ||
-       (obj->cur.anti_alias != obj->prev.anti_alias) ||
-       (obj->cur.render_op != obj->prev.render_op) ||
+       (obj->cur->anti_alias != obj->prev->anti_alias) ||
+       (obj->cur->render_op != obj->prev->render_op) ||
        (changed_color)
       )
      {
@@ -347,10 +339,10 @@ evas_object_line_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
    /* if it changed geometry - and obviously not visibility or color */
    /* calculate differences since we have a constant color fill */
    /* we really only need to update the differences */
-   if ((obj->cur.geometry.x != obj->prev.geometry.x) ||
-       (obj->cur.geometry.y != obj->prev.geometry.y) ||
-       (obj->cur.geometry.w != obj->prev.geometry.w) ||
-       (obj->cur.geometry.h != obj->prev.geometry.h) ||
+   if ((obj->cur->geometry.x != obj->prev->geometry.x) ||
+       (obj->cur->geometry.y != obj->prev->geometry.y) ||
+       (obj->cur->geometry.w != obj->prev->geometry.w) ||
+       (obj->cur->geometry.h != obj->prev->geometry.h) ||
        ((o->changed) &&
         ((o->cur.x1 != o->prev.x1) ||
          (o->cur.y1 != o->prev.y1) ||
@@ -439,12 +431,12 @@ evas_object_line_coords_recalc(Evas_Object *eo_obj, Evas_Object_Protected_Data *
 {
    Evas_Object_Line *o = eo_data_get(eo_obj, MY_CLASS);
 
-   o->cur.cache.x1 = obj->cur.geometry.x + o->cur.x1;
-   o->cur.cache.y1 = obj->cur.geometry.y + o->cur.y1;
-   o->cur.cache.x2 = obj->cur.geometry.x + o->cur.x2;
-   o->cur.cache.y2 = obj->cur.geometry.y + o->cur.y2;
-   o->cur.cache.object.w = obj->cur.geometry.w;
-   o->cur.cache.object.h = obj->cur.geometry.h;
+   o->cur.cache.x1 = obj->cur->geometry.x + o->cur.x1;
+   o->cur.cache.y1 = obj->cur->geometry.y + o->cur.y1;
+   o->cur.cache.x2 = obj->cur->geometry.x + o->cur.x2;
+   o->cur.cache.y2 = obj->cur->geometry.y + o->cur.y2;
+   o->cur.cache.object.w = obj->cur->geometry.w;
+   o->cur.cache.object.h = obj->cur->geometry.h;
 }
 
 static void
index 72afc8e..f740636 100644 (file)
@@ -30,24 +30,34 @@ static const Evas_Object_Proxy_Data default_proxy = {
 static const Evas_Object_Map_Data default_map = {
   { NULL, NULL, 0, 0 }, { NULL, NULL, 0, 0 }, NULL, 0, 0, NULL, NULL
 };
+static const Evas_Object_Protected_State default_state = {
+  NULL, NULL, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
+  { { 0, 0, 0, 0,  0, 0, 0, 0, EINA_FALSE, EINA_FALSE } },
+  { 255, 255, 255, 255 },
+  1.0, EVAS_RENDER_BLEND, EINA_FALSE, EINA_FALSE, EINA_FALSE, EINA_FALSE, EINA_FALSE, EINA_FALSE, EINA_FALSE
+};
 
 Eina_Cow *evas_object_proxy_cow = NULL;
 Eina_Cow *evas_object_map_cow = NULL;
+Eina_Cow *evas_object_state_cow = NULL;
 
 static Eina_Bool
 _init_cow(void)
 {
-   if (evas_object_map_cow && evas_object_proxy_cow) return EINA_TRUE;
+   if (evas_object_map_cow && evas_object_proxy_cow && evas_object_state_cow) return EINA_TRUE;
 
    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);
+   evas_object_state_cow = eina_cow_add("Evas Object State", sizeof (Evas_Object_Protected_State), 64, &default_state);
 
-   if (!(evas_object_map_cow && evas_object_proxy_cow))
+   if (!(evas_object_map_cow && evas_object_proxy_cow && evas_object_state_cow))
      {
         eina_cow_del(evas_object_proxy_cow);
         eina_cow_del(evas_object_map_cow);
+       eina_cow_del(evas_object_state_cow);
         evas_object_proxy_cow = NULL;
         evas_object_map_cow = NULL;
+       evas_object_state_cow = NULL;
         return EINA_FALSE;
      }
 
@@ -70,12 +80,12 @@ _constructor(Eo *eo_obj, void *_pd, va_list *list EINA_UNUSED)
         return;
      }
 
-   obj->cur.scale = 1.0;
-   obj->prev.scale = 1.0;
    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);
+   obj->cur = eina_cow_alloc(evas_object_state_cow);
+   obj->prev = eina_cow_alloc(evas_object_state_cow);
 }
 
 void
@@ -124,7 +134,7 @@ evas_object_cur_prev(Evas_Object *eo_obj)
           map_write->prev = map_write->cur;
         EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
      }
-   obj->prev = obj->cur;
+   eina_cow_memcpy(evas_object_state_cow, (const Eina_Cow_Data **) &obj->prev, obj->cur);
 }
 
 void
@@ -181,6 +191,8 @@ evas_object_free(Evas_Object *eo_obj, int clean_layer)
      }
    eina_cow_free(evas_object_proxy_cow, obj->proxy);
    eina_cow_free(evas_object_map_cow, obj->map);
+   eina_cow_free(evas_object_state_cow, obj->cur);
+   eina_cow_free(evas_object_state_cow, obj->prev);
    eo_manual_free(eo_obj);
 }
 
@@ -259,18 +271,18 @@ evas_object_render_pre_visible_change(Eina_Array *rects, Evas_Object *eo_obj, in
    if (is_v)
      {
         evas_add_rect(rects,
-                      obj->cur.cache.clip.x,
-                      obj->cur.cache.clip.y,
-                      obj->cur.cache.clip.w,
-                      obj->cur.cache.clip.h);
+                      obj->cur->cache.clip.x,
+                      obj->cur->cache.clip.y,
+                      obj->cur->cache.clip.w,
+                      obj->cur->cache.clip.h);
      }
    else
      {
         evas_add_rect(rects,
-                      obj->prev.cache.clip.x,
-                      obj->prev.cache.clip.y,
-                      obj->prev.cache.clip.w,
-                      obj->prev.cache.clip.h);
+                      obj->prev->cache.clip.x,
+                      obj->prev->cache.clip.y,
+                      obj->prev->cache.clip.w,
+                      obj->prev->cache.clip.h);
      }
 }
 
@@ -281,51 +293,51 @@ evas_object_render_pre_clipper_change(Eina_Array *rects, Evas_Object *eo_obj)
 
    if (!obj) return;
    if (obj->is_smart) return;
-   if (obj->cur.clipper == obj->prev.clipper) return;
-   if ((obj->cur.clipper) && (obj->prev.clipper))
+   if (obj->cur->clipper == obj->prev->clipper) return;
+   if ((obj->cur->clipper) && (obj->prev->clipper))
      {
         /* get difference rects between clippers */
         evas_rects_return_difference_rects(rects,
-                                           obj->cur.clipper->cur.cache.clip.x,
-                                           obj->cur.clipper->cur.cache.clip.y,
-                                           obj->cur.clipper->cur.cache.clip.w,
-                                           obj->cur.clipper->cur.cache.clip.h,
-                                           obj->prev.clipper->prev.cache.clip.x,
-                                           obj->prev.clipper->prev.cache.clip.y,
-                                           obj->prev.clipper->prev.cache.clip.w,
-                                           obj->prev.clipper->prev.cache.clip.h);
+                                           obj->cur->clipper->cur->cache.clip.x,
+                                           obj->cur->clipper->cur->cache.clip.y,
+                                           obj->cur->clipper->cur->cache.clip.w,
+                                           obj->cur->clipper->cur->cache.clip.h,
+                                           obj->prev->clipper->prev->cache.clip.x,
+                                           obj->prev->clipper->prev->cache.clip.y,
+                                           obj->prev->clipper->prev->cache.clip.w,
+                                           obj->prev->clipper->prev->cache.clip.h);
      }
-   else if (obj->cur.clipper)
+   else if (obj->cur->clipper)
      {
         evas_rects_return_difference_rects(rects,
-                                           obj->cur.geometry.x,
-                                           obj->cur.geometry.y,
-                                           obj->cur.geometry.w,
-                                           obj->cur.geometry.h,
-////   rl = evas_rects_return_difference_rects(obj->cur.cache.geometry.x,
-////                                           obj->cur.cache.geometry.y,
-////                                           obj->cur.cache.geometry.w,
-////                                           obj->cur.cache.geometry.h,
-                                           obj->cur.clipper->cur.cache.clip.x,
-                                           obj->cur.clipper->cur.cache.clip.y,
-                                           obj->cur.clipper->cur.cache.clip.w,
-                                           obj->cur.clipper->cur.cache.clip.h);
-     }
-   else if (obj->prev.clipper)
+                                           obj->cur->geometry.x,
+                                           obj->cur->geometry.y,
+                                           obj->cur->geometry.w,
+                                           obj->cur->geometry.h,
+////   rl = evas_rects_return_difference_rects(obj->cur->cache.geometry.x,
+////                                           obj->cur->cache.geometry.y,
+////                                           obj->cur->cache.geometry.w,
+////                                           obj->cur->cache.geometry.h,
+                                           obj->cur->clipper->cur->cache.clip.x,
+                                           obj->cur->clipper->cur->cache.clip.y,
+                                           obj->cur->clipper->cur->cache.clip.w,
+                                           obj->cur->clipper->cur->cache.clip.h);
+     }
+   else if (obj->prev->clipper)
      {
      evas_rects_return_difference_rects(rects,
-                                        obj->prev.geometry.x,
-                                        obj->prev.geometry.y,
-                                        obj->prev.geometry.w,
-                                        obj->prev.geometry.h,
-////   rl = evas_rects_return_difference_rects(obj->prev.cache.geometry.x,
-////                                           obj->prev.cache.geometry.y,
-////                                           obj->prev.cache.geometry.w,
-////                                           obj->prev.cache.geometry.h,
-                                        obj->prev.clipper->prev.cache.clip.x,
-                                        obj->prev.clipper->prev.cache.clip.y,
-                                        obj->prev.clipper->prev.cache.clip.w,
-                                        obj->prev.clipper->prev.cache.clip.h);
+                                        obj->prev->geometry.x,
+                                        obj->prev->geometry.y,
+                                        obj->prev->geometry.w,
+                                        obj->prev->geometry.h,
+////   rl = evas_rects_return_difference_rects(obj->prev->cache.geometry.x,
+////                                           obj->prev->cache.geometry.y,
+////                                           obj->prev->cache.geometry.w,
+////                                           obj->prev->cache.geometry.h,
+                                        obj->prev->clipper->prev->cache.clip.x,
+                                        obj->prev->clipper->prev->cache.clip.y,
+                                        obj->prev->clipper->prev->cache.clip.w,
+                                        obj->prev->clipper->prev->cache.clip.h);
      }
 }
 
@@ -335,34 +347,34 @@ evas_object_render_pre_prev_cur_add(Eina_Array *rects, Evas_Object *eo_obj EINA_
    if (!obj) return;
 
    evas_add_rect(rects,
-                 obj->cur.cache.clip.x,
-                 obj->cur.cache.clip.y,
-                 obj->cur.cache.clip.w,
-                 obj->cur.cache.clip.h);
+                 obj->cur->cache.clip.x,
+                 obj->cur->cache.clip.y,
+                 obj->cur->cache.clip.w,
+                 obj->cur->cache.clip.h);
    evas_add_rect(rects,
-                 obj->prev.cache.clip.x,
-                 obj->prev.cache.clip.y,
-                 obj->prev.cache.clip.w,
-                 obj->prev.cache.clip.h);
+                 obj->prev->cache.clip.x,
+                 obj->prev->cache.clip.y,
+                 obj->prev->cache.clip.w,
+                 obj->prev->cache.clip.h);
 /*
         evas_add_rect(rects,
-                      obj->cur.geometry.x,
-                      obj->cur.geometry.y,
-                      obj->cur.geometry.w,
-                      obj->cur.geometry.h);
-////       obj->cur.cache.geometry.x,
-////       obj->cur.cache.geometry.y,
-////       obj->cur.cache.geometry.w,
-////       obj->cur.cache.geometry.h);
+                      obj->cur->geometry.x,
+                      obj->cur->geometry.y,
+                      obj->cur->geometry.w,
+                      obj->cur->geometry.h);
+////       obj->cur->cache.geometry.x,
+////       obj->cur->cache.geometry.y,
+////       obj->cur->cache.geometry.w,
+////       obj->cur->cache.geometry.h);
         evas_add_rect(rects,
-                      obj->prev.geometry.x,
-                      obj->prev.geometry.y,
-                      obj->prev.geometry.w,
-                      obj->prev.geometry.h);
-////       obj->prev.cache.geometry.x,
-////       obj->prev.cache.geometry.y,
-////       obj->prev.cache.geometry.w,
-////       obj->prev.cache.geometry.h);
+                      obj->prev->geometry.x,
+                      obj->prev->geometry.y,
+                      obj->prev->geometry.w,
+                      obj->prev->geometry.h);
+////       obj->prev->cache.geometry.x,
+////       obj->prev->cache.geometry.y,
+////       obj->prev->cache.geometry.w,
+////       obj->prev->cache.geometry.h);
 */
 }
 
@@ -403,10 +415,10 @@ evas_object_render_pre_effect_updates(Eina_Array *rects, Evas_Object *eo_obj, in
              w = r->w;
              h = r->h;
              RECTS_CLIP_TO_RECT(x, y, w, h,
-                                obj->cur.cache.clip.x,
-                                obj->cur.cache.clip.y,
-                                obj->cur.cache.clip.w,
-                                obj->cur.cache.clip.h);
+                                obj->cur->cache.clip.x,
+                                obj->cur->cache.clip.y,
+                                obj->cur->cache.clip.w,
+                                obj->cur->cache.clip.h);
              if ((w > 0) && (h > 0))
                obj->layer->evas->engine.func->output_redraws_rect_add(obj->layer->evas->engine.data.output,
                                                                       x, y, w, h);
@@ -416,10 +428,10 @@ evas_object_render_pre_effect_updates(Eina_Array *rects, Evas_Object *eo_obj, in
              w = r->w;
              h = r->h;
              RECTS_CLIP_TO_RECT(x, y, w, h,
-                                obj->prev.cache.clip.x,
-                                obj->prev.cache.clip.y,
-                                obj->prev.cache.clip.w,
-                                obj->prev.cache.clip.h);
+                                obj->prev->cache.clip.x,
+                                obj->prev->cache.clip.y,
+                                obj->prev->cache.clip.w,
+                                obj->prev->cache.clip.h);
              if ((w > 0) && (h > 0))
                obj->layer->evas->engine.func->output_redraws_rect_add(obj->layer->evas->engine.data.output,
                                                                       x, y, w, h);
@@ -429,7 +441,7 @@ evas_object_render_pre_effect_updates(Eina_Array *rects, Evas_Object *eo_obj, in
           {
              Evas_Object_Protected_Data *clipper;
 
-             clipper = obj->cur.clipper;
+             clipper = obj->cur->clipper;
              while (clipper)
                {
                   EINA_LIST_FOREACH(clipper->clip.changes, l, r)
@@ -437,25 +449,25 @@ evas_object_render_pre_effect_updates(Eina_Array *rects, Evas_Object *eo_obj, in
                        /* get updates and clip to current clip */
                        x = r->x; y = r->y; w = r->w; h = r->h;
                        RECTS_CLIP_TO_RECT(x, y, w, h,
-                                          obj->cur.cache.clip.x,
-                                          obj->cur.cache.clip.y,
-                                          obj->cur.cache.clip.w,
-                                          obj->cur.cache.clip.h);
+                                          obj->cur->cache.clip.x,
+                                          obj->cur->cache.clip.y,
+                                          obj->cur->cache.clip.w,
+                                          obj->cur->cache.clip.h);
                        if ((w > 0) && (h > 0))
                          obj->layer->evas->engine.func->output_redraws_rect_add(obj->layer->evas->engine.data.output,
                                                                                 x, y, w, h);
                        /* get updates and clip to previous clip */
                        x = r->x; y = r->y; w = r->w; h = r->h;
                        RECTS_CLIP_TO_RECT(x, y, w, h,
-                                          obj->prev.cache.clip.x,
-                                          obj->prev.cache.clip.y,
-                                          obj->prev.cache.clip.w,
-                                          obj->prev.cache.clip.h);
+                                          obj->prev->cache.clip.x,
+                                          obj->prev->cache.clip.y,
+                                          obj->prev->cache.clip.w,
+                                          obj->prev->cache.clip.h);
                        if ((w > 0) && (h > 0))
                          obj->layer->evas->engine.func->output_redraws_rect_add(obj->layer->evas->engine.data.output,
                                                                                 x, y, w, h);
                     }
-                  clipper = clipper->cur.clipper;
+                  clipper = clipper->cur->clipper;
                }
           }
      }
@@ -479,10 +491,10 @@ evas_object_was_in_output_rect(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Prot
    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,
-                        obj->prev.cache.clip.y,
-                        obj->prev.cache.clip.w,
-                        obj->prev.cache.clip.h)))
+                        obj->prev->cache.clip.x,
+                        obj->prev->cache.clip.y,
+                        obj->prev->cache.clip.w,
+                        obj->prev->cache.clip.h)))
      return 1;
    return 0;
 }
@@ -491,7 +503,7 @@ int
 evas_object_was_opaque(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
 {
    if (obj->is_smart) return 0;
-   if (obj->prev.cache.clip.a == 255)
+   if (obj->prev->cache.clip.a == 255)
      {
         if (obj->func->was_opaque)
           return obj->func->was_opaque(eo_obj, obj);
@@ -627,7 +639,7 @@ _destructor(Eo *eo_obj, void *_pd, va_list *list EINA_UNUSED)
      evas_object_clip_unset(obj->clip.clipees->data);
    while (obj->proxy->proxies)
      evas_object_image_source_unset(obj->proxy->proxies->data);
-   if (obj->cur.clipper) evas_object_clip_unset(eo_obj);
+   if (obj->cur->clipper) evas_object_clip_unset(eo_obj);
    evas_object_map_set(eo_obj, NULL);
    if (obj->is_smart) evas_object_smart_del(eo_obj);
    _evas_object_event_new();
@@ -659,25 +671,25 @@ evas_object_update_bounding_box(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Pro
 
    if (obj->is_smart)
      {
-        x = obj->cur.bounding_box.x;
-        y = obj->cur.bounding_box.y;
-        w = obj->cur.bounding_box.w;
-        h = obj->cur.bounding_box.h;
-        px = obj->prev.bounding_box.x;
-        py = obj->prev.bounding_box.y;
-        pw = obj->prev.bounding_box.w;
-        ph = obj->prev.bounding_box.h;
+        x = obj->cur->bounding_box.x;
+        y = obj->cur->bounding_box.y;
+        w = obj->cur->bounding_box.w;
+        h = obj->cur->bounding_box.h;
+        px = obj->prev->bounding_box.x;
+        py = obj->prev->bounding_box.y;
+        pw = obj->prev->bounding_box.w;
+        ph = obj->prev->bounding_box.h;
      }
    else
      {
-        x = obj->cur.geometry.x;
-        y = obj->cur.geometry.y;
-        w = obj->cur.geometry.w;
-        h = obj->cur.geometry.h;
-        px = obj->prev.geometry.x;
-        py = obj->prev.geometry.y;
-        pw = obj->prev.geometry.w;
-        ph = obj->prev.geometry.h;
+        x = obj->cur->geometry.x;
+        y = obj->cur->geometry.y;
+        w = obj->cur->geometry.w;
+        h = obj->cur->geometry.h;
+        px = obj->prev->geometry.x;
+        py = obj->prev->geometry.y;
+        pw = obj->prev->geometry.w;
+        ph = obj->prev->geometry.h;
      }
 
    /* We are not yet trying to find the smallest bounding box, but we want to find a good approximation quickly.
@@ -686,56 +698,77 @@ evas_object_update_bounding_box(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Pro
 
    Evas_Object_Protected_Data *smart_parent = eo_data_get(obj->smart.parent, MY_CLASS);
    if (!smart_parent) return;
-   if (smart_parent->cur.valid_bounding_box)
+
+   if (smart_parent->cur->valid_bounding_box)
      {
         /* Update left limit */
-        if (noclip && x < smart_parent->cur.bounding_box.x)
+        if (noclip && x < smart_parent->cur->bounding_box.x)
           {
-             smart_parent->cur.bounding_box.w += smart_parent->cur.bounding_box.x - x;
-             smart_parent->cur.bounding_box.x = x;
+             EINA_COW_STATE_WRITE_BEGIN(smart_parent, state_write, cur)
+               {
+                  state_write->bounding_box.w += state_write->bounding_box.x - x;
+                  state_write->bounding_box.x = x;
+               }
+             EINA_COW_STATE_WRITE_END(smart_parent, state_write, cur);
+
              propagate = EINA_TRUE;
           }
-        else if ((px == smart_parent->prev.bounding_box.x && x > smart_parent->cur.bounding_box.x)
-                 || (!noclip && x == smart_parent->cur.bounding_box.x))
+        else if ((px == smart_parent->prev->bounding_box.x && x > smart_parent->cur->bounding_box.x)
+                 || (!noclip && x == smart_parent->cur->bounding_box.x))
           {
              computeminmax = EINA_TRUE;
           }
 
         /* Update top limit */
-        if (noclip && y < smart_parent->cur.bounding_box.y)
+        if (noclip && y < smart_parent->cur->bounding_box.y)
           {
-             smart_parent->cur.bounding_box.h += smart_parent->cur.bounding_box.x - x;
-             smart_parent->cur.bounding_box.y = y;
+             EINA_COW_STATE_WRITE_BEGIN(smart_parent, state_write, cur)
+               {
+                  state_write->bounding_box.h += state_write->bounding_box.x - x;
+                  state_write->bounding_box.y = y;
+               }
+             EINA_COW_STATE_WRITE_END(smart_parent, state_write, cur);
+
              propagate = EINA_TRUE;
           }
-        else if ((py == smart_parent->prev.bounding_box.y && y  > smart_parent->cur.bounding_box.y)
-                 || (!noclip && y == smart_parent->cur.bounding_box.y))
+        else if ((py == smart_parent->prev->bounding_box.y && y  > smart_parent->cur->bounding_box.y)
+                 || (!noclip && y == smart_parent->cur->bounding_box.y))
           {
              computeminmax = EINA_TRUE;
           }
 
         /* Update right limit */
-        if (noclip && x + w > smart_parent->cur.bounding_box.x + smart_parent->cur.bounding_box.w)
+        if (noclip && x + w > smart_parent->cur->bounding_box.x + smart_parent->cur->bounding_box.w)
           {
-             smart_parent->cur.bounding_box.w = x + w - smart_parent->cur.bounding_box.x;
+             EINA_COW_STATE_WRITE_BEGIN(smart_parent, state_write, cur)
+               {
+                  state_write->bounding_box.w = x + w - state_write->bounding_box.x;
+               }
+             EINA_COW_STATE_WRITE_END(smart_parent, state_write, cur);
+             
              propagate = EINA_TRUE;
           }
-        else if ((px + pw == smart_parent->prev.bounding_box.x + smart_parent->prev.bounding_box.w &&
-                  x + w < smart_parent->cur.bounding_box.x + smart_parent->cur.bounding_box.w)
-                 || (!noclip && x + w == smart_parent->cur.bounding_box.x + smart_parent->cur.bounding_box.w))
+        else if ((px + pw == smart_parent->prev->bounding_box.x + smart_parent->prev->bounding_box.w &&
+                  x + w < smart_parent->cur->bounding_box.x + smart_parent->cur->bounding_box.w)
+                 || (!noclip && x + w == smart_parent->cur->bounding_box.x + smart_parent->cur->bounding_box.w))
           {
              computeminmax = EINA_TRUE;
           }
 
         /* Update bottom limit */
-        if (noclip && y + h > smart_parent->cur.bounding_box.y + smart_parent->cur.bounding_box.h)
+        if (noclip && y + h > smart_parent->cur->bounding_box.y + smart_parent->cur->bounding_box.h)
           {
-             smart_parent->cur.bounding_box.h = y + h - smart_parent->cur.bounding_box.y;
+             EINA_COW_STATE_WRITE_BEGIN(smart_parent, state_write, cur)
+               {
+                  state_write->bounding_box.h = y + h - state_write->bounding_box.y;
+               }
+             EINA_COW_STATE_WRITE_END(smart_parent, state_write, cur);
+
              propagate = EINA_TRUE;
           }
-        else if ((py + ph == smart_parent->prev.bounding_box.y + smart_parent->prev.bounding_box.h &&
-                  y + h < smart_parent->cur.bounding_box.y + smart_parent->cur.bounding_box.h) ||
-                 (!noclip && y + h == smart_parent->cur.bounding_box.y + smart_parent->cur.bounding_box.h))
+        else if ((py + ph == smart_parent->prev->bounding_box.y + smart_parent->prev->bounding_box.h &&
+                  y + h < smart_parent->cur->bounding_box.y + smart_parent->cur->bounding_box.h) ||
+                 (!noclip && y + h == smart_parent->cur->bounding_box.y + smart_parent->cur->bounding_box.h))
           {
              computeminmax = EINA_TRUE;
           }
@@ -749,11 +782,16 @@ evas_object_update_bounding_box(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Pro
      {
         if (noclip)
           {
-             smart_parent->cur.bounding_box.x = x;
-             smart_parent->cur.bounding_box.y = y;
-             smart_parent->cur.bounding_box.w = w;
-             smart_parent->cur.bounding_box.h = h;
-             smart_parent->cur.valid_bounding_box = EINA_TRUE;
+             EINA_COW_STATE_WRITE_BEGIN(smart_parent, state_write, cur)
+               {
+                  state_write->bounding_box.x = x;
+                  state_write->bounding_box.y = y;
+                  state_write->bounding_box.w = w;
+                  state_write->bounding_box.h = h;
+                  state_write->valid_bounding_box = EINA_TRUE;
+               }
+             EINA_COW_STATE_WRITE_END(smart_parent, state_write, cur);
+
              propagate = EINA_TRUE;
           }
      }
@@ -810,7 +848,7 @@ _position_set(Eo *eo_obj, void *_pd, va_list *list)
         return;
      }
 
-   if ((obj->cur.geometry.x == nx) && (obj->cur.geometry.y == ny)) return;
+   if ((obj->cur->geometry.x == nx) && (obj->cur->geometry.y == ny)) return;
 
    if (!(obj->layer->evas->is_frozen))
      {
@@ -829,12 +867,16 @@ _position_set(Eo *eo_obj, void *_pd, va_list *list)
         eo_do(eo_obj, evas_obj_smart_move(nx, ny));
      }
 
-   obj->cur.geometry.x = nx;
-   obj->cur.geometry.y = ny;
+   EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+     {
+        state_write->geometry.x = nx;
+        state_write->geometry.y = ny;
+     }
+   EINA_COW_STATE_WRITE_END(obj, state_write, cur);
 
    evas_object_update_bounding_box(eo_obj, obj);
 
-////   obj->cur.cache.geometry.validity = 0;
+////   obj->cur->cache.geometry.validity = 0;
    obj->changed_move = EINA_TRUE;
    evas_object_change(eo_obj, obj);
    evas_object_clip_dirty(eo_obj, obj);
@@ -849,7 +891,7 @@ _position_set(Eo *eo_obj, void *_pd, va_list *list)
                   is = evas_object_is_in_output_rect(eo_obj, obj,
                                                      obj->layer->evas->pointer.x,
                                                      obj->layer->evas->pointer.y, 1, 1);
-                  if ((is ^ was) && obj->cur.visible)
+                  if ((is ^ was) && obj->cur->visible)
                     evas_event_feed_mouse_move(obj->layer->evas->evas,
                                                obj->layer->evas->pointer.x,
                                                obj->layer->evas->pointer.y,
@@ -893,7 +935,7 @@ _size_set(Eo *eo_obj, void *_pd, va_list *list)
         return;
      }
 
-   if ((obj->cur.geometry.w == w) && (obj->cur.geometry.h == h)) return;
+   if ((obj->cur->geometry.w == w) && (obj->cur->geometry.h == h)) return;
 
    if (!(obj->layer->evas->is_frozen))
      {
@@ -912,12 +954,16 @@ _size_set(Eo *eo_obj, void *_pd, va_list *list)
         eo_do(eo_obj, evas_obj_smart_resize(w, h));
      }
 
-   obj->cur.geometry.w = w;
-   obj->cur.geometry.h = h;
+   EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+     {
+        state_write->geometry.w = w;
+        state_write->geometry.h = h;
+     }
+   EINA_COW_STATE_WRITE_END(obj, state_write, cur);
 
    evas_object_update_bounding_box(eo_obj, obj);
 
-////   obj->cur.cache.geometry.validity = 0;
+////   obj->cur->cache.geometry.validity = 0;
    evas_object_change(eo_obj, obj);
    evas_object_clip_dirty(eo_obj, obj);
    obj->doing.in_resize--;
@@ -935,7 +981,7 @@ _size_set(Eo *eo_obj, void *_pd, va_list *list)
                   is = evas_object_is_in_output_rect(eo_obj, obj,
                                                      obj->layer->evas->pointer.x,
                                                      obj->layer->evas->pointer.y, 1, 1);
-                  if ((is ^ was) && (obj->cur.visible))
+                  if ((is ^ was) && (obj->cur->visible))
                     evas_event_feed_mouse_move(obj->layer->evas->evas,
                                                obj->layer->evas->pointer.x,
                                                obj->layer->evas->pointer.y,
@@ -974,8 +1020,8 @@ _position_get(Eo *eo_obj EINA_UNUSED, void *_pd, va_list *list)
         return;
      }
 
-   nx = obj->cur.geometry.x;
-   ny = obj->cur.geometry.y;
+   nx = obj->cur->geometry.x;
+   ny = obj->cur->geometry.y;
 
    evas = obj->layer->evas;
 
@@ -1006,8 +1052,8 @@ _size_get(Eo *eo_obj EINA_UNUSED, void *_pd, va_list *list)
         return;
      }
 
-   if (w) *w = obj->cur.geometry.w;
-   if (h) *h = obj->cur.geometry.h;
+   if (w) *w = obj->cur->geometry.w;
+   if (h) *h = obj->cur->geometry.h;
 }
 
 static void
@@ -1484,11 +1530,16 @@ _show(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
      {
         eo_do(eo_obj, evas_obj_smart_show());
      }
-   if (obj->cur.visible)
+   if (obj->cur->visible)
      {
         return;
      }
-   obj->cur.visible = 1;
+   EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+     {
+        state_write->visible = 1;
+     }
+   EINA_COW_STATE_WRITE_END(obj, state_write, cur);
+
    evas_object_change(eo_obj, obj);
    evas_object_clip_dirty(eo_obj, obj);
    if (!(obj->layer->evas->is_frozen))
@@ -1528,11 +1579,17 @@ _hide(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
      {
         eo_do(eo_obj, evas_obj_smart_hide());
      }
-   if (!obj->cur.visible)
+   if (!obj->cur->visible)
      {
         return;
      }
-   obj->cur.visible = 0;
+
+   EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+     {
+        state_write->visible = 0;
+     }
+   EINA_COW_STATE_WRITE_END(obj, state_write, cur);
+
    evas_object_change(eo_obj, obj);
    evas_object_clip_dirty(eo_obj, obj);
    if (!(obj->layer->evas->is_frozen))
@@ -1632,7 +1689,7 @@ _visible_get(Eo *eo_obj EINA_UNUSED, void *_pd, va_list *list)
         return;
      }
 
-   if (visible) *visible = obj->cur.visible;
+   if (visible) *visible = obj->cur->visible;
 }
 
 EAPI void
@@ -1680,16 +1737,28 @@ _color_set(Eo *eo_obj, void *_pd, va_list *list)
      {
         eo_do(eo_obj, evas_obj_smart_color_set(r, g, b, a));
      }
-   if ((obj->cur.color.r == r) &&
-       (obj->cur.color.g == g) &&
-       (obj->cur.color.b == b) &&
-       (obj->cur.color.a == a)) return;
-   obj->cur.color.r = r;
-   obj->cur.color.g = g;
-   obj->cur.color.b = b;
+   if ((obj->cur->color.r == r) &&
+       (obj->cur->color.g == g) &&
+       (obj->cur->color.b == b) &&
+       (obj->cur->color.a == a)) return;
+
+   EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+     {
+        state_write->color.r = r;
+        state_write->color.g = g;
+        state_write->color.b = b;
+     }
+   EINA_COW_STATE_WRITE_END(obj, state_write, cur);
+
    evas_object_clip_dirty(eo_obj, obj);
-   if ((obj->cur.color.a == 0) && (a == 0) && (obj->cur.render_op == EVAS_RENDER_BLEND)) return;
-   obj->cur.color.a = a;
+   if ((obj->cur->color.a == 0) && (a == 0) && (obj->cur->render_op == EVAS_RENDER_BLEND)) return;
+
+   EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+     {
+        state_write->color.a = a;
+     }
+   EINA_COW_STATE_WRITE_END(obj, state_write, cur);
+
    obj->changed_color = EINA_TRUE;
    evas_object_change(eo_obj, obj);
 }
@@ -1718,10 +1787,10 @@ _color_get(Eo *eo_obj EINA_UNUSED, void *_pd, va_list *list)
         if (r) *r = 0; if (g) *g = 0; if (b) *b = 0; if (a) *a = 0;
         return;
      }
-   if (r) *r = obj->cur.color.r;
-   if (g) *g = obj->cur.color.g;
-   if (b) *b = obj->cur.color.b;
-   if (a) *a = obj->cur.color.a;
+   if (r) *r = obj->cur->color.r;
+   if (g) *g = obj->cur->color.g;
+   if (b) *b = obj->cur->color.b;
+   if (a) *a = obj->cur->color.a;
 }
 
 EAPI void
@@ -1741,8 +1810,14 @@ _anti_alias_set(Eo *eo_obj, void *_pd, va_list *list)
 
    if (obj->delete_me) return;
    anti_alias = !!anti_alias;
-   if (obj->cur.anti_alias == anti_alias)return;
-   obj->cur.anti_alias = anti_alias;
+   if (obj->cur->anti_alias == anti_alias)return;
+
+   EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+     {
+        state_write->anti_alias = anti_alias;
+     }
+   EINA_COW_STATE_WRITE_END(obj, state_write, cur);
+
    evas_object_change(eo_obj, obj);
 }
 
@@ -1769,7 +1844,7 @@ _anti_alias_get(Eo *eo_obj EINA_UNUSED, void *_pd, va_list *list)
         return;
      }
 
-   if (anti_alias) *anti_alias = obj->cur.anti_alias;
+   if (anti_alias) *anti_alias = obj->cur->anti_alias;
 }
 
 EAPI void
@@ -1788,8 +1863,14 @@ _scale_set(Eo *eo_obj, void *_pd, va_list *list)
 
    double scale = va_arg(*list, double);
    if (obj->delete_me) return;
-   if (obj->cur.scale == scale) return;
-   obj->cur.scale = scale;
+   if (obj->cur->scale == scale) return;
+
+   EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+     {
+        state_write->scale = scale;
+     }
+   EINA_COW_STATE_WRITE_END(obj, state_write, cur);
+
    evas_object_change(eo_obj, obj);
    if (obj->func->scale_update) obj->func->scale_update(eo_obj);
 }
@@ -1816,7 +1897,7 @@ _scale_get(Eo *eo_obj EINA_UNUSED, void *_pd, va_list *list)
         if (scale) *scale = 1.0;
         return;
      }
-   if (scale) *scale = obj->cur.scale;
+   if (scale) *scale = obj->cur->scale;
 }
 
 EAPI void
@@ -1835,8 +1916,14 @@ _render_op_set(Eo *eo_obj, void *_pd, va_list *list)
 
    Evas_Render_Op render_op = va_arg(*list, Evas_Render_Op);
    if (obj->delete_me) return;
-   if (obj->cur.render_op == render_op) return;
-   obj->cur.render_op = render_op;
+   if (obj->cur->render_op == render_op) return;
+
+   EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+     {
+        state_write->render_op = render_op;
+     }
+   EINA_COW_STATE_WRITE_END(obj, state_write, cur);
+
    evas_object_change(eo_obj, obj);
 }
 
@@ -1862,7 +1949,7 @@ _render_op_get(Eo *eo_obj EINA_UNUSED, void *_pd, va_list *list)
         if (render_op) *render_op = EVAS_RENDER_BLEND;
         return;
      }
-   if (render_op) *render_op = obj->cur.render_op;
+   if (render_op) *render_op = obj->cur->render_op;
 }
 
 EAPI Evas *
@@ -2045,7 +2132,7 @@ _canvas_object_top_at_xy_get(Eo *eo_e EINA_UNUSED, void *_pd, va_list *list)
              if ((!include_pass_events_objects) &&
                  (evas_event_passes_through(eo_obj, obj))) continue;
              if (evas_object_is_source_invisible(eo_obj, obj)) continue;
-             if ((!include_hidden_objects) && (!obj->cur.visible)) continue;
+             if ((!include_hidden_objects) && (!obj->cur->visible)) continue;
              evas_object_clip_recalc(eo_obj, obj);
              if ((evas_object_is_in_output_rect(eo_obj, obj, xx, yy, 1, 1)) &&
                  (!obj->clip.clipees))
@@ -2117,7 +2204,7 @@ _canvas_object_top_in_rectangle_get(Eo *eo_e EINA_UNUSED, void *_pd, va_list *li
              if ((!include_pass_events_objects) &&
                  (evas_event_passes_through(eo_obj, obj))) continue;
              if (evas_object_is_source_invisible(eo_obj, obj)) continue;
-             if ((!include_hidden_objects) && (!obj->cur.visible)) continue;
+             if ((!include_hidden_objects) && (!obj->cur->visible)) continue;
              evas_object_clip_recalc(eo_obj, obj);
              if ((evas_object_is_in_output_rect(eo_obj, obj, xx, yy, ww, hh)) &&
                  (!obj->clip.clipees))
@@ -2172,7 +2259,7 @@ _canvas_objects_at_xy_get(Eo *eo_e EINA_UNUSED, void *_pd, va_list *list)
              if ((!include_pass_events_objects) &&
                    (evas_event_passes_through(eo_obj, obj))) continue;
              if (evas_object_is_source_invisible(eo_obj, obj)) continue;
-             if ((!include_hidden_objects) && (!obj->cur.visible)) continue;
+             if ((!include_hidden_objects) && (!obj->cur->visible)) continue;
              evas_object_clip_recalc(eo_obj, obj);
              if ((evas_object_is_in_output_rect(eo_obj, obj, xx, yy, 1, 1)) &&
                  (!obj->clip.clipees))
@@ -2244,7 +2331,7 @@ _canvas_objects_in_rectangle_get(Eo *eo_e EINA_UNUSED, void *_pd, va_list *list)
              if ((!include_pass_events_objects) &&
                  (evas_event_passes_through(eo_obj, obj))) continue;
              if (evas_object_is_source_invisible(eo_obj, obj)) continue;
-             if ((!include_hidden_objects) && (!obj->cur.visible)) continue;
+             if ((!include_hidden_objects) && (!obj->cur->visible)) continue;
              evas_object_clip_recalc(eo_obj, obj);
              if ((evas_object_is_in_output_rect(eo_obj, obj, xx, yy, ww, hh)) &&
                  (!obj->clip.clipees))
index 298ed4a..2172275 100644 (file)
@@ -129,8 +129,8 @@ _polygon_point_add(Eo *eo_obj, void *_pd, va_list *list)
      }
    if (!o->points)
      {
-        o->offset.x = obj->cur.geometry.x;
-        o->offset.y = obj->cur.geometry.y;
+        o->offset.x = obj->cur->geometry.x;
+        o->offset.y = obj->cur->geometry.y;
      }
    else
      {
@@ -151,35 +151,44 @@ _polygon_point_add(Eo *eo_obj, void *_pd, va_list *list)
 
    if (!o->points)
      {
-        obj->cur.geometry.x = p->x;
-        obj->cur.geometry.y = p->y;
-        obj->cur.geometry.w = 2;
-        obj->cur.geometry.h = 2;
+        EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+          {
+             state_write->geometry.x = p->x;
+             state_write->geometry.y = p->y;
+             state_write->geometry.w = 2;
+             state_write->geometry.h = 2;
+          }
+        EINA_COW_STATE_WRITE_END(obj, state_write, cur);
      }
    else
      {
-        if (p->x < obj->cur.geometry.x) min_x = p->x;
-        else min_x = obj->cur.geometry.x;
-        if (p->x > (obj->cur.geometry.x + obj->cur.geometry.w - 2))
+        if (p->x < obj->cur->geometry.x) min_x = p->x;
+        else min_x = obj->cur->geometry.x;
+        if (p->x > (obj->cur->geometry.x + obj->cur->geometry.w - 2))
           max_x = p->x;
-        else max_x = obj->cur.geometry.x + obj->cur.geometry.w - 2;
-        if (p->y < obj->cur.geometry.y) min_y = p->y;
-        else min_y = obj->cur.geometry.y;
-        if (p->y > (obj->cur.geometry.y + obj->cur.geometry.h - 2))
+        else max_x = obj->cur->geometry.x + obj->cur->geometry.w - 2;
+        if (p->y < obj->cur->geometry.y) min_y = p->y;
+        else min_y = obj->cur->geometry.y;
+        if (p->y > (obj->cur->geometry.y + obj->cur->geometry.h - 2))
           max_y = p->y;
-        else max_y = obj->cur.geometry.y + obj->cur.geometry.h - 2;
-        obj->cur.geometry.x = min_x;
-        obj->cur.geometry.y = min_y;
-        obj->cur.geometry.w = max_x - min_x + 2;
-        obj->cur.geometry.h = max_y - min_y + 2;
+        else max_y = obj->cur->geometry.y + obj->cur->geometry.h - 2;
+
+        EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+          {
+             state_write->geometry.x = min_x;
+             state_write->geometry.y = min_y;
+             state_write->geometry.w = max_x - min_x + 2;
+             state_write->geometry.h = max_y - min_y + 2;
+          }
+        EINA_COW_STATE_WRITE_END(obj, state_write, cur);
      }
    o->points = eina_list_append(o->points, p);
 
-   o->geometry = obj->cur.geometry;
+   o->geometry = obj->cur->geometry;
    o->offset.x = 0;
    o->offset.y = 0;
 
-   ////   obj->cur.cache.geometry.validity = 0;
+   ////   obj->cur->cache.geometry.validity = 0;
    o->changed = EINA_TRUE;
    evas_object_change(eo_obj, obj);
    evas_object_clip_dirty(eo_obj, obj);
@@ -193,7 +202,7 @@ _polygon_point_add(Eo *eo_obj, void *_pd, va_list *list)
             !evas_event_freezes_through(eo_obj, obj) &&
             !evas_object_is_source_invisible(eo_obj, obj))
           {
-             if ((is ^ was) && obj->cur.visible)
+             if ((is ^ was) && obj->cur->visible)
                evas_event_feed_mouse_move(obj->layer->evas->evas,
                                           obj->layer->evas->pointer.x,
                                           obj->layer->evas->pointer.y,
@@ -229,11 +238,17 @@ _polygon_points_clear(Eo *eo_obj, void *_pd, va_list *list EINA_UNUSED)
         free(o->points->data);
         o->points = eina_list_remove(o->points, o->points->data);
      }
-   obj->cur.geometry.x = 0;
-   obj->cur.geometry.y = 0;
-   obj->cur.geometry.w = 0;
-   obj->cur.geometry.h = 0;
-   ////   obj->cur.cache.geometry.validity = 0;
+
+   EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+     {
+        state_write->geometry.x = 0;
+        state_write->geometry.y = 0;
+        state_write->geometry.w = 0;
+        state_write->geometry.h = 0;
+     }
+   EINA_COW_STATE_WRITE_END(obj, state_write, cur);
+
+   ////   obj->cur->cache.geometry.validity = 0;
    o->changed = EINA_TRUE;
    evas_object_change(eo_obj, obj);
    evas_object_clip_dirty(eo_obj, obj);
@@ -241,7 +256,7 @@ _polygon_points_clear(Eo *eo_obj, void *_pd, va_list *list EINA_UNUSED)
    is = evas_object_is_in_output_rect(eo_obj, obj,
                                       obj->layer->evas->pointer.x,
                                       obj->layer->evas->pointer.y, 1, 1);
-   if ((is || was) && obj->cur.visible)
+   if ((is || was) && obj->cur->visible)
      evas_event_feed_mouse_move(obj->layer->evas->evas,
                                 obj->layer->evas->pointer.x,
                                 obj->layer->evas->pointer.y,
@@ -256,18 +271,6 @@ static void
 evas_object_polygon_init(Evas_Object *eo_obj)
 {
    Evas_Object_Protected_Data *obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS);
-   /* set up default settings for this kind of object */
-   obj->cur.color.r = 255;
-   obj->cur.color.g = 255;
-   obj->cur.color.b = 255;
-   obj->cur.color.a = 255;
-   obj->cur.geometry.x = 0;
-   obj->cur.geometry.y = 0;
-   obj->cur.geometry.w = 0;
-   obj->cur.geometry.h = 0;
-   obj->cur.layer = 0;
-   /* set up object-specific settings */
-   obj->prev = obj->cur;
    /* set up methods (compulsory) */
    obj->func = &object_func;
    obj->type = o_type;
@@ -306,14 +309,14 @@ evas_object_polygon_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj,
    /* render object to surface with context, and offxet by x,y */
    obj->layer->evas->engine.func->context_color_set(output,
                                                     context,
-                                                    obj->cur.cache.clip.r,
-                                                    obj->cur.cache.clip.g,
-                                                    obj->cur.cache.clip.b,
-                                                    obj->cur.cache.clip.a);
+                                                    obj->cur->cache.clip.r,
+                                                    obj->cur->cache.clip.g,
+                                                    obj->cur->cache.clip.b,
+                                                    obj->cur->cache.clip.a);
    obj->layer->evas->engine.func->context_multiplier_unset(output,
                                                            context);
    obj->layer->evas->engine.func->context_render_op_set(output, context,
-                                                        obj->cur.render_op);
+                                                        obj->cur->render_op);
    if (o->changed)
      {
         o->engine_data = obj->layer->evas->engine.func->polygon_points_clear(obj->layer->evas->engine.data.output,
@@ -354,11 +357,11 @@ evas_object_polygon_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *
    /* then when this is done the object needs to figure if it changed and */
    /* if so what and where and add the appropriate redraw lines */
    /* if someone is clipping this obj - go calculate the clipper */
-   if (obj->cur.clipper)
+   if (obj->cur->clipper)
      {
-        if (obj->cur.cache.clip.dirty)
-          evas_object_clip_recalc(obj->cur.eo_clipper, obj->cur.clipper);
-        obj->cur.clipper->func->render_pre(obj->cur.eo_clipper, obj->cur.clipper);
+        if (obj->cur->cache.clip.dirty)
+          evas_object_clip_recalc(obj->cur->eo_clipper, obj->cur->clipper);
+        obj->cur->clipper->func->render_pre(obj->cur->eo_clipper, obj->cur->clipper);
      }
    /* now figure what changed and add draw rects */
    /* if it just became visible or invisible */
@@ -385,16 +388,16 @@ evas_object_polygon_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *
         goto done;
      }
    /* if it changed render op */
-   if (obj->cur.render_op != obj->prev.render_op)
+   if (obj->cur->render_op != obj->prev->render_op)
      {
         evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj);
         goto done;
      }
    /* if it changed color */
-   if ((obj->cur.color.r != obj->prev.color.r) ||
-       (obj->cur.color.g != obj->prev.color.g) ||
-       (obj->cur.color.b != obj->prev.color.b) ||
-       (obj->cur.color.a != obj->prev.color.a))
+   if ((obj->cur->color.r != obj->prev->color.r) ||
+       (obj->cur->color.g != obj->prev->color.g) ||
+       (obj->cur->color.b != obj->prev->color.b) ||
+       (obj->cur->color.a != obj->prev->color.a))
      {
         evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj);
         goto done;
@@ -402,28 +405,28 @@ evas_object_polygon_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *
    /* if it changed geometry - and obviously not visibility or color */
    /* calculate differences since we have a constant color fill */
    /* we really only need to update the differences */
-   if ((obj->cur.geometry.x != obj->prev.geometry.x) ||
-       (obj->cur.geometry.y != obj->prev.geometry.y) ||
-       (obj->cur.geometry.w != obj->prev.geometry.w) ||
-       (obj->cur.geometry.h != obj->prev.geometry.h) ||
+   if ((obj->cur->geometry.x != obj->prev->geometry.x) ||
+       (obj->cur->geometry.y != obj->prev->geometry.y) ||
+       (obj->cur->geometry.w != obj->prev->geometry.w) ||
+       (obj->cur->geometry.h != obj->prev->geometry.h) ||
        (o->changed))
      {
         evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj);
         goto done;
      }
    done:
-   if ((obj->cur.geometry.x != obj->prev.geometry.x) ||
-       (obj->cur.geometry.y != obj->prev.geometry.y))
+   if ((obj->cur->geometry.x != obj->prev->geometry.x) ||
+       (obj->cur->geometry.y != obj->prev->geometry.y))
      {
         if (!o->changed)
           {
-             o->offset.x = obj->cur.geometry.x - obj->prev.geometry.x;
-             o->offset.y = obj->cur.geometry.y - obj->prev.geometry.y;
+             o->offset.x = obj->cur->geometry.x - obj->prev->geometry.x;
+             o->offset.y = obj->cur->geometry.y - obj->prev->geometry.y;
           }
         else
           {
-             o->offset.x = obj->cur.geometry.x - o->geometry.x;
-             o->offset.y = obj->cur.geometry.y - o->geometry.y;
+             o->offset.x = obj->cur->geometry.x - o->geometry.x;
+             o->offset.y = obj->cur->geometry.y - o->geometry.y;
           }
      }
    evas_object_render_pre_effect_updates(&obj->layer->evas->clip_changes, eo_obj, is_v, was_v);
index 41aaec6..a364da4 100644 (file)
@@ -97,19 +97,6 @@ static void
 evas_object_rectangle_init(Evas_Object *eo_obj)
 {
    Evas_Object_Protected_Data *obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS);
-   /* set up default settings for this kind of object */
-   obj->cur.color.r = 255;
-   obj->cur.color.g = 255;
-   obj->cur.color.b = 255;
-   obj->cur.color.a = 255;
-   obj->cur.geometry.x = 0;
-   obj->cur.geometry.y = 0;
-   obj->cur.geometry.w = 0;
-   obj->cur.geometry.h = 0;
-   obj->cur.layer = 0;
-   obj->cur.render_op = EVAS_RENDER_BLEND;
-   /* set up object-specific settings */
-   obj->prev = obj->cur;
    /* set up methods (compulsory) */
    obj->func = &object_func;
    obj->type = o_type;
@@ -127,26 +114,26 @@ evas_object_rectangle_render(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Protec
    /* render object to surface with context, and offxet by x,y */
    obj->layer->evas->engine.func->context_color_set(output,
                                                    context,
-                                                   obj->cur.cache.clip.r,
-                                                   obj->cur.cache.clip.g,
-                                                   obj->cur.cache.clip.b,
-                                                   obj->cur.cache.clip.a);
+                                                   obj->cur->cache.clip.r,
+                                                   obj->cur->cache.clip.g,
+                                                   obj->cur->cache.clip.b,
+                                                   obj->cur->cache.clip.a);
    obj->layer->evas->engine.func->context_multiplier_unset(output,
                                                           context);
    obj->layer->evas->engine.func->context_render_op_set(output, context,
-                                                       obj->cur.render_op);
+                                                       obj->cur->render_op);
    obj->layer->evas->engine.func->rectangle_draw(output,
                                                 context,
                                                 surface,
-                                                obj->cur.geometry.x + x,
-                                                obj->cur.geometry.y + y,
-                                                obj->cur.geometry.w,
-                                                obj->cur.geometry.h,
+                                                obj->cur->geometry.x + x,
+                                                obj->cur->geometry.y + y,
+                                                obj->cur->geometry.w,
+                                                obj->cur->geometry.h,
                                                 do_async);
-////                                            obj->cur.cache.geometry.x + x,
-////                                            obj->cur.cache.geometry.y + y,
-////                                            obj->cur.cache.geometry.w,
-////                                            obj->cur.cache.geometry.h);
+////                                            obj->cur->cache.geometry.x + x,
+////                                            obj->cur->cache.geometry.y + y,
+////                                            obj->cur->cache.geometry.w,
+////                                            obj->cur->cache.geometry.h);
 }
 
 static void
@@ -163,11 +150,11 @@ evas_object_rectangle_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data
    /* then when this is done the object needs to figure if it changed and */
    /* if so what and where and add the appropriate redraw rectangles */
    /* if someone is clipping this obj - go calculate the clipper */
-   if (obj->cur.clipper)
+   if (obj->cur->clipper)
      {
-        if (obj->cur.cache.clip.dirty)
-          evas_object_clip_recalc(obj->cur.eo_clipper, obj->cur.clipper);
-        obj->cur.clipper->func->render_pre(obj->cur.eo_clipper, obj->cur.clipper);
+        if (obj->cur->cache.clip.dirty)
+          evas_object_clip_recalc(obj->cur->eo_clipper, obj->cur->clipper);
+        obj->cur->clipper->func->render_pre(obj->cur->eo_clipper, obj->cur->clipper);
      }
    /* now figure what changed and add draw rects */
    /* if it just became visible or invisible */
@@ -195,16 +182,16 @@ evas_object_rectangle_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data
        goto done;
      }
    /* if it changed render op */
-   if (obj->cur.render_op != obj->prev.render_op)
+   if (obj->cur->render_op != obj->prev->render_op)
      {
        evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj);
        goto done;
      }
    /* if it changed color */
-   if ((obj->cur.color.r != obj->prev.color.r) ||
-       (obj->cur.color.g != obj->prev.color.g) ||
-       (obj->cur.color.b != obj->prev.color.b) ||
-       (obj->cur.color.a != obj->prev.color.a))
+   if ((obj->cur->color.r != obj->prev->color.r) ||
+       (obj->cur->color.g != obj->prev->color.g) ||
+       (obj->cur->color.b != obj->prev->color.b) ||
+       (obj->cur->color.a != obj->prev->color.a))
      {
        evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj);
        goto done;
@@ -212,28 +199,28 @@ evas_object_rectangle_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data
    /* if it changed geometry - and obviously not visibility or color */
    /* calculate differences since we have a constant color fill */
    /* we really only need to update the differences */
-   if ((obj->cur.geometry.x != obj->prev.geometry.x) ||
-       (obj->cur.geometry.y != obj->prev.geometry.y) ||
-       (obj->cur.geometry.w != obj->prev.geometry.w) ||
-       (obj->cur.geometry.h != obj->prev.geometry.h))
+   if ((obj->cur->geometry.x != obj->prev->geometry.x) ||
+       (obj->cur->geometry.y != obj->prev->geometry.y) ||
+       (obj->cur->geometry.w != obj->prev->geometry.w) ||
+       (obj->cur->geometry.h != obj->prev->geometry.h))
      {
        evas_rects_return_difference_rects(&obj->layer->evas->clip_changes,
-                                          obj->cur.geometry.x,
-                                          obj->cur.geometry.y,
-                                          obj->cur.geometry.w,
-                                          obj->cur.geometry.h,
-                                          obj->prev.geometry.x,
-                                          obj->prev.geometry.y,
-                                          obj->prev.geometry.w,
-                                          obj->prev.geometry.h);
-////   rl = evas_rects_return_difference_rects(obj->cur.cache.geometry.x,
-////                                           obj->cur.cache.geometry.y,
-////                                           obj->cur.cache.geometry.w,
-////                                           obj->cur.cache.geometry.h,
-////                                           obj->prev.cache.geometry.x,
-////                                           obj->prev.cache.geometry.y,
-////                                           obj->prev.cache.geometry.w,
-////                                           obj->prev.cache.geometry.h);
+                                          obj->cur->geometry.x,
+                                          obj->cur->geometry.y,
+                                          obj->cur->geometry.w,
+                                          obj->cur->geometry.h,
+                                          obj->prev->geometry.x,
+                                          obj->prev->geometry.y,
+                                          obj->prev->geometry.w,
+                                          obj->prev->geometry.h);
+////   rl = evas_rects_return_difference_rects(obj->cur->cache.geometry.x,
+////                                           obj->cur->cache.geometry.y,
+////                                           obj->cur->cache.geometry.w,
+////                                           obj->cur->cache.geometry.h,
+////                                           obj->prev->cache.geometry.x,
+////                                           obj->prev->cache.geometry.y,
+////                                           obj->prev->cache.geometry.w,
+////                                           obj->prev->cache.geometry.h);
        goto done;
      }
    /* it obviously didn't change - add a NO obscure - this "unupdates"  this */
@@ -244,10 +231,10 @@ evas_object_rectangle_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data
        evas_object_is_opaque(eo_obj) &&
        (!obj->clip.clipees))
      obj->layer->evas->engine.func->output_redraws_rect_del(obj->layer->evas->engine.data.output,
-                                                           obj->cur.cache.clip.x,
-                                                           obj->cur.cache.clip.y,
-                                                           obj->cur.cache.clip.w,
-                                                           obj->cur.cache.clip.h);
+                                                           obj->cur->cache.clip.x,
+                                                           obj->cur->cache.clip.y,
+                                                           obj->cur->cache.clip.w,
+                                                           obj->cur->cache.clip.h);
   */
    done:
    evas_object_render_pre_effect_updates(&obj->layer->evas->clip_changes, eo_obj, is_v, was_v);
@@ -272,9 +259,9 @@ 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->cur.render_op == EVAS_RENDER_COPY)
+   if (obj->cur->render_op == EVAS_RENDER_COPY)
        return 1;
-   if (obj->cur.render_op != EVAS_RENDER_BLEND)
+   if (obj->cur->render_op != EVAS_RENDER_BLEND)
        return 0;
    return 1;
 }
@@ -284,9 +271,9 @@ evas_object_rectangle_was_opaque(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Pr
 {
    /* this returns 1 if the internal object data implies that the object was */
    /* previously fully opaque over the entire rectangle it occupies */
-   if (obj->prev.render_op == EVAS_RENDER_COPY)
+   if (obj->prev->render_op == EVAS_RENDER_COPY)
        return 1;
-   if (obj->prev.render_op != EVAS_RENDER_BLEND)
+   if (obj->prev->render_op != EVAS_RENDER_BLEND)
        return 0;
    return 1;
 }
index f1ac3a6..3d19e65 100644 (file)
@@ -257,7 +257,12 @@ _smart_member_add(Eo *smart_obj, void *_pd, va_list *list)
    o->member_count++;
    evas_object_release(eo_obj, obj, 1);
    obj->layer = smart->layer;
-   obj->cur.layer = obj->layer->layer;
+   EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+     {
+       state_write->layer = obj->layer->layer;
+     }
+   EINA_COW_STATE_WRITE_END(obj, state_write, cur);
+
    obj->layer->usage++;
    obj->smart.parent = smart_obj;
    o->contained = eina_inlist_append(o->contained, EINA_INLIST_GET(obj));
@@ -303,7 +308,13 @@ _smart_member_del(Eo *smart_obj, void *_pd EINA_UNUSED, va_list *list)
    obj->smart.parent = NULL;
    evas_object_smart_member_cache_invalidate(eo_obj, EINA_TRUE, EINA_TRUE, EINA_TRUE);
    obj->layer->usage--;
-   obj->cur.layer = obj->layer->layer;
+
+   EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+     {
+       state_write->layer = obj->layer->layer;
+     }
+   EINA_COW_STATE_WRITE_END(obj, state_write, cur);
+
    evas_object_inject(eo_obj, obj, obj->layer->evas->evas);
    obj->restack = 1;
    evas_object_change(eo_obj, obj);
@@ -1347,17 +1358,17 @@ evas_object_smart_bounding_box_update(Evas_Object *eo_obj, Evas_Object_Protected
           {
              evas_object_smart_bounding_box_update(o->object, o);
 
-             tx = o->cur.bounding_box.x;
-             ty = o->cur.bounding_box.y;
-             tw = o->cur.bounding_box.x + o->cur.bounding_box.w;
-             th = o->cur.bounding_box.y + o->cur.bounding_box.h;
+             tx = o->cur->bounding_box.x;
+             ty = o->cur->bounding_box.y;
+             tw = o->cur->bounding_box.x + o->cur->bounding_box.w;
+             th = o->cur->bounding_box.y + o->cur->bounding_box.h;
           }
         else
           {
-             tx = o->cur.geometry.x;
-             ty = o->cur.geometry.y;
-             tw = o->cur.geometry.x + o->cur.geometry.w;
-             th = o->cur.geometry.y + o->cur.geometry.h;
+             tx = o->cur->geometry.x;
+             ty = o->cur->geometry.y;
+             tw = o->cur->geometry.x + o->cur->geometry.w;
+             th = o->cur->geometry.y + o->cur->geometry.h;
           }
 
         if (tx < minx) minx = tx;
@@ -1366,26 +1377,42 @@ evas_object_smart_bounding_box_update(Evas_Object *eo_obj, Evas_Object_Protected
         if (th > maxh) maxh = th;
      }
 
-   if (minx != obj->cur.bounding_box.x)
+   if (minx != obj->cur->bounding_box.x)
      {
-        obj->cur.bounding_box.w += obj->cur.bounding_box.x - minx;
-        obj->cur.bounding_box.x = minx;
+        EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+          {
+             state_write->bounding_box.w += state_write->bounding_box.x - minx;
+             state_write->bounding_box.x = minx;
+          }
+        EINA_COW_STATE_WRITE_END(obj, state_write, cur);
      }
 
-   if (miny != obj->cur.bounding_box.y)
+   if (miny != obj->cur->bounding_box.y)
      {
-        obj->cur.bounding_box.h += obj->cur.bounding_box.y - miny;
-        obj->cur.bounding_box.y = miny;
+        EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+          {
+             state_write->bounding_box.h += state_write->bounding_box.y - miny;
+             state_write->bounding_box.y = miny;
+          }
+        EINA_COW_STATE_WRITE_END(obj, state_write, cur);
      }
 
-   if (maxw != obj->cur.bounding_box.x + obj->cur.bounding_box.w)
+   if (maxw != obj->cur->bounding_box.x + obj->cur->bounding_box.w)
      {
-        obj->cur.bounding_box.w = maxw - obj->cur.bounding_box.x;
+        EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+          {
+             state_write->bounding_box.w = maxw - state_write->bounding_box.x;
+          }
+        EINA_COW_STATE_WRITE_END(obj, state_write, cur);
      }
 
-   if (maxh != obj->cur.bounding_box.y + obj->cur.bounding_box.h)
+   if (maxh != obj->cur->bounding_box.y + obj->cur->bounding_box.h)
      {
-        obj->cur.bounding_box.h = maxh - obj->cur.bounding_box.y;
+        EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+          {
+             state_write->bounding_box.h = maxh - state_write->bounding_box.y;
+          }
+        EINA_COW_STATE_WRITE_END(obj, state_write, cur);
      }
 }
 
@@ -1395,18 +1422,6 @@ evas_object_smart_init(Evas_Object *eo_obj)
 {
    Evas_Object_Protected_Data *obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS);
    obj->is_smart = EINA_TRUE;
-   /* set up default settings for this kind of object */
-   obj->cur.color.r = 255;
-   obj->cur.color.g = 255;
-   obj->cur.color.b = 255;
-   obj->cur.color.a = 255;
-   obj->cur.geometry.x = 0;
-   obj->cur.geometry.y = 0;
-   obj->cur.geometry.w = 0;
-   obj->cur.geometry.h = 0;
-   obj->cur.layer = 0;
-   /* set up object-specific settings */
-   obj->prev = obj->cur;
    /* set up methods (compulsory) */
    obj->func = &object_func;
 }
@@ -1421,7 +1436,7 @@ static void
 evas_object_smart_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
 {
    if (obj->pre_render_done) return;
-   if (!obj->child_has_map && !obj->cur.cached_surface)
+   if (!obj->child_has_map && !obj->cur->cached_surface)
      {
 #if 0
         Evas_Object_Smart *o;
@@ -1429,10 +1444,10 @@ evas_object_smart_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *ob
         fprintf(stderr, "");
         o = (Evas_Object_Smart *)(obj->object_data);
         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))
+            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))
           {
              Eina_Bool cache_map = EINA_FALSE;
 
@@ -1456,14 +1471,14 @@ evas_object_smart_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *ob
                        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_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_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; */
@@ -1480,15 +1495,15 @@ evas_object_smart_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *ob
              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(eo_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,
+                       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;
+             obj->cur->cached_surface = cache_map;
           }
 #endif
      }
index 80f86cd..a89866f 100644 (file)
@@ -41,8 +41,8 @@ _smart_move_children_relative(Eo *eo_obj, void *_pd EINA_UNUSED, va_list *list)
         // evas_object_geometry_get(child, &orig_x, &orig_y, NULL, NULL);
         if (child->delete_me) continue;
         if (child->is_static_clip) continue;
-        orig_x = child->cur.geometry.x;
-        orig_y = child->cur.geometry.y;
+        orig_x = child->cur->geometry.x;
+        orig_y = child->cur->geometry.y;
        evas_object_move(child->object, orig_x + dx, orig_y + dy);
      }
 }
index c31ddd4..8232958 100644 (file)
@@ -172,7 +172,7 @@ _evas_object_text_items_clean(Evas_Object_Protected_Data *obj, Evas_Object_Text
        (!memcmp(&o->cur.glow, &o->prev.glow, sizeof (o->cur.glow))) &&
        (!memcmp(&o->cur.glow2, &o->prev.glow2, sizeof (o->cur.glow2))) &&
        (o->cur.style == o->prev.style) &&
-       (obj->cur.scale == obj->prev.scale))
+       (obj->cur->scale == obj->prev->scale))
      {
         if ((o->last_computed.ellipsis_start) &&
             (o->last_computed.ellipsis_start == o->items))
@@ -465,7 +465,7 @@ _text_font_set(Eo *eo_obj, void *_pd, va_list *list)
      }
 
    o->font = evas_font_load(obj->layer->evas->evas, o->cur.fdesc, o->cur.source,
-         (int)(((double) o->cur.size) * obj->cur.scale));
+         (int)(((double) o->cur.size) * obj->cur->scale));
    if (o->font)
      {
         o->ascent = ENFN->font_ascent_get(ENDT, o->font);
@@ -493,7 +493,7 @@ _text_font_set(Eo *eo_obj, void *_pd, va_list *list)
                                                 obj->layer->evas->pointer.x,
                                                 obj->layer->evas->pointer.y,
                                                 1, 1);
-             if ((is ^ was) && obj->cur.visible)
+             if ((is ^ was) && obj->cur->visible)
                evas_event_feed_mouse_move(obj->layer->evas->evas,
                                           obj->layer->evas->pointer.x,
                                           obj->layer->evas->pointer.y,
@@ -697,9 +697,9 @@ _evas_object_text_layout(Evas_Object *eo_obj, Evas_Object_Text *o, Eina_Unicode
    if (o->items &&
        !memcmp(&o->cur, &o->prev, sizeof (o->cur)) &&
        o->cur.text == text &&
-       obj->cur.scale == obj->prev.scale &&
-       o->last_computed.w == obj->cur.geometry.w &&
-       o->last_computed.h == obj->cur.geometry.h)
+       obj->cur->scale == obj->prev->scale &&
+       o->last_computed.w == obj->cur->geometry.w &&
+       o->last_computed.h == obj->cur->geometry.h)
      return ;
 
    evas_object_content_change(eo_obj, obj);
@@ -767,9 +767,9 @@ _evas_object_text_layout(Evas_Object *eo_obj, Evas_Object_Text *o, Eina_Unicode
      }
 
    /* Handle ellipsis */
-   if ((o->cur.ellipsis >= 0.0) && (advance > obj->cur.geometry.w) && (obj->cur.geometry.w > 0))
+   if ((o->cur.ellipsis >= 0.0) && (advance > obj->cur->geometry.w) && (obj->cur->geometry.w > 0))
      {
-        Evas_Coord ellip_frame = obj->cur.geometry.w;
+        Evas_Coord ellip_frame = obj->cur->geometry.w;
         Evas_Object_Text_Item *start_ellip_it = NULL, *end_ellip_it = NULL;
         /* Account of the ellipsis item width. As long as ellipsis != 0
          * we have a left ellipsis. And the same with 1 and right. */
@@ -1029,7 +1029,7 @@ _text_text_set(Eo *eo_obj, void *_pd, va_list *list)
    is = evas_object_is_in_output_rect(eo_obj, obj,
                                      obj->layer->evas->pointer.x,
                                      obj->layer->evas->pointer.y, 1, 1);
-   if ((is || was) && obj->cur.visible)
+   if ((is || was) && obj->cur->visible)
      evas_event_feed_mouse_move(obj->layer->evas->evas,
                                obj->layer->evas->pointer.x,
                                obj->layer->evas->pointer.y,
@@ -1302,14 +1302,14 @@ _text_char_pos_get(Eo *eo_obj, void *_pd, va_list *list)
        w += x;
        x = 0;
      }
-   if ((x + w) > obj->cur.geometry.w) w = obj->cur.geometry.w - x;
+   if ((x + w) > obj->cur->geometry.w) w = obj->cur->geometry.w - x;
    if (w < 0) w = 0;
    if (y < 0)
      {
        h += y;
        y = 0;
      }
-   if ((y + h) > obj->cur.geometry.h) h = obj->cur.geometry.h - y;
+   if ((y + h) > obj->cur->geometry.h) h = obj->cur->geometry.h - y;
    if (h < 0) h = 0;
    if (cx) *cx = x;
    if (cy) *cy = y;
@@ -1387,14 +1387,14 @@ _text_char_coords_get(Eo *eo_obj, void *_pd, va_list *list)
        rx = 0;
      }
    Evas_Object_Protected_Data *obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS);
-   if ((rx + rw) > obj->cur.geometry.w) rw = obj->cur.geometry.w - rx;
+   if ((rx + rw) > obj->cur->geometry.w) rw = obj->cur->geometry.w - rx;
    if (rw < 0) rw = 0;
    if (ry < 0)
      {
        rh += ry;
        ry = 0;
      }
-   if ((ry + rh) > obj->cur.geometry.h) rh = obj->cur.geometry.h - ry;
+   if ((ry + rh) > obj->cur->geometry.h) rh = obj->cur->geometry.h - ry;
    if (rh < 0) rh = 0;
    if (cx) *cx = rx;
    if (cy) *cy = ry;
@@ -1425,11 +1425,17 @@ _text_style_set(Eo *eo_obj, void *_pd, va_list *list)
    evas_text_style_pad_get(o->cur.style, &pl, &pr, &pt, &pb);
    o->cur.style = style;
    evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
-   if (o->items)
-     obj->cur.geometry.w += (l - pl) + (r - pr);
-   else
-     obj->cur.geometry.w = 0;
-   obj->cur.geometry.h += (t - pt) + (b - pb);
+
+   EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+     {
+       if (o->items)
+        state_write->geometry.w += (l - pl) + (r - pr);
+       else
+        state_write->geometry.w = 0;
+       state_write->geometry.h += (t - pt) + (b - pb);
+     }
+   EINA_COW_STATE_WRITE_END(obj, state_write, cur);
+
    evas_object_change(eo_obj, obj);
    evas_object_clip_dirty(eo_obj, obj);
 }
@@ -1878,18 +1884,6 @@ static void
 evas_object_text_init(Evas_Object *eo_obj)
 {
    Evas_Object_Protected_Data *obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS);
-   /* set up default settings for this kind of object */
-   obj->cur.color.r = 255;
-   obj->cur.color.g = 255;
-   obj->cur.color.b = 255;
-   obj->cur.color.a = 255;
-   obj->cur.geometry.x = 0;
-   obj->cur.geometry.y = 0;
-   obj->cur.geometry.w = 0;
-   obj->cur.geometry.h = 0;
-   obj->cur.layer = 0;
-   /* set up object-specific settings */
-   obj->prev = obj->cur;
    /* set up methods (compulsory) */
    obj->func = &object_func;
    obj->type = o_type;
@@ -1968,13 +1962,13 @@ evas_object_text_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, vo
    /* render object to surface with context, and offxet by x,y */
    evas_text_style_pad_get(o->cur.style, &sl, NULL, &st, NULL);
    ENFN->context_multiplier_unset(output, context);
-   ENFN->context_render_op_set(output, context, obj->cur.render_op);
+   ENFN->context_render_op_set(output, context, obj->cur->render_op);
    /* FIXME: This clipping is just until we fix inset handling correctly. */
    ENFN->context_clip_clip(output, context,
-                              obj->cur.geometry.x + x,
-                              obj->cur.geometry.y + y,
-                              obj->cur.geometry.w,
-                              obj->cur.geometry.h);
+                              obj->cur->geometry.x + x,
+                              obj->cur->geometry.y + y,
+                              obj->cur->geometry.w,
+                              obj->cur->geometry.h);
 /*
    ENFN->context_color_set(output,
                            context,
@@ -1982,10 +1976,10 @@ evas_object_text_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, vo
    ENFN->rectangle_draw(output,
                         context,
                         surface,
-                        obj->cur.geometry.x + x,
-                        obj->cur.geometry.y + y,
-                        obj->cur.geometry.w,
-                        obj->cur.geometry.h);
+                        obj->cur->geometry.x + x,
+                        obj->cur->geometry.y + y,
+                        obj->cur->geometry.w,
+                        obj->cur->geometry.h);
  */
 #define COLOR_ONLY_SET(object, sub, col) \
        ENFN->context_color_set(output, context, \
@@ -1995,13 +1989,13 @@ evas_object_text_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, vo
                                object->sub.col.a);
 
 #define COLOR_SET(object, sub, col) \
-        if (obj->cur.clipper)\
+        if (obj->cur->clipper)\
         { \
           ENFN->context_color_set(output, context, \
-                               ((int)object->sub.col.r * ((int)obj->cur.clipper->cur.cache.clip.r + 1)) >> 8, \
-                               ((int)object->sub.col.g * ((int)obj->cur.clipper->cur.cache.clip.g + 1)) >> 8, \
-                               ((int)object->sub.col.b * ((int)obj->cur.clipper->cur.cache.clip.b + 1)) >> 8, \
-                               ((int)object->sub.col.a * ((int)obj->cur.clipper->cur.cache.clip.a + 1)) >> 8); \
+                               ((int)object->sub.col.r * ((int)obj->cur->clipper->cur->cache.clip.r + 1)) >> 8, \
+                               ((int)object->sub.col.g * ((int)obj->cur->clipper->cur->cache.clip.g + 1)) >> 8, \
+                               ((int)object->sub.col.b * ((int)obj->cur->clipper->cur->cache.clip.b + 1)) >> 8, \
+                               ((int)object->sub.col.a * ((int)obj->cur->clipper->cur->cache.clip.a + 1)) >> 8); \
         } \
         else\
           ENFN->context_color_set(output, context, \
@@ -2011,13 +2005,13 @@ evas_object_text_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, vo
                                object->sub.col.a);
 
 #define COLOR_SET_AMUL(object, sub, col, amul) \
-        if (obj->cur.clipper) \
+        if (obj->cur->clipper) \
         { \
            ENFN->context_color_set(output, context, \
-                               (((int)object->sub.col.r) * ((int)obj->cur.clipper->cur.cache.clip.r) * (amul)) / 65025, \
-                               (((int)object->sub.col.g) * ((int)obj->cur.clipper->cur.cache.clip.g) * (amul)) / 65025, \
-                               (((int)object->sub.col.b) * ((int)obj->cur.clipper->cur.cache.clip.b) * (amul)) / 65025, \
-                               (((int)object->sub.col.a) * ((int)obj->cur.clipper->cur.cache.clip.a) * (amul)) / 65025); \
+                               (((int)object->sub.col.r) * ((int)obj->cur->clipper->cur->cache.clip.r) * (amul)) / 65025, \
+                               (((int)object->sub.col.g) * ((int)obj->cur->clipper->cur->cache.clip.g) * (amul)) / 65025, \
+                               (((int)object->sub.col.b) * ((int)obj->cur->clipper->cur->cache.clip.b) * (amul)) / 65025, \
+                               (((int)object->sub.col.a) * ((int)obj->cur->clipper->cur->cache.clip.a) * (amul)) / 65025); \
         } \
         else \
            ENFN->context_color_set(output, context, \
@@ -2032,14 +2026,14 @@ evas_object_text_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, vo
                                 context,                                \
                                 surface,                                \
                                 o->font,                                \
-                                obj->cur.geometry.x + x + sl + ox + it->x, \
-                                obj->cur.geometry.y + y + st + oy +     \
+                                obj->cur->geometry.x + x + sl + ox + it->x, \
+                                obj->cur->geometry.y + y + st + oy +     \
                                 (int)                                   \
-                                (((o->max_ascent * obj->cur.geometry.h) / obj->cur.geometry.h)), \
-                                obj->cur.geometry.w,                    \
-                                obj->cur.geometry.h,                    \
-                                obj->cur.geometry.w,                    \
-                                obj->cur.geometry.h,                    \
+                                (((o->max_ascent * obj->cur->geometry.h) / obj->cur->geometry.h)), \
+                                obj->cur->geometry.w,                    \
+                                obj->cur->geometry.h,                    \
+                                obj->cur->geometry.w,                    \
+                                obj->cur->geometry.h,                    \
                                 &it->text_props,                        \
                                 do_async);
 
@@ -2191,7 +2185,7 @@ evas_object_text_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, vo
           }
 
         /* normal text */
-        COLOR_ONLY_SET(obj, cur.cache, clip);
+        COLOR_ONLY_SET(obj, cur->cache, clip);
         DRAW_TEXT(0, 0);
      }
 }
@@ -2210,18 +2204,18 @@ evas_object_text_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
     Then when this is done the object needs to figure if it changed and 
     if so what and where and add the appropriate redraw rectangles */
    /* if someone is clipping this obj - go calculate the clipper */
-   if (obj->cur.clipper)
+   if (obj->cur->clipper)
      {
-       if (obj->cur.cache.clip.dirty)
-         evas_object_clip_recalc(obj->cur.eo_clipper, obj->cur.clipper);
-       obj->cur.clipper->func->render_pre(obj->cur.eo_clipper, obj->cur.clipper);
+       if (obj->cur->cache.clip.dirty)
+         evas_object_clip_recalc(obj->cur->eo_clipper, obj->cur->clipper);
+       obj->cur->clipper->func->render_pre(obj->cur->eo_clipper, obj->cur->clipper);
      }
    /* If object size changed and ellipsis is set */
    if (((o->cur.ellipsis >= 0.0 ||
         o->cur.ellipsis != o->prev.ellipsis) &&
-       ((obj->cur.geometry.w != o->last_computed.w) ||
-        (obj->cur.geometry.h != o->last_computed.h))) ||
-       (obj->cur.scale != obj->prev.scale))
+       ((obj->cur->geometry.w != o->last_computed.w) ||
+        (obj->cur->geometry.h != o->last_computed.h))) ||
+       (obj->cur->scale != obj->prev->scale))
      {
        _evas_object_text_recalc(eo_obj, o->cur.text);
        evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
@@ -2256,10 +2250,10 @@ evas_object_text_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
        goto done;
      }
    /* if it changed color */
-   if ((obj->cur.color.r != obj->prev.color.r) ||
-       (obj->cur.color.g != obj->prev.color.g) ||
-       (obj->cur.color.b != obj->prev.color.b) ||
-       (obj->cur.color.a != obj->prev.color.a))
+   if ((obj->cur->color.r != obj->prev->color.r) ||
+       (obj->cur->color.g != obj->prev->color.g) ||
+       (obj->cur->color.b != obj->prev->color.b) ||
+       (obj->cur->color.a != obj->prev->color.a))
      {
        evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, 
                                            eo_obj, obj);
@@ -2268,16 +2262,16 @@ evas_object_text_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
    /* if it changed geometry - and obviously not visibility or color
     calculate differences since we have a constant color fill
     we really only need to update the differences */
-   if ((obj->cur.geometry.x != obj->prev.geometry.x) ||
-       (obj->cur.geometry.y != obj->prev.geometry.y) ||
-       (obj->cur.geometry.w != obj->prev.geometry.w) ||
-       (obj->cur.geometry.h != obj->prev.geometry.h))
+   if ((obj->cur->geometry.x != obj->prev->geometry.x) ||
+       (obj->cur->geometry.y != obj->prev->geometry.y) ||
+       (obj->cur->geometry.w != obj->prev->geometry.w) ||
+       (obj->cur->geometry.h != obj->prev->geometry.h))
      {
        evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, 
                                            eo_obj, obj);
        goto done;
      }
-   if (obj->cur.render_op != obj->prev.render_op)
+   if (obj->cur->render_op != obj->prev->render_op)
      {
        evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, 
                                            eo_obj, obj);
@@ -2385,7 +2379,7 @@ _evas_object_text_rehint(Evas_Object *eo_obj)
    is = evas_object_is_in_output_rect(eo_obj, obj,
                                      obj->layer->evas->pointer.x,
                                      obj->layer->evas->pointer.y, 1, 1);
-   if ((is || was) && obj->cur.visible)
+   if ((is || was) && obj->cur->visible)
      evas_event_feed_mouse_move(obj->layer->evas->evas,
                                obj->layer->evas->pointer.x,
                                obj->layer->evas->pointer.y,
@@ -2412,21 +2406,32 @@ _evas_object_text_recalc(Evas_Object *eo_obj, Eina_Unicode *text)
         w = _evas_object_text_horiz_advance_get(eo_obj, o);
         h = _evas_object_text_vert_advance_get(eo_obj, o);
        evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
-        obj->cur.geometry.w = w + l + r;
-        obj->cur.geometry.h = h + t + b;
-////        obj->cur.cache.geometry.validity = 0;
+
+       EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+         {
+           state_write->geometry.w = w + l + r;
+           state_write->geometry.h = h + t + b;
+         }
+       EINA_COW_STATE_WRITE_END(obj, state_write, cur);
+
+////        obj->cur->cache.geometry.validity = 0;
      }
    else
      {
        int t = 0, b = 0;
 
        evas_text_style_pad_get(o->cur.style, NULL, NULL, &t, &b);
-        obj->cur.geometry.w = 0;
-        obj->cur.geometry.h = o->max_ascent + o->max_descent + t + b;
-////        obj->cur.cache.geometry.validity = 0;
+       EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+         {
+           state_write->geometry.w = 0;
+           state_write->geometry.h = o->max_ascent + o->max_descent + t + b;
+         }
+       EINA_COW_STATE_WRITE_END(obj, state_write, cur);
+           
+////        obj->cur->cache.geometry.validity = 0;
      }
-   o->last_computed.w = obj->cur.geometry.w;
-   o->last_computed.h = obj->cur.geometry.h;
+   o->last_computed.w = obj->cur->geometry.w;
+   o->last_computed.h = obj->cur->geometry.h;
    evas_object_clip_dirty(eo_obj, obj);
 }
 
index 5ff691a..cc7e135 100644 (file)
@@ -2429,7 +2429,7 @@ _format_dup(Evas_Object *eo_obj, const Evas_Object_Textblock_Format *fmt)
 
    /* FIXME: just ref the font here... */
    fmt2->font.font = evas_font_load(obj->layer->evas->evas, fmt2->font.fdesc,
-         fmt2->font.source, (int)(((double) fmt2->font.size) * obj->cur.scale));
+         fmt2->font.source, (int)(((double) fmt2->font.size) * obj->cur->scale));
    return fmt2;
 }
 
@@ -2526,7 +2526,7 @@ _layout_format_ascent_descent_adjust(const Evas_Object *eo_obj,
           {
              int dh;
 
-             dh = obj->cur.geometry.h - (*maxascent + *maxdescent);
+             dh = obj->cur->geometry.h - (*maxascent + *maxdescent);
              if (dh < 0) dh = 0;
              dh = fmt->linefill * dh;
              *maxdescent += dh / 2;
@@ -3107,8 +3107,8 @@ _layout_calculate_format_item_size(const Evas_Object *eo_obj,
               p += 6;
               if (sscanf(p, "%ix%i", &w, &h) == 2)
                 {
-                   w = w * obj->cur.scale;
-                   h = h * obj->cur.scale;
+                   w = w * obj->cur->scale;
+                   h = h * obj->cur->scale;
                 }
            }
          break;
@@ -3723,7 +3723,7 @@ _format_finalize(Evas_Object *eo_obj, Evas_Object_Textblock_Format *fmt)
    of = fmt->font.font;
 
    fmt->font.font = evas_font_load(obj->layer->evas->evas, fmt->font.fdesc,
-         fmt->font.source, (int)(((double) fmt->font.size) * obj->cur.scale));
+         fmt->font.source, (int)(((double) fmt->font.size) * obj->cur->scale));
    if (of) evas_font_free(obj->layer->evas->evas, of);
 }
 
@@ -4873,7 +4873,7 @@ _layout(const Evas_Object *eo_obj, int w, int h, int *w_ret, int *h_ret)
    c->align = 0.0;
    c->align_auto = EINA_TRUE;
    c->ln = NULL;
-   c->width_changed = (obj->cur.geometry.w != o->last_w);
+   c->width_changed = (obj->cur->geometry.w != o->last_w);
 
    /* Start of logical layout creation */
    /* setup default base style */
@@ -5029,11 +5029,11 @@ _relayout(const Evas_Object *eo_obj)
 {
    Evas_Object_Protected_Data *obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS);
    Evas_Object_Textblock *o = eo_data_get(eo_obj, MY_CLASS);
-   _layout(eo_obj, obj->cur.geometry.w, obj->cur.geometry.h,
+   _layout(eo_obj, obj->cur->geometry.w, obj->cur->geometry.h,
          &o->formatted.w, &o->formatted.h);
    o->formatted.valid = 1;
-   o->last_w = obj->cur.geometry.w;
-   o->last_h = obj->cur.geometry.h;
+   o->last_w = obj->cur->geometry.w;
+   o->last_h = obj->cur->geometry.h;
    o->changed = 0;
    o->content_changed = 0;
    o->format_changed = EINA_FALSE;
@@ -9180,7 +9180,7 @@ evas_textblock_cursor_visible_range_get(Evas_Textblock_Cursor *start, Evas_Textb
    TB_HEAD_RETURN(EINA_FALSE);
    eo_e = evas_object_evas_get(eo_obj);
    Evas_Public_Data *e = eo_data_get(eo_e, EVAS_CLASS);
-   cy = 0 - obj->cur.geometry.y;
+   cy = 0 - obj->cur->geometry.y;
    ch = e->viewport.h;
    evas_textblock_cursor_line_coord_set(start, cy);
    evas_textblock_cursor_line_coord_set(end, cy + ch);
@@ -10131,18 +10131,6 @@ evas_object_textblock_init(Evas_Object *eo_obj)
         init_wordbreak();
      }
 
-   /* set up default settings for this kind of object */
-   obj->cur.color.r = 255;
-   obj->cur.color.g = 255;
-   obj->cur.color.b = 255;
-   obj->cur.color.a = 255;
-   obj->cur.geometry.x = 0.0;
-   obj->cur.geometry.y = 0.0;
-   obj->cur.geometry.w = 0.0;
-   obj->cur.geometry.h = 0.0;
-   obj->cur.layer = 0;
-   /* set up object-specific settings */
-   obj->prev = obj->cur;
    /* set up methods (compulsory) */
    obj->func = &object_func;
    obj->type = o_type;
@@ -10211,10 +10199,10 @@ evas_object_textblock_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *ob
                                                           context);
    /* FIXME: This clipping is just until we fix inset handling correctly. */
    ENFN->context_clip_clip(output, context,
-                              obj->cur.geometry.x + x,
-                              obj->cur.geometry.y + y,
-                              obj->cur.geometry.w,
-                              obj->cur.geometry.h);
+                              obj->cur->geometry.x + x,
+                              obj->cur->geometry.y + y,
+                              obj->cur->geometry.w,
+                              obj->cur->geometry.h);
    clip = ENFN->context_clip_get(output, context, &cx, &cy, &cw, &ch);
    /* If there are no paragraphs and thus there are no lines,
     * there's nothing left to do. */
@@ -10226,9 +10214,9 @@ evas_object_textblock_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *ob
         if (!par->visible) continue; \
         if (clip) \
           { \
-             if ((obj->cur.geometry.y + y + par->y + par->h) < (cy - 20)) \
+             if ((obj->cur->geometry.y + y + par->y + par->h) < (cy - 20)) \
              continue; \
-             if ((obj->cur.geometry.y + y + par->y) > (cy + ch + 20)) \
+             if ((obj->cur->geometry.y + y + par->y) > (cy + ch + 20)) \
              break; \
           } \
         _layout_paragraph_render(o, par); \
@@ -10238,9 +10226,9 @@ evas_object_textblock_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *ob
              \
              if (clip) \
                { \
-                  if ((obj->cur.geometry.y + y + par->y + ln->y + ln->h) < (cy - 20)) \
+                  if ((obj->cur->geometry.y + y + par->y + ln->y + ln->h) < (cy - 20)) \
                   continue; \
-                  if ((obj->cur.geometry.y + y + par->y + ln->y) > (cy + ch + 20)) \
+                  if ((obj->cur->geometry.y + y + par->y + ln->y) > (cy + ch + 20)) \
                   break; \
                } \
              EINA_INLIST_FOREACH(ln->items, itr) \
@@ -10253,13 +10241,13 @@ evas_object_textblock_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *ob
                     } \
                   if (clip) \
                     { \
-                       if ((obj->cur.geometry.x + x + ln->x + itr->x + itr->w) < (cx - 20)) \
+                       if ((obj->cur->geometry.x + x + ln->x + itr->x + itr->w) < (cx - 20)) \
                        continue; \
-                       if ((obj->cur.geometry.x + x + ln->x + itr->x) > (cx + cw + 20)) \
+                       if ((obj->cur->geometry.x + x + ln->x + itr->x) > (cx + cw + 20)) \
                        break; \
                     } \
                   if ((ln->x + itr->x + itr->w) <= 0) continue; \
-                  if (ln->x + itr->x > obj->cur.geometry.w) break; \
+                  if (ln->x + itr->x > obj->cur->geometry.w) break; \
                   do
 
 #define ITEM_WALK_END() \
@@ -10270,22 +10258,22 @@ evas_object_textblock_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *ob
    do {} while(0)
 #define COLOR_SET(col) \
    ENFN->context_color_set(output, context, \
-         (obj->cur.cache.clip.r * ti->parent.format->color.col.r) / 255, \
-         (obj->cur.cache.clip.g * ti->parent.format->color.col.g) / 255, \
-         (obj->cur.cache.clip.b * ti->parent.format->color.col.b) / 255, \
-         (obj->cur.cache.clip.a * ti->parent.format->color.col.a) / 255);
+         (obj->cur->cache.clip.r * ti->parent.format->color.col.r) / 255, \
+         (obj->cur->cache.clip.g * ti->parent.format->color.col.g) / 255, \
+         (obj->cur->cache.clip.b * ti->parent.format->color.col.b) / 255, \
+         (obj->cur->cache.clip.a * ti->parent.format->color.col.a) / 255);
 #define COLOR_SET_AMUL(col, amul) \
    ENFN->context_color_set(output, context, \
-         (obj->cur.cache.clip.r * ti->parent.format->color.col.r * (amul)) / 65025, \
-         (obj->cur.cache.clip.g * ti->parent.format->color.col.g * (amul)) / 65025, \
-         (obj->cur.cache.clip.b * ti->parent.format->color.col.b * (amul)) / 65025, \
-         (obj->cur.cache.clip.a * ti->parent.format->color.col.a * (amul)) / 65025);
+         (obj->cur->cache.clip.r * ti->parent.format->color.col.r * (amul)) / 65025, \
+         (obj->cur->cache.clip.g * ti->parent.format->color.col.g * (amul)) / 65025, \
+         (obj->cur->cache.clip.b * ti->parent.format->color.col.b * (amul)) / 65025, \
+         (obj->cur->cache.clip.a * ti->parent.format->color.col.a * (amul)) / 65025);
 #define DRAW_TEXT(ox, oy)                                               \
    if (ti->parent.format->font.font)                                    \
      evas_font_draw_async_check(obj, output, context, surface,          \
         ti->parent.format->font.font,                                   \
-        obj->cur.geometry.x + ln->x + ti->parent.x + x + (ox),          \
-        obj->cur.geometry.y + ln->par->y + ln->y + yoff + y + (oy),     \
+        obj->cur->geometry.x + ln->x + ti->parent.x + x + (ox),          \
+        obj->cur->geometry.y + ln->par->y + ln->y + yoff + y + (oy),     \
         ti->parent.w, ti->parent.h, ti->parent.w, ti->parent.h,         \
         &ti->text_props, do_async);
 
@@ -10295,15 +10283,15 @@ evas_object_textblock_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *ob
      { \
         ENFN->context_color_set(output, \
               context, \
-              (obj->cur.cache.clip.r * or) / 255, \
-              (obj->cur.cache.clip.g * og) / 255, \
-              (obj->cur.cache.clip.b * ob) / 255, \
-              (obj->cur.cache.clip.a * oa) / 255); \
+              (obj->cur->cache.clip.r * or) / 255, \
+              (obj->cur->cache.clip.g * og) / 255, \
+              (obj->cur->cache.clip.b * ob) / 255, \
+              (obj->cur->cache.clip.a * oa) / 255); \
         ENFN->rectangle_draw(output, \
               context, \
               surface, \
-              obj->cur.geometry.x + ln->x + x + (ox), \
-              obj->cur.geometry.y + ln->par->y + ln->y + y + (oy), \
+              obj->cur->geometry.x + ln->x + x + (ox), \
+              obj->cur->geometry.y + ln->par->y + ln->y + y + (oy), \
               (ow), \
               (oh), \
               do_async); \
@@ -10365,10 +10353,10 @@ evas_object_textblock_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *ob
    while (0)
 
      {
-        Evas_Coord look_for_y = 0 - (obj->cur.geometry.y + y);
+        Evas_Coord look_for_y = 0 - (obj->cur->geometry.y + y);
         if (clip)
           {
-             Evas_Coord tmp_lfy = cy - (obj->cur.geometry.y + y);
+             Evas_Coord tmp_lfy = cy - (obj->cur->geometry.y + y);
              if (tmp_lfy > look_for_y)
                 look_for_y = tmp_lfy;
           }
@@ -10601,9 +10589,9 @@ evas_object_textblock_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data
    /* then when this is done the object needs to figure if it changed and */
    /* if so what and where and add the appropriate redraw textblocks */
    if ((o->changed) || (o->content_changed) || (o->format_changed) ||
-       ((obj->cur.geometry.w != o->last_w) ||
+       ((obj->cur->geometry.w != o->last_w) ||
            (((o->valign != 0.0) || (o->have_ellipsis)) &&
-               (obj->cur.geometry.h != o->last_h))))
+               (obj->cur->geometry.h != o->last_h))))
      {
         _relayout(eo_obj);
        o->redraw = 0;
@@ -10621,11 +10609,11 @@ evas_object_textblock_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data
        goto done;
      }
    /* if someone is clipping this obj - go calculate the clipper */
-   if (obj->cur.clipper)
+   if (obj->cur->clipper)
      {
-       if (obj->cur.cache.clip.dirty)
-         evas_object_clip_recalc(obj->cur.eo_clipper, obj->cur.clipper);
-       obj->cur.clipper->func->render_pre(obj->cur.eo_clipper, obj->cur.clipper);
+       if (obj->cur->cache.clip.dirty)
+         evas_object_clip_recalc(obj->cur->eo_clipper, obj->cur->clipper);
+       obj->cur->clipper->func->render_pre(obj->cur->eo_clipper, obj->cur->clipper);
      }
    /* now figure what changed and add draw rects */
    /* if it just became visible or invisible */
@@ -10653,10 +10641,10 @@ evas_object_textblock_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data
        goto done;
      }
    /* if it changed color */
-   if ((obj->cur.color.r != obj->prev.color.r) ||
-       (obj->cur.color.g != obj->prev.color.g) ||
-       (obj->cur.color.b != obj->prev.color.b) ||
-       (obj->cur.color.a != obj->prev.color.a))
+   if ((obj->cur->color.r != obj->prev->color.r) ||
+       (obj->cur->color.g != obj->prev->color.g) ||
+       (obj->cur->color.b != obj->prev->color.b) ||
+       (obj->cur->color.a != obj->prev->color.a))
      {
        evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj);
        goto done;
@@ -10664,10 +10652,10 @@ evas_object_textblock_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data
    /* if it changed geometry - and obviously not visibility or color */
    /* calculate differences since we have a constant color fill */
    /* we really only need to update the differences */
-   if ((obj->cur.geometry.x != obj->prev.geometry.x) ||
-       (obj->cur.geometry.y != obj->prev.geometry.y) ||
-       (obj->cur.geometry.w != obj->prev.geometry.w) ||
-       (obj->cur.geometry.h != obj->prev.geometry.h))
+   if ((obj->cur->geometry.x != obj->prev->geometry.x) ||
+       (obj->cur->geometry.y != obj->prev->geometry.y) ||
+       (obj->cur->geometry.w != obj->prev->geometry.w) ||
+       (obj->cur->geometry.h != obj->prev->geometry.h))
      {
        evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj);
        goto done;
@@ -10733,9 +10721,9 @@ static void
 evas_object_textblock_coords_recalc(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
 {
    Evas_Object_Textblock *o = eo_data_get(eo_obj, MY_CLASS);
-   if ((obj->cur.geometry.w != o->last_w) ||
+   if ((obj->cur->geometry.w != o->last_w) ||
        (((o->valign != 0.0) || (o->have_ellipsis)) &&
-           (obj->cur.geometry.h != o->last_h)))
+           (obj->cur->geometry.h != o->last_h)))
      {
        o->formatted.valid = 0;
        o->changed = 1;
index 51f4d0d..451cb5a 100644 (file)
@@ -342,18 +342,6 @@ static void
 evas_object_textgrid_init(Evas_Object *eo_obj)
 {
    Evas_Object_Protected_Data *obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS);
-   /* set up default settings for this kind of object */
-   obj->cur.color.r = 255;
-   obj->cur.color.g = 255;
-   obj->cur.color.b = 255;
-   obj->cur.color.a = 255;
-   obj->cur.geometry.x = 0;
-   obj->cur.geometry.y = 0;
-   obj->cur.geometry.w = 0;
-   obj->cur.geometry.h = 0;
-   obj->cur.layer = 0;
-   /* set up object-specific settings */
-   obj->prev = obj->cur;
    /* set up methods (compulsory) */
    obj->func = &object_func;
    obj->type = o_type;
@@ -578,14 +566,14 @@ evas_object_textgrid_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
    /* render object to surface with context, and offset by x,y */
    Evas_Object_Textgrid *o = eo_data_get(eo_obj, MY_CLASS);
    ENFN->context_multiplier_unset(output, context);
-   ENFN->context_render_op_set(output, context, obj->cur.render_op);
+   ENFN->context_render_op_set(output, context, obj->cur->render_op);
 
    if (!(o->font) || (!o->cur.cells)) return;
 
    w = o->cur.char_width;
    h = o->cur.char_height;
-   ww = obj->cur.geometry.w;
-   hh = obj->cur.geometry.h;
+   ww = obj->cur->geometry.w;
+   hh = obj->cur->geometry.h;
 
    // generate row data from cells (and only deal with rows that updated)
    for (yy = 0, cells = o->cur.cells; yy < o->cur.h; yy++)
@@ -672,14 +660,14 @@ evas_object_textgrid_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
                                                   rr, rg, rb, ra);
           }
      }
-   yp = obj->cur.geometry.y + y;
+   yp = obj->cur->geometry.y + y;
    // draw the row data that is generated from the cell array
    for (yy = 0, cells = o->cur.cells; yy < o->cur.h; yy++)
      {
         Evas_Object_Textgrid_Row *row = &(o->cur.rows[yy]);
         Evas_Font_Array          *texts;
 
-        xp = obj->cur.geometry.x + x;
+        xp = obj->cur->geometry.x + x;
         for (xx = 0; xx < row->rects_num; xx++)
           {
              ENFN->context_color_set(output, context,
@@ -803,11 +791,11 @@ evas_object_textgrid_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data
    /* if so what and where and add thr appropriate redraw rectangles */
    Evas_Object_Textgrid *o = eo_data_get(eo_obj, MY_CLASS);
    /* if someone is clipping this obj - go calculate the clipper */
-   if (obj->cur.clipper)
+   if (obj->cur->clipper)
      {
-       if (obj->cur.cache.clip.dirty)
-         evas_object_clip_recalc(obj->cur.eo_clipper, obj->cur.clipper);
-       obj->cur.clipper->func->render_pre(obj->cur.eo_clipper, obj->cur.clipper);
+       if (obj->cur->cache.clip.dirty)
+         evas_object_clip_recalc(obj->cur->eo_clipper, obj->cur->clipper);
+       obj->cur->clipper->func->render_pre(obj->cur->eo_clipper, obj->cur->clipper);
      }
    /* now figure what changed and add draw rects */
    /* if it just became visible or invisible */
@@ -835,10 +823,10 @@ evas_object_textgrid_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data
        goto done;
      }
    /* if it changed color */
-   if ((obj->cur.color.r != obj->prev.color.r) ||
-       (obj->cur.color.g != obj->prev.color.g) ||
-       (obj->cur.color.b != obj->prev.color.b) ||
-       (obj->cur.color.a != obj->prev.color.a))
+   if ((obj->cur->color.r != obj->prev->color.r) ||
+       (obj->cur->color.g != obj->prev->color.g) ||
+       (obj->cur->color.b != obj->prev->color.b) ||
+       (obj->cur->color.a != obj->prev->color.a))
      {
        evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj);
        goto done;
@@ -846,20 +834,20 @@ evas_object_textgrid_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data
    /* if it changed geometry - and obviously not visibility or color */
    /* calculate differences since we have a constant color fill */
    /* we really only need to update the differences */
-   if ((obj->cur.geometry.x != obj->prev.geometry.x) ||
-       (obj->cur.geometry.y != obj->prev.geometry.y) ||
-       (obj->cur.geometry.w != obj->prev.geometry.w) ||
-       (obj->cur.geometry.h != obj->prev.geometry.h))
+   if ((obj->cur->geometry.x != obj->prev->geometry.x) ||
+       (obj->cur->geometry.y != obj->prev->geometry.y) ||
+       (obj->cur->geometry.w != obj->prev->geometry.w) ||
+       (obj->cur->geometry.h != obj->prev->geometry.h))
      {
        evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj);
        goto done;
      }
-   if (obj->cur.render_op != obj->prev.render_op)
+   if (obj->cur->render_op != obj->prev->render_op)
      {
        evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj);
        goto done;
      }
-   if (obj->cur.scale != obj->prev.scale)
+   if (obj->cur->scale != obj->prev->scale)
      {
        evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj);
        goto done;
@@ -896,9 +884,9 @@ evas_object_textgrid_render_pre(Evas_Object *eo_obj, Evas_Object_Protected_Data
                   Evas_Object_Textgrid_Row *r = &(o->cur.rows[i]);
                   if (r->ch1 >= 0)
                     evas_add_rect(&obj->layer->evas->clip_changes,
-                                  obj->cur.geometry.x + 
+                                  obj->cur->geometry.x + 
                                   (r->ch1 * o->cur.char_width),
-                                  obj->cur.geometry.y + 
+                                  obj->cur->geometry.y + 
                                   (i * o->cur.char_height),
                                   (r->ch2 - r->ch1 + 1) * o->cur.char_width,
                                   o->cur.char_height);
@@ -1221,7 +1209,7 @@ _font_set(Eo *eo_obj, void *_pd, va_list *list)
    o->font = evas_font_load(obj->layer->evas->evas, o->cur.font_description,
                             o->cur.font_source,
                             (int)(((double) o->cur.font_size) * 
-                                  obj->cur.scale));
+                                  obj->cur->scale));
    if (o->font)
      {
         Eina_Unicode W[2] = { 'W', 0 };
@@ -1251,8 +1239,13 @@ _font_set(Eo *eo_obj, void *_pd, va_list *list)
      }
    else
      {
-        obj->cur.geometry.w = 0;
-        obj->cur.geometry.h = 0;
+        EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+          {
+             state_write->geometry.w = 0;
+             state_write->geometry.h = 0;
+          }
+        EINA_COW_STATE_WRITE_END(obj, state_write, cur);
+
         o->max_ascent = 0;
      }
 
@@ -1268,7 +1261,7 @@ _font_set(Eo *eo_obj, void *_pd, va_list *list)
                                                 obj->layer->evas->pointer.x,
                                                 obj->layer->evas->pointer.y,
                                                 1, 1);
-             if ((is ^ was) && obj->cur.visible)
+             if ((is ^ was) && obj->cur->visible)
                evas_event_feed_mouse_move(obj->layer->evas->evas,
                                           obj->layer->evas->pointer.x,
                                           obj->layer->evas->pointer.y,
index 097800a..e818459 100644 (file)
@@ -199,36 +199,36 @@ 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->cur.map) && (obj->prev->usemap));
 }
 
 static Eina_Bool
 _evas_render_is_relevant(Evas_Object *eo_obj)
 {
    Evas_Object_Protected_Data *obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS);
-   return ((evas_object_is_visible(eo_obj, obj) && (!obj->cur.have_clipees)) ||
-           (evas_object_was_visible(eo_obj, obj) && (!obj->prev.have_clipees)));
+   return ((evas_object_is_visible(eo_obj, obj) && (!obj->cur->have_clipees)) ||
+           (evas_object_was_visible(eo_obj, obj) && (!obj->prev->have_clipees)));
 }
 
 static Eina_Bool
 _evas_render_can_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
 {
-   return (evas_object_is_visible(eo_obj, obj) && (!obj->cur.have_clipees));
+   return (evas_object_is_visible(eo_obj, obj) && (!obj->cur->have_clipees));
 }
 
 static void
 _evas_render_prev_cur_clip_cache_add(Evas_Public_Data *e, Evas_Object_Protected_Data *obj)
 {
    e->engine.func->output_redraws_rect_add(e->engine.data.output,
-                                           obj->prev.cache.clip.x,
-                                           obj->prev.cache.clip.y,
-                                           obj->prev.cache.clip.w,
-                                           obj->prev.cache.clip.h);
+                                           obj->prev->cache.clip.x,
+                                           obj->prev->cache.clip.y,
+                                           obj->prev->cache.clip.w,
+                                           obj->prev->cache.clip.h);
    e->engine.func->output_redraws_rect_add(e->engine.data.output,
-                                           obj->cur.cache.clip.x,
-                                           obj->cur.cache.clip.y,
-                                           obj->cur.cache.clip.w,
-                                           obj->cur.cache.clip.h);
+                                           obj->cur->cache.clip.x,
+                                           obj->cur->cache.clip.y,
+                                           obj->cur->cache.clip.w,
+                                           obj->cur->cache.clip.h);
 }
 
 static void
@@ -236,17 +236,17 @@ _evas_render_cur_clip_cache_del(Evas_Public_Data *e, Evas_Object_Protected_Data
 {
    Evas_Coord x, y, w, h;
 
-   x = obj->cur.cache.clip.x;
-   y = obj->cur.cache.clip.y;
-   w = obj->cur.cache.clip.w;
-   h = obj->cur.cache.clip.h;
-   if (obj->cur.clipper)
+   x = obj->cur->cache.clip.x;
+   y = obj->cur->cache.clip.y;
+   w = obj->cur->cache.clip.w;
+   h = obj->cur->cache.clip.h;
+   if (obj->cur->clipper)
      {
         RECTS_CLIP_TO_RECT(x, y, w, h,
-                           obj->cur.clipper->cur.cache.clip.x,
-                           obj->cur.clipper->cur.cache.clip.y,
-                           obj->cur.clipper->cur.cache.clip.w,
-                           obj->cur.clipper->cur.cache.clip.h);
+                           obj->cur->clipper->cur->cache.clip.x,
+                           obj->cur->clipper->cur->cache.clip.y,
+                           obj->cur->clipper->cur->cache.clip.w,
+                           obj->cur->clipper->cur->cache.clip.h);
      }
    e->engine.func->output_redraws_rect_del(e->engine.data.output,
                                            x, y, w, h);
@@ -318,7 +318,7 @@ _evas_render_phase1_direct(Evas_Public_Data *e,
                 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->prev.map, obj->prev->usemap,
                 _evas_render_has_map(eo_obj, obj),
                 _evas_render_had_map(obj));
              if ((obj->is_smart) &&
@@ -384,7 +384,7 @@ _evas_render_phase1_object_process(Evas_Public_Data *e, Evas_Object *eo_obj,
    obj->is_active = is_active;
 
    RDI(level);
-   RD("    [--- PROCESS [%p] '%s' active = %i, del = %i | %i %i %ix%i\n", obj, obj->type, is_active, obj->delete_me, obj->cur.geometry.x, obj->cur.geometry.y, obj->cur.geometry.w, obj->cur.geometry.h);
+   RD("    [--- PROCESS [%p] '%s' active = %i, del = %i | %i %i %ix%i\n", obj, obj->type, is_active, obj->delete_me, obj->cur->geometry.x, obj->cur->geometry.y, obj->cur->geometry.w, obj->cur->geometry.h);
 
    if ((!mapped_parent) && ((is_active) || (obj->delete_me != 0)))
      eina_array_push(active_objects, obj);
@@ -393,7 +393,7 @@ _evas_render_phase1_object_process(Evas_Public_Data *e, Evas_Object *eo_obj,
    if (!is_active)
      {
         RDI(level);
-        RD("     [%p] vis: %i, cache.clip.vis: %i cache.clip.a: %i [%p]\n", obj, obj->cur.visible, obj->cur.cache.clip.visible, obj->cur.cache.clip.a, obj->func->is_visible);
+        RD("     [%p] vis: %i, cache.clip.vis: %i cache.clip.a: %i [%p]\n", obj, obj->cur->visible, obj->cur->cache.clip.visible, obj->cur->cache.clip.a, obj->func->is_visible);
      }
 #endif
 
@@ -420,8 +420,8 @@ _evas_render_phase1_object_process(Evas_Public_Data *e, Evas_Object *eo_obj,
              if (map != hmap) *redraw_all = 1;
 
              if ((is_active) && (!obj->clip.clipees) &&
-                 ((evas_object_is_visible(eo_obj, obj) && (!obj->cur.have_clipees)) ||
-                  (evas_object_was_visible(eo_obj, obj) && (!obj->prev.have_clipees))))
+                 ((evas_object_is_visible(eo_obj, obj) && (!obj->cur->have_clipees)) ||
+                  (evas_object_was_visible(eo_obj, obj) && (!obj->prev->have_clipees))))
                {
                   eina_array_push(render_objects, obj);
                   _evas_render_prev_cur_clip_cache_add(e, obj);
@@ -522,12 +522,12 @@ _evas_render_phase1_object_process(Evas_Public_Data *e, Evas_Object *eo_obj,
      {
         RD("      not changed... [%i] -> (%i %i %p %i) [%i]\n",
            evas_object_is_visible(eo_obj, obj),
-           obj->cur.visible, obj->cur.cache.clip.visible, obj->smart.smart,
-           obj->cur.cache.clip.a, evas_object_was_visible(eo_obj, obj));
+           obj->cur->visible, obj->cur->cache.clip.visible, obj->smart.smart,
+           obj->cur->cache.clip.a, evas_object_was_visible(eo_obj, obj));
 
         if ((!obj->clip.clipees) && (obj->delete_me == 0) &&
             (_evas_render_can_render(eo_obj, obj) ||
-             (evas_object_was_visible(eo_obj, obj) && (!obj->prev.have_clipees))))
+             (evas_object_was_visible(eo_obj, obj) && (!obj->prev->have_clipees))))
           {
              if (obj->is_smart)
                {
@@ -679,7 +679,7 @@ _evas_render_check_pending_objects(Eina_Array *pending_objects, Evas *eo_e EINA_
                   else
                     if ((is_active) && (obj->restack) && (!obj->clip.clipees) &&
                         (_evas_render_can_render(eo_obj, obj) ||
-                         (evas_object_was_visible(eo_obj, obj) && (!obj->prev.have_clipees))))
+                         (evas_object_was_visible(eo_obj, obj) && (!obj->prev->have_clipees))))
                       {
                          if (!(obj->render_pre || obj->rect_del))
                            ok = EINA_TRUE;
@@ -687,7 +687,7 @@ _evas_render_check_pending_objects(Eina_Array *pending_objects, Evas *eo_e EINA_
                     else
                       if (is_active && (!obj->clip.clipees) &&
                           (_evas_render_can_render(eo_obj, obj) ||
-                           (evas_object_was_visible(eo_obj, obj) && (!obj->prev.have_clipees))))
+                           (evas_object_was_visible(eo_obj, obj) && (!obj->prev->have_clipees))))
                         {
                            if (obj->render_pre || obj->rect_del) ok = EINA_TRUE;
                         }
@@ -695,7 +695,7 @@ _evas_render_check_pending_objects(Eina_Array *pending_objects, Evas *eo_e EINA_
              else
                {
                   if ((!obj->clip.clipees) && (obj->delete_me == 0) &&
-                      (!obj->cur.have_clipees || (evas_object_was_visible(eo_obj, obj) && (!obj->prev.have_clipees)))
+                      (!obj->cur->have_clipees || (evas_object_was_visible(eo_obj, obj) && (!obj->prev->have_clipees)))
                       && evas_object_is_opaque(eo_obj, obj) && evas_object_is_visible(eo_obj, obj))
                     {
                        if (obj->rect_del || obj->is_smart) ok = EINA_TRUE;
@@ -764,18 +764,18 @@ _evas_render_can_use_overlay(Evas_Public_Data *e, Evas_Object *eo_obj)
    if (!evas_object_is_visible(eo_obj, obj)) return EINA_FALSE; /* no need to update the overlay if it's not visible */
 
    /* If any recoloring of the surface is needed, n overlay to */
-   if ((obj->cur.cache.clip.r != 255) ||
-       (obj->cur.cache.clip.g != 255) ||
-       (obj->cur.cache.clip.b != 255) ||
-       (obj->cur.cache.clip.a != 255))
+   if ((obj->cur->cache.clip.r != 255) ||
+       (obj->cur->cache.clip.g != 255) ||
+       (obj->cur->cache.clip.b != 255) ||
+       (obj->cur->cache.clip.a != 255))
      return EINA_FALSE;
 
    /* Check presence of transparent object on top of the video object */
    EINA_RECTANGLE_SET(&zone,
-                      obj->cur.cache.clip.x,
-                      obj->cur.cache.clip.y,
-                      obj->cur.cache.clip.w,
-                      obj->cur.cache.clip.h);
+                      obj->cur->cache.clip.x,
+                      obj->cur->cache.clip.y,
+                      obj->cur->cache.clip.w,
+                      obj->cur->cache.clip.h);
 
    for (i = e->active_objects.count - 1; i > 0; i--)
      {
@@ -793,25 +793,25 @@ _evas_render_can_use_overlay(Evas_Public_Data *e, Evas_Object *eo_obj)
           break;
 
         EINA_RECTANGLE_SET(&self,
-                           current->cur.cache.clip.x,
-                           current->cur.cache.clip.y,
-                           current->cur.cache.clip.w,
-                           current->cur.cache.clip.h);
+                           current->cur->cache.clip.x,
+                           current->cur->cache.clip.y,
+                           current->cur->cache.clip.w,
+                           current->cur->cache.clip.h);
 
         /* This doesn't cover the area of the video object, so don't bother with that object */
         if (!eina_rectangles_intersect(&zone, &self))
           continue;
 
-        xc1 = current->cur.cache.clip.x;
-        yc1 = current->cur.cache.clip.y;
-        xc2 = current->cur.cache.clip.x + current->cur.cache.clip.w;
-        yc2 = current->cur.cache.clip.y + current->cur.cache.clip.h;
+        xc1 = current->cur->cache.clip.x;
+        yc1 = current->cur->cache.clip.y;
+        xc2 = current->cur->cache.clip.x + current->cur->cache.clip.w;
+        yc2 = current->cur->cache.clip.y + current->cur->cache.clip.h;
 
         if (evas_object_is_visible(eo_current, current) &&
             (!current->clip.clipees) &&
-            (current->cur.visible) &&
+            (current->cur->visible) &&
             (!current->delete_me) &&
-            (current->cur.cache.clip.visible) &&
+            (current->cur->cache.clip.visible) &&
             (!eo_isa(eo_current, EVAS_OBJ_SMART_CLASS)))
           {
              Eina_Bool included = EINA_FALSE;
@@ -844,8 +844,8 @@ _evas_render_can_use_overlay(Evas_Public_Data *e, Evas_Object *eo_obj)
                        Eina_List *ln;
                        Evas_Coord xn2, yn2;
 
-                       r = eina_rectangle_new(current->cur.cache.clip.x, current->cur.cache.clip.y,
-                                              current->cur.cache.clip.w, current->cur.cache.clip.h);
+                       r = eina_rectangle_new(current->cur->cache.clip.x, current->cur->cache.clip.y,
+                                              current->cur->cache.clip.w, current->cur->cache.clip.h);
 
                        opaques = eina_list_append(opaques, r);
 
@@ -911,8 +911,8 @@ _evas_render_can_use_overlay(Evas_Public_Data *e, Evas_Object *eo_obj)
                   /* No inclusion at all, so add it */
                   if (!included)
                     {
-                       r = eina_rectangle_new(current->cur.cache.clip.x, current->cur.cache.clip.y,
-                                              current->cur.cache.clip.w, current->cur.cache.clip.h);
+                       r = eina_rectangle_new(current->cur->cache.clip.x, current->cur->cache.clip.y,
+                                              current->cur->cache.clip.w, current->cur->cache.clip.h);
 
                        alphas = eina_list_append(alphas, r);
                     }
@@ -958,7 +958,7 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
    if (mapped)
      {
         if ((!evas_object_is_visible(eo_obj, obj)) || (obj->clip.clipees) ||
-            (obj->cur.have_clipees))
+            (obj->cur->have_clipees))
           {
              RDI(level);
              RD("      }\n");
@@ -987,8 +987,8 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
 
         clean_them = EINA_TRUE;
 
-        sw = obj->cur.geometry.w;
-        sh = obj->cur.geometry.h;
+        sw = obj->cur->geometry.w;
+        sh = obj->cur->geometry.h;
         RDI(level);
         RD("        mapped obj: %ix%i\n", sw, sh);
         if ((sw <= 0) || (sh <= 0))
@@ -1097,8 +1097,8 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
                   e->engine.func->context_free(e->engine.data.output, ctx);
                }
              ctx = e->engine.func->context_new(e->engine.data.output);
-             off_x2 = -obj->cur.geometry.x;
-             off_y2 = -obj->cur.geometry.y;
+             off_x2 = -obj->cur->geometry.x;
+             off_y2 = -obj->cur->geometry.y;
              if (obj->is_smart)
                {
                   EINA_INLIST_FOREACH
@@ -1123,10 +1123,10 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
                   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,
-                                     obj->cur.geometry.w,
-                                     obj->cur.geometry.h);
+                                     obj->cur->geometry.x + off_x2,
+                                     obj->cur->geometry.y + off_y2,
+                                     obj->cur->geometry.w,
+                                     obj->cur->geometry.h);
 
                   e->engine.func->context_clip_set(e->engine.data.output,
                                                    ctx, x, y, w, h);
@@ -1157,36 +1157,40 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
                                            context);
         if (obj->map->surface)
           {
-             if (obj->cur.clipper)
+             if (obj->cur->clipper)
                {
                   int x, y, w, h;
 
                   evas_object_clip_recalc(eo_obj, obj);
-                  x = obj->cur.cache.clip.x;
-                  y = obj->cur.cache.clip.y;
-                  w = obj->cur.cache.clip.w;
-                  h = obj->cur.cache.clip.h;
+                  x = obj->cur->cache.clip.x;
+                  y = obj->cur->cache.clip.y;
+                  w = obj->cur->cache.clip.w;
+                  h = obj->cur->cache.clip.h;
 
                   if (obj->is_smart)
                     {
                        Evas_Object *tobj;
 
-                       obj->cur.cache.clip.dirty = EINA_TRUE;
+                      EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+                        {
+                          state_write->cache.clip.dirty = EINA_TRUE;
+                        }
+                      EINA_COW_STATE_WRITE_END(obj, state_write, cur);
 
                        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 = 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,
-                                     obj->cur.clipper->cur.cache.clip.x,
-                                     obj->cur.clipper->cur.cache.clip.y,
-                                     obj->cur.clipper->cur.cache.clip.w,
-                                     obj->cur.clipper->cur.cache.clip.h);
+                                     obj->cur->clipper->cur->cache.clip.x,
+                                     obj->cur->clipper->cur->cache.clip.y,
+                                     obj->cur->clipper->cur->cache.clip.w,
+                                     obj->cur->clipper->cur->cache.clip.h);
 
                   e->engine.func->context_clip_set(e->engine.data.output,
                                                    context,
@@ -1197,7 +1201,7 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
           e->engine.func->context_clip_clip(e->engine.data.output,
                                             context,
                                             ecx, ecy, ecw, ech);
-        if (obj->cur.cache.clip.visible)
+        if (obj->cur->cache.clip.visible)
           {
              obj->layer->evas->engine.func->context_multiplier_unset
                (e->engine.data.output, context);
@@ -1214,11 +1218,11 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
      }
    else
      {
-        if (0 && obj->cur.cached_surface)
+        if (0 && obj->cur->cached_surface)
           fprintf(stderr, "We should cache '%s' [%i, %i, %i, %i]\n",
                   evas_object_type_get(eo_obj),
-                  obj->cur.bounding_box.x, obj->cur.bounding_box.x,
-                  obj->cur.bounding_box.w, obj->cur.bounding_box.h);
+                  obj->cur->bounding_box.x, obj->cur->bounding_box.x,
+                  obj->cur->bounding_box.w, obj->cur->bounding_box.h);
         if (mapped)
           {
              RDI(level);
@@ -1244,39 +1248,39 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
                {
                   RDI(level);
 
-                  if (obj->cur.clipper)
+                  if (obj->cur->clipper)
                     {
                        RD("        clip: %i %i %ix%i [%i %i %ix%i]\n",
-                          obj->cur.cache.clip.x + off_x,
-                          obj->cur.cache.clip.y + off_y,
-                          obj->cur.cache.clip.w,
-                          obj->cur.cache.clip.h,
-                          obj->cur.geometry.x + off_x,
-                          obj->cur.geometry.y + off_y,
-                          obj->cur.geometry.w,
-                          obj->cur.geometry.h);
+                          obj->cur->cache.clip.x + off_x,
+                          obj->cur->cache.clip.y + off_y,
+                          obj->cur->cache.clip.w,
+                          obj->cur->cache.clip.h,
+                          obj->cur->geometry.x + off_x,
+                          obj->cur->geometry.y + off_y,
+                          obj->cur->geometry.w,
+                          obj->cur->geometry.h);
 
                        RD("        clipper: %i %i %ix%i\n",
-                          obj->cur.clipper->cur.cache.clip.x + off_x,
-                          obj->cur.clipper->cur.cache.clip.y + off_y,
-                          obj->cur.clipper->cur.cache.clip.w,
-                          obj->cur.clipper->cur.cache.clip.h);
+                          obj->cur->clipper->cur->cache.clip.x + off_x,
+                          obj->cur->clipper->cur->cache.clip.y + off_y,
+                          obj->cur->clipper->cur->cache.clip.w,
+                          obj->cur->clipper->cur->cache.clip.h);
 
                        int x, y, w, h;
 
                        if (_evas_render_has_map(eo_obj, obj))
                          evas_object_clip_recalc(eo_obj, obj);
 
-                       x = obj->cur.cache.clip.x + off_x;
-                       y = obj->cur.cache.clip.y + off_y;
-                       w = obj->cur.cache.clip.w;
-                       h = obj->cur.cache.clip.h;
+                       x = obj->cur->cache.clip.x + off_x;
+                       y = obj->cur->cache.clip.y + off_y;
+                       w = obj->cur->cache.clip.w;
+                       h = obj->cur->cache.clip.h;
 
                        RECTS_CLIP_TO_RECT(x, y, w, h,
-                                          obj->cur.clipper->cur.cache.clip.x + off_x,
-                                          obj->cur.clipper->cur.cache.clip.y + off_y,
-                                          obj->cur.clipper->cur.cache.clip.w,
-                                          obj->cur.clipper->cur.cache.clip.h);
+                                          obj->cur->clipper->cur->cache.clip.x + off_x,
+                                          obj->cur->clipper->cur->cache.clip.y + off_y,
+                                          obj->cur->clipper->cur->cache.clip.w,
+                                          obj->cur->clipper->cur->cache.clip.h);
 
                        e->engine.func->context_clip_set(e->engine.data.output,
                                                         ctx, x, y, w, h);
@@ -1288,21 +1292,21 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
           }
         else
           {
-             if (obj->cur.clipper)
+             if (obj->cur->clipper)
                {
                   int x, y, w, h;
 
                   if (_evas_render_has_map(eo_obj, obj))
                     evas_object_clip_recalc(eo_obj, obj);
-                  x = obj->cur.cache.clip.x;
-                  y = obj->cur.cache.clip.y;
-                  w = obj->cur.cache.clip.w;
-                  h = obj->cur.cache.clip.h;
+                  x = obj->cur->cache.clip.x;
+                  y = obj->cur->cache.clip.y;
+                  w = obj->cur->cache.clip.w;
+                  h = obj->cur->cache.clip.h;
                   RECTS_CLIP_TO_RECT(x, y, w, h,
-                                     obj->cur.clipper->cur.cache.clip.x,
-                                     obj->cur.clipper->cur.cache.clip.y,
-                                     obj->cur.clipper->cur.cache.clip.w,
-                                     obj->cur.clipper->cur.cache.clip.h);
+                                     obj->cur->clipper->cur->cache.clip.x,
+                                     obj->cur->clipper->cur->cache.clip.y,
+                                     obj->cur->clipper->cur->cache.clip.w,
+                                     obj->cur->clipper->cur->cache.clip.h);
                   e->engine.func->context_clip_set(e->engine.data.output,
                                                    context,
                                                    x + off_x, y + off_y, w, h);
@@ -1334,10 +1338,10 @@ _evas_render_cutout_add(Evas *eo_e, Evas_Object *eo_obj, int off_x, int off_y)
    if (evas_object_is_opaque(eo_obj, obj))
      {
         Evas_Coord cox, coy, cow, coh;
-        cox = obj->cur.cache.clip.x;
-        coy = obj->cur.cache.clip.y;
-        cow = obj->cur.cache.clip.w;
-        coh = obj->cur.cache.clip.h;
+        cox = obj->cur->cache.clip.x;
+        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))
           {
              Evas_Object *eo_oo;
@@ -1345,19 +1349,19 @@ _evas_render_cutout_add(Evas *eo_e, Evas_Object *eo_obj, int off_x, int off_y)
 
              eo_oo = eo_obj;
              oo = eo_data_get(eo_oo, EVAS_OBJ_CLASS);
-             while (oo->cur.clipper)
+             while (oo->cur->clipper)
                {
-                  if ((oo->cur.clipper->map->cur.map_parent
+                  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,
-                                     oo->cur.geometry.y,
-                                     oo->cur.geometry.w,
-                                     oo->cur.geometry.h);
-                  eo_oo = oo->cur.eo_clipper;
-                  oo = oo->cur.clipper;
+                                     oo->cur->geometry.x,
+                                     oo->cur->geometry.y,
+                                     oo->cur->geometry.w,
+                                     oo->cur->geometry.h);
+                  eo_oo = oo->cur->eo_clipper;
+                  oo = oo->cur->clipper;
                }
           }
         e->engine.func->context_cutout_add
@@ -1376,10 +1380,10 @@ _evas_render_cutout_add(Evas *eo_e, Evas_Object *eo_obj, int off_x, int off_y)
                   obx += off_x;
                   oby += off_y;
                   RECTS_CLIP_TO_RECT(obx, oby, obw, obh,
-                                     obj->cur.cache.clip.x + off_x,
-                                     obj->cur.cache.clip.y + off_y,
-                                     obj->cur.cache.clip.w,
-                                     obj->cur.cache.clip.h);
+                                     obj->cur->cache.clip.x + off_x,
+                                     obj->cur->cache.clip.y + off_y,
+                                     obj->cur->cache.clip.w,
+                                     obj->cur->cache.clip.h);
                   e->engine.func->context_cutout_add
                     (e->engine.data.output, e->engine.data.context,
                         obx, oby, obw, obh);
@@ -1593,10 +1597,10 @@ evas_render_updates_internal(Evas *eo_e,
           eo_data_get(e->framespace.clip, EVAS_OBJ_CLASS);
 
         EINA_RECTANGLE_SET(&clip_rect,
-                           framespace_clip->cur.geometry.x,
-                           framespace_clip->cur.geometry.y,
-                           framespace_clip->cur.geometry.w,
-                           framespace_clip->cur.geometry.h)
+                           framespace_clip->cur->geometry.x,
+                           framespace_clip->cur->geometry.y,
+                           framespace_clip->cur->geometry.w,
+                           framespace_clip->cur->geometry.h)
 
         /* With the master clip all setup, we need to loop the objects on this 
          * canvas and determine if the object is in the viewport space. If it 
@@ -1620,8 +1624,8 @@ evas_render_updates_internal(Evas *eo_e,
              if (eo_obj == framespace_clip->object) continue;
 
              EINA_RECTANGLE_SET(&obj_rect,
-                                obj->cur.geometry.x, obj->cur.geometry.y,
-                                obj->cur.geometry.w, obj->cur.geometry.h);
+                                obj->cur->geometry.x, obj->cur->geometry.y,
+                                obj->cur->geometry.w, obj->cur->geometry.h);
 
              /* if the object does not intersect our clip rect, ignore it */
              if (!eina_rectangles_intersect(&clip_rect, &obj_rect))
@@ -1657,9 +1661,9 @@ evas_render_updates_internal(Evas *eo_e,
                        (obj->func->has_opaque_rect(eo_obj, obj)))) &&
                      evas_object_is_visible(eo_obj, obj) &&
                      (!obj->clip.clipees) &&
-                     (obj->cur.visible) &&
+                     (obj->cur->visible) &&
                      (!obj->delete_me) &&
-                     (obj->cur.cache.clip.visible) &&
+                     (obj->cur->cache.clip.visible) &&
                      (!obj->is_smart)))
           /*     obscuring_objects = eina_list_append(obscuring_objects, obj); */
           eina_array_push(&e->obscuring_objects, obj);
@@ -1751,19 +1755,19 @@ evas_render_updates_internal(Evas *eo_e,
                   eo_obj = obj->object;
 
                   /* if it's in our outpout rect and it doesn't clip anything */
-                  RD("    OBJ: [%p] '%s' %i %i %ix%i\n", obj, obj->type, obj->cur.geometry.x, obj->cur.geometry.y, obj->cur.geometry.w, obj->cur.geometry.h);
+                  RD("    OBJ: [%p] '%s' %i %i %ix%i\n", obj, obj->type, obj->cur->geometry.x, obj->cur->geometry.y, obj->cur->geometry.w, obj->cur->geometry.h);
                   if ((evas_object_is_in_output_rect(eo_obj, obj, ux, uy, uw, uh) ||
                        (obj->is_smart)) &&
                       (!obj->clip.clipees) &&
-                      (obj->cur.visible) &&
+                      (obj->cur->visible) &&
                       (!obj->delete_me) &&
-                      (obj->cur.cache.clip.visible) &&
+                      (obj->cur->cache.clip.visible) &&
 //                   (!obj->is_smart) &&
-                      ((obj->cur.color.a > 0 || obj->cur.render_op != EVAS_RENDER_BLEND)))
+                      ((obj->cur->color.a > 0 || obj->cur->render_op != EVAS_RENDER_BLEND)))
                     {
                        int x, y, w, h;
 
-                       RD("      DRAW (vis: %i, a: %i, clipees: %p\n", obj->cur.visible, obj->cur.color.a, obj->clip.clipees);
+                       RD("      DRAW (vis: %i, a: %i, clipees: %p\n", obj->cur->visible, obj->cur->color.a, obj->clip.clipees);
                        if ((e->temporary_objects.count > offset) &&
                            (eina_array_data_get(&e->temporary_objects, offset) == obj))
                          offset++;
@@ -1773,10 +1777,10 @@ evas_render_updates_internal(Evas *eo_e,
                             if (!obj->is_smart)
                               {
                                  RECTS_CLIP_TO_RECT(x, y, w, h,
-                                                    obj->cur.cache.clip.x + off_x,
-                                                    obj->cur.cache.clip.y + off_y,
-                                                    obj->cur.cache.clip.w,
-                                                    obj->cur.cache.clip.h);
+                                                    obj->cur->cache.clip.x + off_x,
+                                                    obj->cur->cache.clip.y + off_y,
+                                                    obj->cur->cache.clip.w,
+                                                    obj->cur->cache.clip.h);
                               }
 
                             e->engine.func->context_clip_set(e->engine.data.output,
index eaae503..82db3d4 100644 (file)
@@ -83,7 +83,7 @@ _raise(Eo *eo_obj, void *_pd, va_list *list EINA_UNUSED)
              if (evas_object_is_in_output_rect(eo_obj, obj,
                                                obj->layer->evas->pointer.x,
                                                obj->layer->evas->pointer.y,
-                                               1, 1) && obj->cur.visible)
+                                               1, 1) && obj->cur->visible)
                evas_event_feed_mouse_move(obj->layer->evas->evas,
                                           obj->layer->evas->pointer.x,
                                           obj->layer->evas->pointer.y,
@@ -140,7 +140,7 @@ _lower(Eo *eo_obj, void *_pd, va_list *list EINA_UNUSED)
              if (evas_object_is_in_output_rect(eo_obj, obj,
                                                obj->layer->evas->pointer.x,
                                                obj->layer->evas->pointer.y,
-                                               1, 1) && obj->cur.visible)
+                                               1, 1) && obj->cur->visible)
                evas_event_feed_mouse_move(obj->layer->evas->evas,
                                           obj->layer->evas->pointer.x,
                                           obj->layer->evas->pointer.y,
@@ -227,7 +227,7 @@ _stack_above(Eo *eo_obj, void *_pd, va_list *list)
              if (evas_object_is_in_output_rect(eo_obj, obj,
                                                obj->layer->evas->pointer.x,
                                                obj->layer->evas->pointer.y,
-                                               1, 1) && obj->cur.visible)
+                                               1, 1) && obj->cur->visible)
                evas_event_feed_mouse_move(obj->layer->evas->evas,
                                           obj->layer->evas->pointer.x,
                                           obj->layer->evas->pointer.y,
@@ -314,7 +314,7 @@ _stack_below(Eo *eo_obj, void *_pd, va_list *list)
              if (evas_object_is_in_output_rect(eo_obj, obj,
                                                obj->layer->evas->pointer.x,
                                                obj->layer->evas->pointer.y,
-                                               1, 1) && obj->cur.visible)
+                                               1, 1) && obj->cur->visible)
                evas_event_feed_mouse_move(obj->layer->evas->evas,
                                           obj->layer->evas->pointer.x,
                                           obj->layer->evas->pointer.y,
index c291f1c..1b7d0cf 100644 (file)
@@ -18,10 +18,10 @@ _evas_object_event_new(void)
 static inline int
 evas_object_was_visible(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
 {
-   if ((obj->prev.visible) &&
-       ((obj->prev.cache.clip.visible) || obj->is_smart) &&
-       ((obj->prev.cache.clip.a > 0 && obj->prev.render_op == EVAS_RENDER_BLEND)
-       || obj->prev.render_op != EVAS_RENDER_BLEND))
+   if ((obj->prev->visible) &&
+       ((obj->prev->cache.clip.visible) || obj->is_smart) &&
+       ((obj->prev->cache.clip.a > 0 && obj->prev->render_op == EVAS_RENDER_BLEND)
+       || obj->prev->render_op != EVAS_RENDER_BLEND))
      {
         if (obj->func->was_visible)
           return obj->func->was_visible(eo_obj);
@@ -66,13 +66,13 @@ evas_object_is_opaque(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
 {
    if (obj->is_smart) return 0;
    /* If a mask: Assume alpha */
-   if (obj->cur.cache.clip.a == 255)
+   if (obj->cur->cache.clip.a == 255)
      {
         if (obj->func->is_opaque)
           return obj->func->is_opaque(eo_obj, obj);
         return 1;
      }
-   if (obj->cur.render_op == EVAS_RENDER_COPY)
+   if (obj->cur->render_op == EVAS_RENDER_COPY)
      return 1;
    return 0;
 }
@@ -123,10 +123,10 @@ evas_object_is_source_invisible(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Pro
 static inline int
 evas_object_is_visible(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
 {                        /* post 1.0 -> enable? */
-   if ((obj->cur.visible)/* && (obj->cur.color.a > 0)*/ &&
-       ((obj->cur.cache.clip.visible) || (obj->is_smart)) &&
-       ((obj->cur.cache.clip.a > 0 && obj->cur.render_op == EVAS_RENDER_BLEND)
-       || obj->cur.render_op != EVAS_RENDER_BLEND))
+   if ((obj->cur->visible)/* && (obj->cur->color.a > 0)*/ &&
+       ((obj->cur->cache.clip.visible) || (obj->is_smart)) &&
+       ((obj->cur->cache.clip.a > 0 && obj->cur->render_op == EVAS_RENDER_BLEND)
+       || obj->cur->render_op != EVAS_RENDER_BLEND))
      {
         if (obj->func->is_visible)
           return obj->func->is_visible(eo_obj);
@@ -138,12 +138,12 @@ evas_object_is_visible(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
 static inline int
 evas_object_clippers_is_visible(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj)
 {
-   if (obj->cur.visible)
+   if (obj->cur->visible)
      {
-        if (obj->cur.clipper)
+        if (obj->cur->clipper)
           {
-             return evas_object_clippers_is_visible(obj->cur.eo_clipper,
-                                                    obj->cur.clipper);
+             return evas_object_clippers_is_visible(obj->cur->eo_clipper,
+                                                    obj->cur->clipper);
           }
         return 1;
      }
@@ -155,10 +155,10 @@ evas_object_is_in_output_rect(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Prote
 {
    /* assumes coords have been recalced */
    if ((RECTS_INTERSECT(x, y, w, h,
-                        obj->cur.cache.clip.x,
-                        obj->cur.cache.clip.y,
-                        obj->cur.cache.clip.w,
-                        obj->cur.cache.clip.h)))
+                        obj->cur->cache.clip.x,
+                        obj->cur->cache.clip.y,
+                        obj->cur->cache.clip.w,
+                        obj->cur->cache.clip.h)))
      return 1;
    return 0;
 }
@@ -198,20 +198,20 @@ evas_object_is_active(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
 static inline void
 evas_object_coords_recalc(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
 {
-////   if (obj->cur.cache.geometry.validity == obj->layer->evas->output_validity)
+////   if (obj->cur->cache.geometry.validity == obj->layer->evas->output_validity)
 ////     return;
-////   obj->cur.cache.geometry.x =
-////     evas_coord_world_x_to_screen(obj->layer->evas, obj->cur.geometry.x);
-////   obj->cur.cache.geometry.y =
-////     evas_coord_world_y_to_screen(obj->layer->evas, obj->cur.geometry.y);
-////   obj->cur.cache.geometry.w =
-////     evas_coord_world_x_to_screen(obj->layer->evas, obj->cur.geometry.w) -
+////   obj->cur->cache.geometry.x =
+////     evas_coord_world_x_to_screen(obj->layer->evas, obj->cur->geometry.x);
+////   obj->cur->cache.geometry.y =
+////     evas_coord_world_y_to_screen(obj->layer->evas, obj->cur->geometry.y);
+////   obj->cur->cache.geometry.w =
+////     evas_coord_world_x_to_screen(obj->layer->evas, obj->cur->geometry.w) -
 ////     evas_coord_world_x_to_screen(obj->layer->evas, 0);
-////   obj->cur.cache.geometry.h =
-////     evas_coord_world_y_to_screen(obj->layer->evas, obj->cur.geometry.h) -
+////   obj->cur->cache.geometry.h =
+////     evas_coord_world_y_to_screen(obj->layer->evas, obj->cur->geometry.h) -
 ////     evas_coord_world_y_to_screen(obj->layer->evas, 0);
    if (obj->func->coords_recalc) obj->func->coords_recalc(eo_obj, obj);
-////   obj->cur.cache.geometry.validity = obj->layer->evas->output_validity;
+////   obj->cur->cache.geometry.validity = obj->layer->evas->output_validity;
 }
 
 static inline void
@@ -222,10 +222,10 @@ evas_object_clip_recalc(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
    int nx, ny, nw, nh, nr, ng, nb, na;
    Eina_Bool cvis, nvis;
 
-   clipper = obj->cur.clipper;
+   clipper = obj->cur->clipper;
 
-   if ((!obj->cur.cache.clip.dirty) &&
-       !(!obj->cur.clipper || clipper->cur.cache.clip.dirty)) return;
+   if ((!obj->cur->cache.clip.dirty) &&
+       !(!obj->cur->clipper || clipper->cur->cache.clip.dirty)) return;
 
    if (obj->layer->evas->is_frozen) return;
 
@@ -240,60 +240,65 @@ evas_object_clip_recalc(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
      }
    else
      {
-        cx = obj->cur.geometry.x;
-        cy = obj->cur.geometry.y;
-        cw = obj->cur.geometry.w;
-        ch = obj->cur.geometry.h;
+        cx = obj->cur->geometry.x;
+        cy = obj->cur->geometry.y;
+        cw = obj->cur->geometry.w;
+        ch = obj->cur->geometry.h;
      }
 
-   if (obj->cur.color.a == 0 && obj->cur.render_op == EVAS_RENDER_BLEND)
+   if (obj->cur->color.a == 0 && obj->cur->render_op == EVAS_RENDER_BLEND)
       cvis = EINA_FALSE;
-   else cvis = obj->cur.visible;
+   else cvis = obj->cur->visible;
 
-   cr = obj->cur.color.r; cg = obj->cur.color.g;
-   cb = obj->cur.color.b; ca = obj->cur.color.a;
+   cr = obj->cur->color.r; cg = obj->cur->color.g;
+   cb = obj->cur->color.b; ca = obj->cur->color.a;
 
    if (clipper)
      {
         // this causes problems... hmmm ?????
-        if (clipper->cur.cache.clip.dirty)
-          evas_object_clip_recalc(obj->cur.eo_clipper, clipper);
+        if (clipper->cur->cache.clip.dirty)
+          evas_object_clip_recalc(obj->cur->eo_clipper, clipper);
 
         // 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)
           {
-             nx = clipper->cur.cache.clip.x;
-             ny = clipper->cur.cache.clip.y;
-             nw = clipper->cur.cache.clip.w;
-             nh = clipper->cur.cache.clip.h;
+             nx = clipper->cur->cache.clip.x;
+             ny = clipper->cur->cache.clip.y;
+             nw = clipper->cur->cache.clip.w;
+             nh = clipper->cur->cache.clip.h;
              RECTS_CLIP_TO_RECT(cx, cy, cw, ch, nx, ny, nw, nh);
           }
 
-        nvis = clipper->cur.cache.clip.visible;
-        nr = clipper->cur.cache.clip.r;
-        ng = clipper->cur.cache.clip.g;
-        nb = clipper->cur.cache.clip.b;
-        na = clipper->cur.cache.clip.a;
+        nvis = clipper->cur->cache.clip.visible;
+        nr = clipper->cur->cache.clip.r;
+        ng = clipper->cur->cache.clip.g;
+        nb = clipper->cur->cache.clip.b;
+        na = clipper->cur->cache.clip.a;
         cvis = (cvis & nvis);
         cr = (cr * (nr + 1)) >> 8;
         cg = (cg * (ng + 1)) >> 8;
         cb = (cb * (nb + 1)) >> 8;
         ca = (ca * (na + 1)) >> 8;
      }
-   if ((ca == 0 && obj->cur.render_op == EVAS_RENDER_BLEND) ||
+   if ((ca == 0 && obj->cur->render_op == EVAS_RENDER_BLEND) ||
        (cw <= 0) || (ch <= 0)) cvis = EINA_FALSE;
-   obj->cur.cache.clip.x = cx;
-   obj->cur.cache.clip.y = cy;
-   obj->cur.cache.clip.w = cw;
-   obj->cur.cache.clip.h = ch;
-   obj->cur.cache.clip.visible = cvis;
-   obj->cur.cache.clip.r = cr;
-   obj->cur.cache.clip.g = cg;
-   obj->cur.cache.clip.b = cb;
-   obj->cur.cache.clip.a = ca;
-   obj->cur.cache.clip.dirty = EINA_FALSE;
+
+   EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+     {
+        state_write->cache.clip.x = cx;
+        state_write->cache.clip.y = cy;
+        state_write->cache.clip.w = cw;
+        state_write->cache.clip.h = ch;
+        state_write->cache.clip.visible = cvis;
+        state_write->cache.clip.r = cr;
+        state_write->cache.clip.g = cg;
+        state_write->cache.clip.b = cb;
+        state_write->cache.clip.a = ca;
+        state_write->cache.clip.dirty = EINA_FALSE;
+     }
+   EINA_COW_STATE_WRITE_END(obj, state_write, cur);
 }
 
 #endif
index 6258d44..3d0d21a 100644 (file)
@@ -536,7 +536,7 @@ struct _Evas_Object_Protected_State
 {
    Evas_Object_Protected_Data *clipper;
    Evas_Object          *eo_clipper;
-   double                scale;
+
    Evas_Coord_Rectangle  geometry;
    Evas_Coord_Rectangle  bounding_box;
    struct {
@@ -547,21 +547,23 @@ struct _Evas_Object_Protected_State
          Eina_Bool       dirty : 1;
       } clip;
    } cache;
-   short                 layer;
    struct {
       unsigned char      r, g, b, a;
    } color;
 
+   double                scale;
+
+   short                 layer;
+
    Evas_Render_Op        render_op : 4;
 
    Eina_Bool             visible : 1;
    Eina_Bool             have_clipees : 1;
    Eina_Bool             anti_alias : 1;
    Eina_Bool             valid_bounding_box : 1;
+
    Eina_Bool             cached_surface : 1;
    Eina_Bool             parent_cached_surface : 1;
-   Eina_Bool             opaque_valid : 1;
-   Eina_Bool             opaque : 1;
 };
 
 struct _Evas_Object_Protected_Data
@@ -571,7 +573,8 @@ struct _Evas_Object_Protected_Data
    const char              *type;
    Evas_Layer              *layer;
 
-   Evas_Object_Protected_State cur, prev;
+   const Evas_Object_Protected_State *cur;
+   const Evas_Object_Protected_State *prev;
 
    char                       *name;
 
@@ -1257,11 +1260,19 @@ void _evas_device_unref(Evas_Device *dev);
        
 extern Eina_Cow *evas_object_proxy_cow;
 extern Eina_Cow *evas_object_map_cow;
+extern Eina_Cow *evas_object_state_cow;
 
 extern Eina_Cow *evas_object_image_pixels_cow;
 extern Eina_Cow *evas_object_image_load_opts_cow;
 extern Eina_Cow *evas_object_image_state_cow;
 
+# define EINA_COW_STATE_WRITE_BEGIN(Obj, Write, State)          \
+  EINA_COW_WRITE_BEGIN(evas_object_state_cow, Obj->State, \
+                       Evas_Object_Protected_State, Write)
+
+# define EINA_COW_STATE_WRITE_END(Obj, Write, State)                    \
+  EINA_COW_WRITE_END(evas_object_state_cow, Obj->State, Write)
+
 /****************************************************************************/
 /*****************************************/
 /********************/
index e7f0f28..52f97be 100644 (file)
@@ -164,10 +164,10 @@ compute_gl_coordinates(Evas_Object *obj, int rot, int clip,
    if (rot == 0)
      {
         // oringinal image object coordinate in gl coordinate
-        imgc[0] = pd->cur.geometry.x;
-        imgc[1] = pd->layer->evas->output.h - pd->cur.geometry.y - pd->cur.geometry.h;
-        imgc[2] = imgc[0] + pd->cur.geometry.w;
-        imgc[3] = imgc[1] + pd->cur.geometry.h;
+        imgc[0] = pd->cur->geometry.x;
+        imgc[1] = pd->layer->evas->output.h - pd->cur->geometry.y - pd->cur->geometry.h;
+        imgc[2] = imgc[0] + pd->cur->geometry.w;
+        imgc[3] = imgc[1] + pd->cur->geometry.h;
 
         // transformed (x,y,width,height) in gl coordinate
         objc[0] = imgc[0] + x;
@@ -178,14 +178,14 @@ compute_gl_coordinates(Evas_Object *obj, int rot, int clip,
    else if (rot == 180)
      {
         // oringinal image object coordinate in gl coordinate
-        imgc[0] = pd->layer->evas->output.w - pd->cur.geometry.x - pd->cur.geometry.w;
-        imgc[1] = pd->cur.geometry.y;
-        imgc[2] = imgc[0] + pd->cur.geometry.w;
-        imgc[3] = imgc[1] + pd->cur.geometry.h;
+        imgc[0] = pd->layer->evas->output.w - pd->cur->geometry.x - pd->cur->geometry.w;
+        imgc[1] = pd->cur->geometry.y;
+        imgc[2] = imgc[0] + pd->cur->geometry.w;
+        imgc[3] = imgc[1] + pd->cur->geometry.h;
 
         // transformed (x,y,width,height) in gl coordinate
-        objc[0] = imgc[0] + pd->cur.geometry.w - x - width;
-        objc[1] = imgc[1] + pd->cur.geometry.h - y - height;
+        objc[0] = imgc[0] + pd->cur->geometry.w - x - width;
+        objc[1] = imgc[1] + pd->cur->geometry.h - y - height;
         objc[2] = objc[0] + width;
         objc[3] = objc[1] + height;
 
@@ -193,13 +193,13 @@ compute_gl_coordinates(Evas_Object *obj, int rot, int clip,
    else if (rot == 90)
      {
         // oringinal image object coordinate in gl coordinate
-        imgc[0] = pd->cur.geometry.y;
-        imgc[1] = pd->cur.geometry.x;
-        imgc[2] = imgc[0] + pd->cur.geometry.h;
-        imgc[3] = imgc[1] + pd->cur.geometry.w;
+        imgc[0] = pd->cur->geometry.y;
+        imgc[1] = pd->cur->geometry.x;
+        imgc[2] = imgc[0] + pd->cur->geometry.h;
+        imgc[3] = imgc[1] + pd->cur->geometry.w;
 
         // transformed (x,y,width,height) in gl coordinate
-        objc[0] = imgc[0] + pd->cur.geometry.h - y - height;
+        objc[0] = imgc[0] + pd->cur->geometry.h - y - height;
         objc[1] = imgc[1] + x;
         objc[2] = objc[0] + height;
         objc[3] = objc[1] + width;
@@ -207,14 +207,14 @@ compute_gl_coordinates(Evas_Object *obj, int rot, int clip,
    else if (rot == 270)
      {
         // oringinal image object coordinate in gl coordinate
-        imgc[0] = pd->layer->evas->output.h - pd->cur.geometry.y - pd->cur.geometry.h;
-        imgc[1] = pd->layer->evas->output.w - pd->cur.geometry.x - pd->cur.geometry.w;
-        imgc[2] = imgc[0] + pd->cur.geometry.h;
-        imgc[3] = imgc[1] + pd->cur.geometry.w;
+        imgc[0] = pd->layer->evas->output.h - pd->cur->geometry.y - pd->cur->geometry.h;
+        imgc[1] = pd->layer->evas->output.w - pd->cur->geometry.x - pd->cur->geometry.w;
+        imgc[2] = imgc[0] + pd->cur->geometry.h;
+        imgc[3] = imgc[1] + pd->cur->geometry.w;
 
         // transformed (x,y,width,height) in gl coordinate
         objc[0] = imgc[0] + y;
-        objc[1] = imgc[1] + pd->cur.geometry.w - x - width;
+        objc[1] = imgc[1] + pd->cur->geometry.w - x - width;
         objc[2] = objc[0] + height;
         objc[3] = objc[1] + width;
      }
@@ -390,8 +390,8 @@ _evgl_glGetIntegerv(GLenum pname, GLint* params)
                {
                   params[0] = 0;
                   params[1] = 0;
-                  params[2] = (GLint)img->cur.geometry.w;
-                  params[3] = (GLint)img->cur.geometry.h;
+                  params[2] = (GLint)img->cur->geometry.w;
+                  params[3] = (GLint)img->cur->geometry.h;
                   return;
                }
           }