forked from enlightenment/efl
efl_ui/box: optimize position_set operations with boxes
if a box is moved and no other changes are made to the box or its children, e.g., if the box is scrolled, then there is no need to loop over the box's items repeatedly in order to accurately calculate all the item geometries and positions. instead, simply apply an offset from the last box calc position to each child item and handle the position changes more transparently this yields roughly a 12% perf improvement to the 'efl.ui.scroller simple' test and brings rendering up to nearly 60fps Reviewed-by: Cedric BAIL <cedric.bail@free.fr> Differential Revision: https://phab.enlightenment.org/D9342
This commit is contained in:
parent
ebcf5e0cd9
commit
d5da991bc5
|
@ -138,7 +138,7 @@ EOLIAN static void
|
|||
_efl_ui_box_efl_gfx_entity_size_set(Eo *obj, Efl_Ui_Box_Data *_pd EINA_UNUSED, Eina_Size2D sz)
|
||||
{
|
||||
efl_gfx_entity_size_set(efl_super(obj, MY_CLASS), sz);
|
||||
efl_canvas_group_change(obj);
|
||||
efl_pack_layout_request(obj);
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
|
@ -186,6 +186,7 @@ _efl_ui_box_efl_object_constructor(Eo *obj, Efl_Ui_Box_Data *pd)
|
|||
pd->dir = EFL_UI_LAYOUT_ORIENTATION_VERTICAL;
|
||||
pd->align.h = 0.5;
|
||||
pd->align.v = 0.5;
|
||||
pd->full_recalc = EINA_TRUE;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
@ -360,8 +361,9 @@ _efl_ui_box_efl_pack_linear_pack_index_get(Eo *obj EINA_UNUSED, Efl_Ui_Box_Data
|
|||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_ui_box_efl_pack_layout_layout_request(Eo *obj, Efl_Ui_Box_Data *pd EINA_UNUSED)
|
||||
_efl_ui_box_efl_pack_layout_layout_request(Eo *obj, Efl_Ui_Box_Data *pd)
|
||||
{
|
||||
pd->full_recalc = EINA_TRUE;
|
||||
efl_canvas_group_need_recalculate_set(obj, EINA_TRUE);
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,28 @@ _weight_sort_cb(const void *l1, const void *l2)
|
|||
return it2->weight_factor <= it1->weight_factor ? -1 : 1;
|
||||
}
|
||||
|
||||
/* this function performs a simplified layout when the box has changed position
|
||||
* but no other changes have occurred, e.g., when a box is being scrolled
|
||||
*/
|
||||
static void
|
||||
_efl_ui_box_layout_simple(Efl_Ui_Box *ui_box, Efl_Ui_Box_Data *pd)
|
||||
{
|
||||
Eo *child;
|
||||
Eina_List *l;
|
||||
Eina_Position2D pos = efl_gfx_entity_position_get(ui_box);
|
||||
|
||||
EINA_LIST_FOREACH(pd->children, l, child)
|
||||
{
|
||||
Eina_Position2D child_pos = efl_gfx_entity_position_get(child);
|
||||
|
||||
efl_gfx_entity_position_set(child,
|
||||
EINA_POSITION2D(pos.x - pd->last_pos.x + child_pos.x,
|
||||
pos.y - pd->last_pos.y + child_pos.y));
|
||||
}
|
||||
pd->last_pos = pos;
|
||||
efl_event_callback_call(ui_box, EFL_PACK_EVENT_LAYOUT_UPDATED, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
_efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Efl_Ui_Box_Data *pd)
|
||||
{
|
||||
|
@ -49,8 +71,14 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Efl_Ui_Box_Data *pd)
|
|||
efl_gfx_hint_size_restricted_min_set(ui_box, EINA_SIZE2D(0, 0));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pd->full_recalc)
|
||||
{
|
||||
_efl_ui_box_layout_simple(ui_box, pd);
|
||||
return;
|
||||
}
|
||||
_efl_ui_container_layout_init(ui_box, box_calc);
|
||||
pd->last_pos.x = box_calc[0].pos - box_calc[0].margin[0];
|
||||
pd->last_pos.y = box_calc[1].pos - box_calc[1].margin[0];
|
||||
|
||||
/* Item_Calc struct is currently 152 bytes.
|
||||
* this is pretty big to be allocating a huge number of, and we don't want to explode the stack
|
||||
|
@ -207,6 +235,7 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Efl_Ui_Box_Data *pd)
|
|||
want[1] += (box_calc[1].margin[0] + box_calc[1].margin[1]) +
|
||||
(box_calc[1].pad * (count - 1));
|
||||
|
||||
pd->full_recalc = EINA_FALSE;
|
||||
efl_gfx_hint_size_restricted_min_set(ui_box, EINA_SIZE2D(want[0], want[1]));
|
||||
|
||||
efl_event_callback_call(ui_box, EFL_PACK_EVENT_LAYOUT_UPDATED, NULL);
|
||||
|
|
|
@ -27,7 +27,10 @@ struct _Efl_Ui_Box_Data
|
|||
double h, v;
|
||||
} align;
|
||||
|
||||
Eina_Position2D last_pos;
|
||||
|
||||
Eina_Bool homogeneous : 1;
|
||||
Eina_Bool full_recalc : 1; //whether to force full recalc
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue