evas: delay O(n) update of the bounding box until we really need it.

SVN revision: 71773
This commit is contained in:
Cedric BAIL 2012-06-07 07:10:36 +00:00
parent e14550b58c
commit 3333544ed6
4 changed files with 107 additions and 68 deletions

View 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 &&

View 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

View 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)

View 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);