forked from enlightenment/efl
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:
parent
ef0e4dcaec
commit
9d405225fe
|
@ -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;
|
||||
|
||||
if (!o->clip.clipees && 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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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)
|
||||
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))
|
||||
{
|
||||
Evas_Coord ty = o->smart.smart ? o->cur.bounding_box.y : o->cur.geometry.y;
|
||||
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 && ty < miny) miny = ty;
|
||||
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 (miny != obj->smart.parent->cur.bounding_box.y)
|
||||
/* Update top limit */
|
||||
if (!clip && y < 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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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)
|
||||
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))
|
||||
{
|
||||
Evas_Coord tw = o->smart.smart
|
||||
? o->cur.bounding_box.x + o->cur.bounding_box.w
|
||||
: o->cur.geometry.x + o->cur.geometry.w;
|
||||
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;
|
||||
|
||||
if (!o->clip.clipees && tw > maxw) maxw = tw;
|
||||
list = evas_object_smart_members_get_direct(obj->smart.parent);
|
||||
EINA_INLIST_FOREACH(list, o)
|
||||
{
|
||||
Evas_Coord 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)
|
||||
{
|
||||
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)
|
||||
/* 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.w = maxw - 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;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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)
|
||||
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))
|
||||
{
|
||||
Evas_Coord th = o->smart.smart
|
||||
? o->cur.bounding_box.y + o->cur.bounding_box.h
|
||||
: o->cur.geometry.y + o->cur.geometry.h;
|
||||
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;
|
||||
|
||||
if (!o->clip.clipees && th > maxh) maxh = th;
|
||||
list = evas_object_smart_members_get_direct(obj->smart.parent);
|
||||
EINA_INLIST_FOREACH(list, o)
|
||||
{
|
||||
Evas_Coord tw;
|
||||
|
||||
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 && !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 (maxh != obj->smart.parent->cur.bounding_box.y + obj->smart.parent->cur.bounding_box.h)
|
||||
/* 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.h = maxh - 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;
|
||||
}
|
||||
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;
|
||||
|
||||
list = evas_object_smart_members_get_direct(obj->smart.parent);
|
||||
EINA_INLIST_FOREACH(list, o)
|
||||
{
|
||||
Evas_Coord th;
|
||||
|
||||
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 (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.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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue