evas: let's try to determine the smallest possible size

for the bounding box. This vastly improve the time spent
during event propagation when playing with elm_genlist.


SVN revision: 70683
This commit is contained in:
Cedric BAIL 2012-05-03 03:58:27 +00:00
parent ef0e4dcaec
commit 9d405225fe
3 changed files with 142 additions and 96 deletions

View 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 */ 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 /* 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 */ 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) if (obj->smart.smart)
{ {
@ -490,6 +490,8 @@ evas_object_update_bounding_box(Evas_Object *obj)
* That's why we initialiaze min and max search to geometry of the parent object. * That's why we initialiaze min and max search to geometry of the parent object.
*/ */
if (obj->smart.parent->cur.valid_bounding_box)
{
/* Update left limit */ /* Update left limit */
if (!clip && x < obj->smart.parent->cur.bounding_box.x) if (!clip && x < obj->smart.parent->cur.bounding_box.x)
{ {
@ -497,19 +499,23 @@ evas_object_update_bounding_box(Evas_Object *obj)
obj->smart.parent->cur.bounding_box.x = x; obj->smart.parent->cur.bounding_box.x = x;
propagate = EINA_TRUE; propagate = EINA_TRUE;
} }
else if ((px == obj->smart.parent->cur.bounding_box.x && x > obj->smart.parent->cur.bounding_box.x) 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)) || (clip && x == obj->smart.parent->cur.bounding_box.x))
{ {
const Eina_Inlist *list; const Eina_Inlist *list;
const Evas_Object *o; const Evas_Object *o;
Evas_Coord minx = obj->smart.parent->cur.geometry.x; /* Evas_Coord minx = obj->smart.parent->cur.geometry.x; */
Evas_Coord minx = clip ? obj->layer->evas->output.w : x;
list = evas_object_smart_members_get_direct(obj->smart.parent); list = evas_object_smart_members_get_direct(obj->smart.parent);
EINA_INLIST_FOREACH(list, o) EINA_INLIST_FOREACH(list, o)
{ {
Evas_Coord tx = o->smart.smart ? o->cur.bounding_box.x : o->cur.geometry.x; Evas_Coord tx;
if (!o->clip.clipees && tx < minx) minx = 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) if (minx != obj->smart.parent->cur.bounding_box.x)
@ -521,25 +527,29 @@ evas_object_update_bounding_box(Evas_Object *obj)
} }
/* Update top limit */ /* Update top limit */
if (y < obj->smart.parent->cur.bounding_box.y) if (!clip && 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.h += obj->smart.parent->cur.bounding_box.x - x;
obj->smart.parent->cur.bounding_box.y = y; obj->smart.parent->cur.bounding_box.y = y;
propagate = EINA_TRUE; propagate = EINA_TRUE;
} }
else if ((py == obj->smart.parent->cur.bounding_box.y && y > obj->smart.parent->cur.bounding_box.y) 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)) || (clip && y == obj->smart.parent->cur.bounding_box.y))
{ {
const Eina_Inlist *list; const Eina_Inlist *list;
const Evas_Object *o; const Evas_Object *o;
Evas_Coord miny = obj->smart.parent->cur.geometry.y; /* Evas_Coord miny = obj->smart.parent->cur.geometry.y; */
Evas_Coord miny = clip ? obj->layer->evas->output.h : y;
list = evas_object_smart_members_get_direct(obj->smart.parent); list = evas_object_smart_members_get_direct(obj->smart.parent);
EINA_INLIST_FOREACH(list, o) EINA_INLIST_FOREACH(list, o)
{ {
Evas_Coord ty = o->smart.smart ? o->cur.bounding_box.y : o->cur.geometry.y; Evas_Coord ty;
if (!o->clip.clipees && ty < miny) miny = ty; 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 (miny != obj->smart.parent->cur.bounding_box.y) if (miny != obj->smart.parent->cur.bounding_box.y)
@ -551,27 +561,31 @@ evas_object_update_bounding_box(Evas_Object *obj)
} }
/* Update right limit */ /* Update right limit */
if (x + w > obj->smart.parent->cur.bounding_box.x + obj->smart.parent->cur.bounding_box.w) if (!clip && 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; obj->smart.parent->cur.bounding_box.w = x + w - obj->smart.parent->cur.bounding_box.x;
propagate = EINA_TRUE; propagate = EINA_TRUE;
} }
else if ((px + pw == obj->smart.parent->cur.bounding_box.x + obj->smart.parent->cur.bounding_box.w && 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) 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)) || (clip && x + w == obj->smart.parent->cur.bounding_box.x + obj->smart.parent->cur.bounding_box.w))
{ {
const Eina_Inlist *list; const Eina_Inlist *list;
const Evas_Object *o; const Evas_Object *o;
Evas_Coord maxw = obj->smart.parent->cur.geometry.x + obj->smart.parent->cur.geometry.w; /* Evas_Coord maxw = obj->smart.parent->cur.geometry.x + obj->smart.parent->cur.geometry.w; */
Evas_Coord maxw = clip ? 0 : x + w;
list = evas_object_smart_members_get_direct(obj->smart.parent); list = evas_object_smart_members_get_direct(obj->smart.parent);
EINA_INLIST_FOREACH(list, o) EINA_INLIST_FOREACH(list, o)
{ {
Evas_Coord tw = o->smart.smart Evas_Coord tw;
if (o == obj) continue;
tw = o->smart.smart
? o->cur.bounding_box.x + o->cur.bounding_box.w ? o->cur.bounding_box.x + o->cur.bounding_box.w
: o->cur.geometry.x + o->cur.geometry.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) if (maxw != obj->smart.parent->cur.bounding_box.x + obj->smart.parent->cur.bounding_box.w)
@ -582,23 +596,27 @@ evas_object_update_bounding_box(Evas_Object *obj)
} }
/* Update bottom limit */ /* Update bottom limit */
if (y + h > obj->smart.parent->cur.bounding_box.y + obj->smart.parent->cur.bounding_box.h) if (!clip && 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; obj->smart.parent->cur.bounding_box.h = y + h - obj->smart.parent->cur.bounding_box.y;
propagate = EINA_TRUE; propagate = EINA_TRUE;
} }
else if ((py + ph == obj->smart.parent->cur.bounding_box.y + obj->smart.parent->cur.bounding_box.h && 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) || 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)) (clip && y + h == obj->smart.parent->cur.bounding_box.y + obj->smart.parent->cur.bounding_box.h))
{ {
const Eina_Inlist *list; const Eina_Inlist *list;
const Evas_Object *o; const Evas_Object *o;
Evas_Coord maxh = obj->smart.parent->cur.geometry.y + obj->smart.parent->cur.geometry.h; /* Evas_Coord maxh = obj->smart.parent->cur.geometry.y + obj->smart.parent->cur.geometry.h; */
Evas_Coord maxh = clip ? 0 : y + h;
list = evas_object_smart_members_get_direct(obj->smart.parent); list = evas_object_smart_members_get_direct(obj->smart.parent);
EINA_INLIST_FOREACH(list, o) EINA_INLIST_FOREACH(list, o)
{ {
Evas_Coord th = o->smart.smart Evas_Coord th;
if (o == obj) continue;
th = o->smart.smart
? o->cur.bounding_box.y + o->cur.bounding_box.h ? o->cur.bounding_box.y + o->cur.bounding_box.h
: o->cur.geometry.y + o->cur.geometry.h; : o->cur.geometry.y + o->cur.geometry.h;
@ -611,6 +629,19 @@ evas_object_update_bounding_box(Evas_Object *obj)
propagate = EINA_TRUE; propagate = EINA_TRUE;
} }
} }
}
else
{
if (!clip)
{
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;
}
}
if (propagate) if (propagate)
evas_object_update_bounding_box(obj->smart.parent); evas_object_update_bounding_box(obj->smart.parent);

