From 3333544ed6e49b0e466e1487e5811dc254df52c0 Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Thu, 7 Jun 2012 07:10:36 +0000 Subject: [PATCH] evas: delay O(n) update of the bounding box until we really need it. SVN revision: 71773 --- legacy/evas/src/lib/canvas/evas_events.c | 2 + legacy/evas/src/lib/canvas/evas_object_main.c | 69 +----------- .../evas/src/lib/canvas/evas_object_smart.c | 102 ++++++++++++++++++ legacy/evas/src/lib/include/evas_private.h | 2 + 4 files changed, 107 insertions(+), 68 deletions(-) diff --git a/legacy/evas/src/lib/canvas/evas_events.c b/legacy/evas/src/lib/canvas/evas_events.c index d90d9973ca..a3d90eda74 100644 --- a/legacy/evas/src/lib/canvas/evas_events.c +++ b/legacy/evas/src/lib/canvas/evas_events.c @@ -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 && diff --git a/legacy/evas/src/lib/canvas/evas_object_main.c b/legacy/evas/src/lib/canvas/evas_object_main.c index f0da75ef54..3b2fc8033a 100644 --- a/legacy/evas/src/lib/canvas/evas_object_main.c +++ b/legacy/evas/src/lib/canvas/evas_object_main.c @@ -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 diff --git a/legacy/evas/src/lib/canvas/evas_object_smart.c b/legacy/evas/src/lib/canvas/evas_object_smart.c index 9337551500..c32730727a 100644 --- a/legacy/evas/src/lib/canvas/evas_object_smart.c +++ b/legacy/evas/src/lib/canvas/evas_object_smart.c @@ -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) diff --git a/legacy/evas/src/lib/include/evas_private.h b/legacy/evas/src/lib/include/evas_private.h index 6e9a8205d7..30e4274229 100644 --- a/legacy/evas/src/lib/include/evas_private.h +++ b/legacy/evas/src/lib/include/evas_private.h @@ -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);