cedric pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=d5da991bc586980e9e0a3d0cac78b026a6b611d1

commit d5da991bc586980e9e0a3d0cac78b026a6b611d1
Author: Mike Blumenkrantz <zm...@samsung.com>
Date:   Wed Jul 17 13:12:23 2019 -0400

    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.b...@free.fr>
    Differential Revision: https://phab.enlightenment.org/D9342
---
 src/lib/elementary/efl_ui_box.c         |  6 ++++--
 src/lib/elementary/efl_ui_box_layout.c  | 31 ++++++++++++++++++++++++++++++-
 src/lib/elementary/efl_ui_box_private.h |  3 +++
 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
 _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);
 }
 
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)
    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);
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
       double h, v;
    } align;
 
+   Eina_Position2D last_pos;
+
    Eina_Bool homogeneous : 1;
+   Eina_Bool full_recalc : 1; //whether to force full recalc
 };
 
 #endif

-- 


Reply via email to