View File

@ -170,6 +170,7 @@ evas_object_smart_member_add(Evas_Object *obj, Evas_Object *smart_obj)
evas_object_mapped_clip_across_mark(obj); evas_object_mapped_clip_across_mark(obj);
if (smart_obj->smart.smart->smart_class->member_add) if (smart_obj->smart.smart->smart_class->member_add)
smart_obj->smart.smart->smart_class->member_add(smart_obj, obj); smart_obj->smart.smart->smart_class->member_add(smart_obj, obj);
evas_object_update_bounding_box(obj);
} }
EAPI void EAPI void
@ -907,6 +908,18 @@ static void
evas_object_smart_render_pre(Evas_Object *obj) evas_object_smart_render_pre(Evas_Object *obj)
{ {
if (obj->pre_render_done) return; 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) || if ((obj->cur.map != obj->prev.map) ||
(obj->cur.usemap != obj->prev.usemap)) (obj->cur.usemap != obj->prev.usemap))
{ {

View File

@ -527,6 +527,8 @@ struct _Evas_Object
Eina_Bool have_clipees : 1; Eina_Bool have_clipees : 1;
Eina_Bool anti_alias : 1; Eina_Bool anti_alias : 1;
Evas_Render_Op render_op : 4; Evas_Render_Op render_op : 4;
Eina_Bool valid_bounding_box : 1;
} cur, prev; } cur, prev;
char *name; char *name;