evas: let's try to determine the smallest possible size
authorcedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 3 May 2012 03:58:27 +0000 (03:58 +0000)
committercedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 3 May 2012 03:58:27 +0000 (03:58 +0000)
for the bounding box. This vastly improve the time spent
during event propagation when playing with elm_genlist.

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

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

index f5433d7..4e717ac 100644 (file)
@@ -461,7 +461,7 @@ evas_object_update_bounding_box(Evas_Object *obj)
    if (obj->child_has_map) return ; /* Disable bounding box computation for this object and its parent */
    /* We could also remove object that are not visible from the bounding box, use the clipping information
       to reduce the bounding of the object they are clipping, but for the moment this will do it's jobs */
-   clip = !!obj->clip.clipees;
+   clip = !!obj->clip.clipees || obj->is_static_clip;
 
    if (obj->smart.smart)
      {
@@ -490,124 +490,155 @@ evas_object_update_bounding_box(Evas_Object *obj)
     * That's why we initialiaze min and max search to geometry of the parent object.
     */
 
-   /* Update left limit */
-   if (!clip && x < obj->smart.parent->cur.bounding_box.x)
+   if (obj->smart.parent->cur.valid_bounding_box)
      {
-        obj->smart.parent->cur.bounding_box.w += obj->smart.parent->cur.bounding_box.x - x;
-        obj->smart.parent->cur.bounding_box.x = x;
-        propagate = EINA_TRUE;
-     }
-   else if ((px == obj->smart.parent->cur.bounding_box.x && x > obj->smart.parent->cur.bounding_box.x)
-            || (clip && x == obj->smart.parent->cur.bounding_box.x))
-     {
-        const Eina_Inlist *list;
-        const Evas_Object *o;
-        Evas_Coord minx = obj->smart.parent->cur.geometry.x;
-
-        list = evas_object_smart_members_get_direct(obj->smart.parent);
-        EINA_INLIST_FOREACH(list, o)
+        /* Update left limit */
+        if (!clip && x < obj->smart.parent->cur.bounding_box.x)
           {
-             Evas_Coord tx = o->smart.smart ? o->cur.bounding_box.x : o->cur.geometry.x;
+             obj->smart.parent->cur.bounding_box.w += obj->smart.parent->cur.bounding_box.x - x;
+             obj->smart.parent->cur.bounding_box.x = x;
+             propagate = EINA_TRUE;
+          }
+        else if ((px == obj->smart.parent->prev.bounding_box.x && x > obj->smart.parent->cur.bounding_box.x)
+                 || (clip && x == obj->smart.parent->cur.bounding_box.x))
+          {
+             const Eina_Inlist *list;
+             const Evas_Object *o;
+             /* Evas_Coord minx = obj->smart.parent->cur.geometry.x; */
+             Evas_Coord minx = clip ? obj->layer->evas->output.w : x;
 
-             if (!o->clip.clipees && tx < minx) minx = tx;
+             list = evas_object_smart_members_get_direct(obj->smart.parent);
+             EINA_INLIST_FOREACH(list, o)
+               {
+                  Evas_Coord tx;
+
+                  if (o == obj) continue ;
+                  tx = o->smart.smart ? o->cur.bounding_box.x : o->cur.geometry.x;
+
+                  if (!o->clip.clipees && !o->is_static_clip && tx < minx) minx = tx;
+               }
+
+             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 (minx != obj->smart.parent->cur.bounding_box.x)
+        /* Update top limit */
+        if (!clip && y < obj->smart.parent->cur.bounding_box.y)
           {
-             obj->smart.parent->cur.bounding_box.w += obj->smart.parent->cur.bounding_box.x - minx;
-             obj->smart.parent->cur.bounding_box.x = minx;
+             obj->smart.parent->cur.bounding_box.h += obj->smart.parent->cur.bounding_box.x - x;
+             obj->smart.parent->cur.bounding_box.y = y;
              propagate = EINA_TRUE;
           }
-     }
+        else if ((py == obj->smart.parent->prev.bounding_box.y && y  > obj->smart.parent->cur.bounding_box.y)
+                 || (clip && y == obj->smart.parent->cur.bounding_box.y))
+          {
+             const Eina_Inlist *list;
+             const Evas_Object *o;
+             /* Evas_Coord miny = obj->smart.parent->cur.geometry.y; */
+             Evas_Coord miny = clip ? obj->layer->evas->output.h : y;
 
-   /* Update top limit */
-   if (y < obj->smart.parent->cur.bounding_box.y)
-     {
-        obj->smart.parent->cur.bounding_box.h += obj->smart.parent->cur.bounding_box.x - x;
-        obj->smart.parent->cur.bounding_box.y = y;
-        propagate = EINA_TRUE;
-     }
-   else if ((py == obj->smart.parent->cur.bounding_box.y && y  > obj->smart.parent->cur.bounding_box.y)
-            || (clip && y == obj->smart.parent->cur.bounding_box.y))
-     {
-        const Eina_Inlist *list;
-        const Evas_Object *o;
-        Evas_Coord miny = obj->smart.parent->cur.geometry.y;
+             list = evas_object_smart_members_get_direct(obj->smart.parent);
+             EINA_INLIST_FOREACH(list, o)
+               {
+                  Evas_Coord ty;
 
-        list = evas_object_smart_members_get_direct(obj->smart.parent);
-        EINA_INLIST_FOREACH(list, o)
-          {
-             Evas_Coord ty = o->smart.smart ? o->cur.bounding_box.y : o->cur.geometry.y;
+                  if (o == obj) continue;
+                  ty = o->smart.smart ? o->cur.bounding_box.y : o->cur.geometry.y;
+
+                  if (!o->clip.clipees && !o->is_static_clip && ty < miny) miny = ty;
+               }
 
-             if (!o->clip.clipees && ty < miny) miny = ty;
+             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 (miny != obj->smart.parent->cur.bounding_box.y)
+        /* Update right limit */
+        if (!clip && x + w > obj->smart.parent->cur.bounding_box.x + obj->smart.parent->cur.bounding_box.w)
           {
-             obj->smart.parent->cur.bounding_box.h += obj->smart.parent->cur.bounding_box.y - miny;
-             obj->smart.parent->cur.bounding_box.y = miny;
+             obj->smart.parent->cur.bounding_box.w = x + w - obj->smart.parent->cur.bounding_box.x;
              propagate = EINA_TRUE;
           }
-     }
+        else if ((px + pw == obj->smart.parent->prev.bounding_box.x + obj->smart.parent->prev.bounding_box.w &&
+                  x + w < obj->smart.parent->cur.bounding_box.x + obj->smart.parent->cur.bounding_box.w)
+                 || (clip && x + w == obj->smart.parent->cur.bounding_box.x + obj->smart.parent->cur.bounding_box.w))
+          {
+             const Eina_Inlist *list;
+             const Evas_Object *o;
+             /* Evas_Coord maxw = obj->smart.parent->cur.geometry.x + obj->smart.parent->cur.geometry.w; */
+             Evas_Coord maxw = clip ? 0 : x + w;
 
-   /* Update right limit */
-   if (x + w > obj->smart.parent->cur.bounding_box.x + obj->smart.parent->cur.bounding_box.w)
-     {
-        obj->smart.parent->cur.bounding_box.w = x + w - obj->smart.parent->cur.bounding_box.x;
-        propagate = EINA_TRUE;
-     }
-   else if ((px + pw == obj->smart.parent->cur.bounding_box.x + obj->smart.parent->cur.bounding_box.w &&
-             x + w < obj->smart.parent->cur.bounding_box.x + obj->smart.parent->cur.bounding_box.w)
-            || (clip && x + w == obj->smart.parent->cur.bounding_box.x + obj->smart.parent->cur.bounding_box.w))
-     {
-        const Eina_Inlist *list;
-        const Evas_Object *o;
-        Evas_Coord maxw = obj->smart.parent->cur.geometry.x + obj->smart.parent->cur.geometry.w;
+             list = evas_object_smart_members_get_direct(obj->smart.parent);
+             EINA_INLIST_FOREACH(list, o)
+               {
+                  Evas_Coord tw;
 
-        list = evas_object_smart_members_get_direct(obj->smart.parent);
-        EINA_INLIST_FOREACH(list, o)
-          {
-             Evas_Coord tw = o->smart.smart
-               ? o->cur.bounding_box.x + o->cur.bounding_box.w
-               : o->cur.geometry.x + o->cur.geometry.w;
+                  if (o == obj) continue;
+                  tw = o->smart.smart
+                    ? o->cur.bounding_box.x + o->cur.bounding_box.w
+                    : o->cur.geometry.x + o->cur.geometry.w;
 
-             if (!o->clip.clipees && tw > maxw) maxw = tw;
+                  if (!o->clip.clipees && !o->is_static_clip && tw > maxw) maxw = tw;
+               }
+
+             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 (maxw != obj->smart.parent->cur.bounding_box.x + obj->smart.parent->cur.bounding_box.w)
+        /* Update bottom limit */
+        if (!clip && y + h > obj->smart.parent->cur.bounding_box.y + obj->smart.parent->cur.bounding_box.h)
           {
-             obj->smart.parent->cur.bounding_box.w = maxw - obj->smart.parent->cur.bounding_box.x;
+             obj->smart.parent->cur.bounding_box.h = y + h - obj->smart.parent->cur.bounding_box.y;
              propagate = EINA_TRUE;
           }
-     }
+        else if ((py + ph == obj->smart.parent->prev.bounding_box.y + obj->smart.parent->prev.bounding_box.h &&
+                  y + h < obj->smart.parent->cur.bounding_box.y + obj->smart.parent->cur.bounding_box.h) ||
+                 (clip && y + h == obj->smart.parent->cur.bounding_box.y + obj->smart.parent->cur.bounding_box.h))
+          {
+             const Eina_Inlist *list;
+             const Evas_Object *o;
+             /* Evas_Coord maxh = obj->smart.parent->cur.geometry.y + obj->smart.parent->cur.geometry.h; */
+             Evas_Coord maxh = clip ? 0 : y + h;
 
-   /* Update bottom limit */
-   if (y + h > obj->smart.parent->cur.bounding_box.y + obj->smart.parent->cur.bounding_box.h)
-     {
-        obj->smart.parent->cur.bounding_box.h = y + h - obj->smart.parent->cur.bounding_box.y;
-        propagate = EINA_TRUE;
-     }
-   else if ((py + ph == obj->smart.parent->cur.bounding_box.y + obj->smart.parent->cur.bounding_box.h &&
-             y + h < obj->smart.parent->cur.bounding_box.y + obj->smart.parent->cur.bounding_box.h) ||
-            (clip && y + h == obj->smart.parent->cur.bounding_box.y + obj->smart.parent->cur.bounding_box.h))
-     {
-        const Eina_Inlist *list;
-        const Evas_Object *o;
-        Evas_Coord maxh = obj->smart.parent->cur.geometry.y + obj->smart.parent->cur.geometry.h;
+             list = evas_object_smart_members_get_direct(obj->smart.parent);
+             EINA_INLIST_FOREACH(list, o)
+               {
+                  Evas_Coord th;
 
-        list = evas_object_smart_members_get_direct(obj->smart.parent);
-        EINA_INLIST_FOREACH(list, o)
-          {
-             Evas_Coord th = o->smart.smart
-               ? o->cur.bounding_box.y + o->cur.bounding_box.h
-               : o->cur.geometry.y + o->cur.geometry.h;
+                  if (o == obj) continue;
+                  th = o->smart.smart
+                    ? o->cur.bounding_box.y + o->cur.bounding_box.h
+                    : o->cur.geometry.y + o->cur.geometry.h;
 
-             if (!o->clip.clipees && th > maxh) maxh = th;
-          }
+                  if (!o->clip.clipees && th > maxh) maxh = th;
+               }
 
-        if (maxh != obj->smart.parent->cur.bounding_box.y + obj->smart.parent->cur.bounding_box.h)
+             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;
+               }
+          }
+     }
+   else
+     {
+        if (!clip)
           {
-             obj->smart.parent->cur.bounding_box.h = maxh - obj->smart.parent->cur.bounding_box.y;
+             obj->smart.parent->cur.bounding_box.x = x;
+             obj->smart.parent->cur.bounding_box.y = y;
+             obj->smart.parent->cur.bounding_box.w = w;
+             obj->smart.parent->cur.bounding_box.h = h;
+             obj->smart.parent->cur.valid_bounding_box = EINA_TRUE;
              propagate = EINA_TRUE;
           }
      }
index 69d7f3b..e643092 100644 (file)
@@ -170,6 +170,7 @@ evas_object_smart_member_add(Evas_Object *obj, Evas_Object *smart_obj)
    evas_object_mapped_clip_across_mark(obj);
    if (smart_obj->smart.smart->smart_class->member_add)
      smart_obj->smart.smart->smart_class->member_add(smart_obj, obj);
+   evas_object_update_bounding_box(obj);
 }
 
 EAPI void
@@ -907,6 +908,18 @@ static void
 evas_object_smart_render_pre(Evas_Object *obj)
 {
    if (obj->pre_render_done) return;
+   if (!obj->child_has_map)
+     {
+#if 0
+        if (obj->cur.bounding_box.w == obj->prev.bounding_box.w &&
+            obj->cur.bounding_box.h == obj->prev.bounding_box.h &&
+            (obj->cur.bounding_box.x != obj->prev.bounding_box.x ||
+             obj->cur.bounding_box.y != obj->prev.bounding_box.y))
+          {
+             fprintf(stderr, "Wouhou, I can detect moving smart object (%s)\n", evas_object_type_get(obj));
+          }
+#endif
+     }
    if ((obj->cur.map != obj->prev.map) ||
        (obj->cur.usemap != obj->prev.usemap))
      {
index af71e89..8acd338 100644 (file)
@@ -527,6 +527,8 @@ struct _Evas_Object
       Eina_Bool             have_clipees : 1;
       Eina_Bool             anti_alias : 1;
       Evas_Render_Op        render_op : 4;
+
+      Eina_Bool             valid_bounding_box : 1;
    } cur, prev;
 
    char                       *name;