evas: delay O(n) update of the bounding box until we really need it.
authorcedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 7 Jun 2012 07:10:36 +0000 (07:10 +0000)
committercedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 7 Jun 2012 07:10:36 +0000 (07:10 +0000)
git-svn-id: http://svn.enlightenment.org/svn/e/trunk/evas@71773 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/canvas/evas_events.c
src/lib/canvas/evas_object_main.c
src/lib/canvas/evas_object_smart.c
src/lib/include/evas_private.h

index d90d997..a3d90ed 100644 (file)
@@ -73,6 +73,8 @@ _evas_event_object_list_raw_in_get(Evas *e, Eina_List *in,
                     }
                   else
                     {
+                       if (!obj->child_has_map)
+                         evas_object_smart_bouding_box_update(obj);
                        if (obj->child_has_map ||
                            (obj->cur.bounding_box.x <= x &&
                             obj->cur.bounding_box.x + obj->cur.bounding_box.w >= x &&
index f0da75e..3b2fc80 100644 (file)
@@ -546,74 +546,7 @@ evas_object_update_bounding_box(Evas_Object *obj)
 
        if (computeminmax)
           {
-             const Eina_Inlist *list;
-             const Evas_Object *o;
-             /* Evas_Coord minx = obj->smart.parent->cur.geometry.x; */
-             Evas_Coord minx = noclip ? x : obj->layer->evas->output.w ;
-             /* Evas_Coord miny = obj->smart.parent->cur.geometry.y; */
-             Evas_Coord miny = noclip ? y : obj->layer->evas->output.h;
-             /* Evas_Coord maxw = obj->smart.parent->cur.geometry.x + obj->smart.parent->cur.geometry.w; */
-             Evas_Coord maxw = noclip ? x + w : 0;
-             /* Evas_Coord maxh = obj->smart.parent->cur.geometry.y + obj->smart.parent->cur.geometry.h; */
-             Evas_Coord maxh = noclip ? y + h : 0;
-
-             list = evas_object_smart_members_get_direct(obj->smart.parent);
-             EINA_INLIST_FOREACH(list, o)
-               {
-                  Evas_Coord tx;
-                  Evas_Coord ty;
-                  Evas_Coord tw;
-                  Evas_Coord th;
-
-                  if (o == obj) continue ;
-                  if (o->clip.clipees || o->is_static_clip) continue ;
-
-                  if (o->smart.smart)
-                    {
-                       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;
-                    }
-
-                  if (tx < minx) minx = tx;
-                  if (ty < miny) miny = ty;
-                  if (tw > maxw) maxw = tw;
-                  if (th > maxh) maxh = th;
-               }
-
-             if (minx != obj->smart.parent->cur.bounding_box.x)
-               {
-                  obj->smart.parent->cur.bounding_box.w += obj->smart.parent->cur.bounding_box.x - minx;
-                  obj->smart.parent->cur.bounding_box.x = minx;
-                  propagate = EINA_TRUE;
-               }
-
-             if (miny != obj->smart.parent->cur.bounding_box.y)
-               {
-                  obj->smart.parent->cur.bounding_box.h += obj->smart.parent->cur.bounding_box.y - miny;
-                  obj->smart.parent->cur.bounding_box.y = miny;
-                  propagate = EINA_TRUE;
-               }
-
-             if (maxw != obj->smart.parent->cur.bounding_box.x + obj->smart.parent->cur.bounding_box.w)
-               {
-                  obj->smart.parent->cur.bounding_box.w = maxw - obj->smart.parent->cur.bounding_box.x;
-                  propagate = EINA_TRUE;
-               }
-
-             if (maxh != obj->smart.parent->cur.bounding_box.y + obj->smart.parent->cur.bounding_box.h)
-               {
-                  obj->smart.parent->cur.bounding_box.h = maxh - obj->smart.parent->cur.bounding_box.y;
-                  propagate = EINA_TRUE;
-               }
+             evas_object_smart_need_bounding_box_update(obj->smart.parent);
           }
      }
    else
index 9337551..c327307 100644 (file)
@@ -16,6 +16,7 @@ struct _Evas_Object_Smart
    int               member_count;
    Eina_Bool         deletions_waiting : 1;
    Eina_Bool         need_recalculate : 1;
+   Eina_Bool         update_boundingbox_needed : 1;
 };
 
 struct _Evas_Smart_Callback
@@ -850,6 +851,107 @@ evas_object_smart_member_stack_below(Evas_Object *member, Evas_Object *other)
    o->contained = eina_inlist_prepend_relative(o->contained, EINA_INLIST_GET(member), EINA_INLIST_GET(other));
 }
 
+void
+evas_object_smart_need_bounding_box_update(Evas_Object *obj)
+{
+   Evas_Object_Smart *o;
+
+   MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+   return;
+   MAGIC_CHECK_END();
+   o = (Evas_Object_Smart *)(obj->object_data);
+   MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
+   return;
+   MAGIC_CHECK_END();
+
+   if (o->update_boundingbox_needed) return ;
+   o->update_boundingbox_needed = EINA_TRUE;
+
+   if (obj->smart.parent) evas_object_smart_need_bounding_box_update(obj->smart.parent);
+}
+
+void
+evas_object_smart_bouding_box_update(Evas_Object *obj)
+{
+   Eina_Inlist *list;
+   Evas_Object *o;
+   Evas_Object_Smart *os;
+   Evas_Coord minx;
+   Evas_Coord miny;
+   Evas_Coord maxw = 0;
+   Evas_Coord maxh = 0;
+
+   MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+   return;
+   MAGIC_CHECK_END();
+   os = (Evas_Object_Smart *)(obj->object_data);
+   MAGIC_CHECK(os, Evas_Object_Smart, MAGIC_OBJ_SMART);
+   return;
+   MAGIC_CHECK_END();
+
+   if (!os->update_boundingbox_needed) return ;
+   os->update_boundingbox_needed = EINA_FALSE;
+
+   minx = obj->layer->evas->output.w;
+   miny = obj->layer->evas->output.h;
+
+   list = os->contained;
+   EINA_INLIST_FOREACH(list, o)
+     {
+        Evas_Coord tx;
+        Evas_Coord ty;
+        Evas_Coord tw;
+        Evas_Coord th;
+
+        if (o == obj) continue ;
+        /* if (o->clip.clipees || o->is_static_clip) continue ; */
+
+        if (o->smart.smart)
+          {
+             evas_object_smart_bouding_box_update(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;
+          }
+        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;
+          }
+
+        if (tx < minx) minx = tx;
+        if (ty < miny) miny = ty;
+        if (tw > maxw) maxw = tw;
+        if (th > maxh) maxh = th;
+     }
+
+   if (minx != obj->cur.bounding_box.x)
+     {
+        obj->cur.bounding_box.w += obj->cur.bounding_box.x - minx;
+        obj->cur.bounding_box.x = minx;
+     }
+
+   if (miny != obj->cur.bounding_box.y)
+     {
+        obj->cur.bounding_box.h += obj->cur.bounding_box.y - miny;
+        obj->cur.bounding_box.y = miny;
+     }
+
+   if (maxw != obj->cur.bounding_box.x + obj->cur.bounding_box.w)
+     {
+        obj->cur.bounding_box.w = maxw - obj->cur.bounding_box.x;
+     }
+
+   if (maxh != obj->cur.bounding_box.y + obj->cur.bounding_box.h)
+     {
+        obj->cur.bounding_box.h = maxh - obj->cur.bounding_box.y;
+     }
+}
+
 /* all nice and private */
 static void
 evas_object_smart_init(Evas_Object *obj)
index 6e9a820..30e4274 100644 (file)
@@ -956,6 +956,8 @@ void evas_object_smart_member_stack_below(Evas_Object *member, Evas_Object *othe
 const Eina_Inlist *evas_object_smart_members_get_direct(const Evas_Object *obj);
 void _evas_object_smart_members_all_del(Evas_Object *obj);
 void evas_call_smarts_calculate(Evas *e);
+void evas_object_smart_bouding_box_update(Evas_Object *obj);
+void evas_object_smart_need_bounding_box_update(Evas_Object *obj);
 void *evas_mem_calloc(int size);
 void _evas_post_event_callback_call(Evas *e);
 void _evas_post_event_callback_free(Evas *e);