evas: bugfix in evas_render of not maintaining changed flags on object correctly.

This bug is particularly visible in EFM video preview ( T 539 ). The problem is
that the logic for changed has evolved over time. At the beginning Evas canvas
was flat and could be handle in an array. It was then not using the changed flag
that much. This day, we are living with a tree and we need to propagate the
changed flag to the parent, so that when we walk them we only need to walk the
active objects and don't spend our time on branch that are completely static.

Sadly things did collide here. We remove all object that have been rendered
from the pending_objects array. That does include any smart object that was
processed even if one of the child was not. Once any of the child of that not
processed object is marked changed, it will be propagated up to the first
parent that is changed. As the parent of that one are marked as not changed
when evas_render walk the tree, he is blocked really early in the process and
never get a chance to detect that the child of a not changed object did change
and tada !

The fix is to add all the parent of all the object that are in the pending_objects
array back into the pending_objects list. So they will always be marked as changed.
Another alternative to this logic would have been to change pending_change to
filter out those and keep them around. I choose the first solution as I think it
will be more robust to catch all the parent in all case.
This commit is contained in:
Cedric Bail 2013-12-03 16:23:05 +09:00
parent 7cac8bceef
commit f90803aa2f
1 changed files with 16 additions and 1 deletions

View File

@ -2048,6 +2048,21 @@ evas_render_updates_internal(Evas *eo_e,
them from the pending list. */
eina_array_remove(&e->pending_objects, pending_change, NULL);
/* Reinsert parent of changed object in the pending changed state */
for (i = 0; i < e->pending_objects.count; ++i)
{
obj = eina_array_data_get(&e->pending_objects, i);
eo_obj = obj->object;
if (obj->smart.parent)
{
Evas_Object_Protected_Data *smart_parent;
smart_parent = eo_data_scope_get(obj->smart.parent,
EVAS_OBJ_CLASS);
evas_object_change(obj->smart.parent, smart_parent);
}
}
for (i = 0; i < e->render_objects.count; ++i)
{
obj = eina_array_data_get(&e->render_objects, i);
@ -2055,7 +2070,7 @@ evas_render_updates_internal(Evas *eo_e,
obj->pre_render_done = EINA_FALSE;
if ((obj->changed) && (do_draw))
{
obj->func->render_post(eo_obj, obj, obj->private_data);
obj->func->render_post(eo_obj, obj, obj->private_data);
obj->restack = EINA_FALSE;
evas_object_change_reset(eo_obj);
}