summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Blumenkrantz <zmike@samsung.com>2019-07-17 13:12:23 -0400
committerCedric BAIL <cedric.bail@free.fr>2019-07-17 10:54:44 -0700
commitd5da991bc586980e9e0a3d0cac78b026a6b611d1 (patch)
treea7720a58111ab48b0b1d67e6f0319d066a481942
parentebcf5e0cd9688235609f95f33c366759eb66321d (diff)
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
-rw-r--r--src/lib/elementary/efl_ui_box.c6
-rw-r--r--src/lib/elementary/efl_ui_box_layout.c31
-rw-r--r--src/lib/elementary/efl_ui_box_private.h3
3 files changed, 37 insertions, 3 deletions
diff --git a/src/lib/elementary/efl_ui_box.c b/src/lib/elementary/efl_ui_box.c
index e9d31eb964..9db283ba6f 100644
--- a/src/lib/elementary/efl_ui_box.c
+++ b/src/lib/elementary/efl_ui_box.c
@@ -138,7 +138,7 @@ EOLIAN static void
138_efl_ui_box_efl_gfx_entity_size_set(Eo *obj, Efl_Ui_Box_Data *_pd EINA_UNUSED, Eina_Size2D sz) 138_efl_ui_box_efl_gfx_entity_size_set(Eo *obj, Efl_Ui_Box_Data *_pd EINA_UNUSED, Eina_Size2D sz)
139{ 139{
140 efl_gfx_entity_size_set(efl_super(obj, MY_CLASS), sz); 140 efl_gfx_entity_size_set(efl_super(obj, MY_CLASS), sz);
141 efl_canvas_group_change(obj); 141 efl_pack_layout_request(obj);
142} 142}
143 143
144EOLIAN static void 144EOLIAN static void
@@ -186,6 +186,7 @@ _efl_ui_box_efl_object_constructor(Eo *obj, Efl_Ui_Box_Data *pd)
186 pd->dir = EFL_UI_LAYOUT_ORIENTATION_VERTICAL; 186 pd->dir = EFL_UI_LAYOUT_ORIENTATION_VERTICAL;
187 pd->align.h = 0.5; 187 pd->align.h = 0.5;
188 pd->align.v = 0.5; 188 pd->align.v = 0.5;
189 pd->full_recalc = EINA_TRUE;
189 190
190 return obj; 191 return obj;
191} 192}
@@ -360,8 +361,9 @@ _efl_ui_box_efl_pack_linear_pack_index_get(Eo *obj EINA_UNUSED, Efl_Ui_Box_Data
360} 361}
361 362
362EOLIAN static void 363EOLIAN static void
363_efl_ui_box_efl_pack_layout_layout_request(Eo *obj, Efl_Ui_Box_Data *pd EINA_UNUSED) 364_efl_ui_box_efl_pack_layout_layout_request(Eo *obj, Efl_Ui_Box_Data *pd)
364{ 365{
366 pd->full_recalc = EINA_TRUE;
365 efl_canvas_group_need_recalculate_set(obj, EINA_TRUE); 367 efl_canvas_group_need_recalculate_set(obj, EINA_TRUE);
366} 368}
367 369
diff --git a/src/lib/elementary/efl_ui_box_layout.c b/src/lib/elementary/efl_ui_box_layout.c
index d45532d1fc..8e22742385 100644
--- a/src/lib/elementary/efl_ui_box_layout.c
+++ b/src/lib/elementary/efl_ui_box_layout.c
@@ -27,6 +27,28 @@ _weight_sort_cb(const void *l1, const void *l2)
27 return it2->weight_factor <= it1->weight_factor ? -1 : 1; 27 return it2->weight_factor <= it1->weight_factor ? -1 : 1;
28} 28}
29 29
30/* this function performs a simplified layout when the box has changed position
31 * but no other changes have occurred, e.g., when a box is being scrolled
32 */
33static void
34_efl_ui_box_layout_simple(Efl_Ui_Box *ui_box, Efl_Ui_Box_Data *pd)
35{
36 Eo *child;
37 Eina_List *l;
38 Eina_Position2D pos = efl_gfx_entity_position_get(ui_box);
39
40 EINA_LIST_FOREACH(pd->children, l, child)
41 {
42 Eina_Position2D child_pos = efl_gfx_entity_position_get(child);
43
44 efl_gfx_entity_position_set(child,
45 EINA_POSITION2D(pos.x - pd->last_pos.x + child_pos.x,
46 pos.y - pd->last_pos.y + child_pos.y));
47 }
48 pd->last_pos = pos;
49 efl_event_callback_call(ui_box, EFL_PACK_EVENT_LAYOUT_UPDATED, NULL);
50}
51
30void 52void
31_efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Efl_Ui_Box_Data *pd) 53_efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Efl_Ui_Box_Data *pd)
32{ 54{
@@ -49,8 +71,14 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Efl_Ui_Box_Data *pd)
49 efl_gfx_hint_size_restricted_min_set(ui_box, EINA_SIZE2D(0, 0)); 71 efl_gfx_hint_size_restricted_min_set(ui_box, EINA_SIZE2D(0, 0));
50 return; 72 return;
51 } 73 }
52 74 if (!pd->full_recalc)
75 {
76 _efl_ui_box_layout_simple(ui_box, pd);
77 return;
78 }
53 _efl_ui_container_layout_init(ui_box, box_calc); 79 _efl_ui_container_layout_init(ui_box, box_calc);
80 pd->last_pos.x = box_calc[0].pos - box_calc[0].margin[0];
81 pd->last_pos.y = box_calc[1].pos - box_calc[1].margin[0];
54 82
55 /* Item_Calc struct is currently 152 bytes. 83 /* Item_Calc struct is currently 152 bytes.
56 * this is pretty big to be allocating a huge number of, and we don't want to explode the stack 84 * 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)
207 want[1] += (box_calc[1].margin[0] + box_calc[1].margin[1]) + 235 want[1] += (box_calc[1].margin[0] + box_calc[1].margin[1]) +
208 (box_calc[1].pad * (count - 1)); 236 (box_calc[1].pad * (count - 1));
209 237
238 pd->full_recalc = EINA_FALSE;
210 efl_gfx_hint_size_restricted_min_set(ui_box, EINA_SIZE2D(want[0], want[1])); 239 efl_gfx_hint_size_restricted_min_set(ui_box, EINA_SIZE2D(want[0], want[1]));
211 240
212 efl_event_callback_call(ui_box, EFL_PACK_EVENT_LAYOUT_UPDATED, NULL); 241 efl_event_callback_call(ui_box, EFL_PACK_EVENT_LAYOUT_UPDATED, NULL);
diff --git a/src/lib/elementary/efl_ui_box_private.h b/src/lib/elementary/efl_ui_box_private.h
index 47400df3fc..4cb94c5d8f 100644
--- a/src/lib/elementary/efl_ui_box_private.h
+++ b/src/lib/elementary/efl_ui_box_private.h
@@ -27,7 +27,10 @@ struct _Efl_Ui_Box_Data
27 double h, v; 27 double h, v;
28 } align; 28 } align;
29 29
30 Eina_Position2D last_pos;
31
30 Eina_Bool homogeneous : 1; 32 Eina_Bool homogeneous : 1;
33 Eina_Bool full_recalc : 1; //whether to force full recalc
31}; 34};
32 35
33#endif 36#endif