From 8d034f08e8322921b1b059cc2e93e10f7b0550f1 Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Wed, 29 Jul 2020 12:01:43 +0200 Subject: [PATCH] efl_ui_focus_manager: reduce the amount of relying on events with this commit we are not replying on event invocations anymore, but rather on direct flag observation in the focus manager itself. This reduces the amount of events that are emitted as a consequence to elements beeing marked dirty segnificantly. startup time of elementary_test goes from 0.50 to 0.46s. Differential Revision: https://phab.enlightenment.org/D12072 --- src/lib/elementary/efl_ui_focus_manager.eo | 9 +++++++++ .../elementary/efl_ui_focus_manager_calc.c | 20 +++++++++++++++---- .../elementary/efl_ui_focus_manager_calc.eo | 1 + src/lib/elementary/efl_ui_focus_manager_sub.c | 15 +------------- 4 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/lib/elementary/efl_ui_focus_manager.eo b/src/lib/elementary/efl_ui_focus_manager.eo index dd95256b6d..080edaaf7a 100644 --- a/src/lib/elementary/efl_ui_focus_manager.eo +++ b/src/lib/elementary/efl_ui_focus_manager.eo @@ -96,6 +96,15 @@ interface Efl.Ui.Focus.Manager { over the border objects.]] } } + @property border_elements_changed { + [[Return $true if the border elements have changed since the last invocation of @.border_elements.get]] + get { + + } + values { + changed : bool; [[$true if there was a change, $false if not]] + } + } @property viewport_elements { [[Elements that are at the border of the viewport diff --git a/src/lib/elementary/efl_ui_focus_manager_calc.c b/src/lib/elementary/efl_ui_focus_manager_calc.c index 173a663d79..7fb80c38c2 100644 --- a/src/lib/elementary/efl_ui_focus_manager_calc.c +++ b/src/lib/elementary/efl_ui_focus_manager_calc.c @@ -85,6 +85,7 @@ typedef struct { int freeze; Node *root; + Eina_Bool border_elements_changed; } Efl_Ui_Focus_Manager_Calc_Data; static Eina_Mempool *_node_mempool; @@ -247,7 +248,6 @@ node_item_free(Node *item) Eina_List *l; Eo *obj = item->manager; FOCUS_DATA(obj); - Eina_Bool dirty_added = EINA_FALSE; /*cleanup graph parts*/ @@ -264,7 +264,7 @@ node_item_free(Node *item) if (partner->type != NODE_TYPE_ONLY_LOGICAL) \ { \ dirty_add(obj, pd, partner); \ - dirty_added = EINA_TRUE; \ + pd->border_elements_changed = EINA_TRUE; \ } \ } @@ -278,7 +278,7 @@ node_item_free(Node *item) } //the unregistering of a item should ever result in atleast a coords_dirty call - if (dirty_added) + if (pd->border_elements_changed) efl_event_callback_call(obj, EFL_UI_FOCUS_MANAGER_EVENT_COORDS_DIRTY, NULL); /*cleanup manager householdings*/ @@ -475,7 +475,9 @@ dirty_add(Eo *obj, Efl_Ui_Focus_Manager_Calc_Data *pd, Node *dirty) pd->dirty = eina_list_append(pd->dirty, dirty); dirty->on_list = EINA_TRUE; - efl_event_callback_call(obj, EFL_UI_FOCUS_MANAGER_EVENT_COORDS_DIRTY, NULL); + if (!pd->border_elements_changed) + efl_event_callback_call(obj, EFL_UI_FOCUS_MANAGER_EVENT_COORDS_DIRTY, NULL); + pd->border_elements_changed = EINA_TRUE; } @@ -924,6 +926,7 @@ _efl_ui_focus_manager_calc_efl_object_constructor(Eo *obj, Efl_Ui_Focus_Manager_ pd->node_hash = eina_hash_pointer_new(_free_node); pd->graph_ctx.offset_focusable = offsetof(Node, focusable); + pd->border_elements_changed = EINA_TRUE; return obj; } @@ -1110,9 +1113,18 @@ _elements_iterator_new(const Eo *obj, Efl_Ui_Focus_Manager_Calc_Data *pd) EOLIAN static Eina_Iterator* _efl_ui_focus_manager_calc_efl_ui_focus_manager_border_elements_get(const Eo *obj, Efl_Ui_Focus_Manager_Calc_Data *pd) { + pd->border_elements_changed = EINA_FALSE; return (Eina_Iterator*) _elements_iterator_new(obj, pd); } + +EOLIAN static Eina_Bool +_efl_ui_focus_manager_calc_efl_ui_focus_manager_border_elements_changed_get(const Eo *obj EINA_UNUSED, Efl_Ui_Focus_Manager_Calc_Data *pd) +{ + return pd->border_elements_changed; +} + + EOLIAN static Eina_Iterator* _efl_ui_focus_manager_calc_efl_ui_focus_manager_viewport_elements_get(const Eo *obj, Efl_Ui_Focus_Manager_Calc_Data *pd, Eina_Rect viewport) { diff --git a/src/lib/elementary/efl_ui_focus_manager_calc.eo b/src/lib/elementary/efl_ui_focus_manager_calc.eo index ed86b7b05c..d7f9124fe8 100644 --- a/src/lib/elementary/efl_ui_focus_manager_calc.eo +++ b/src/lib/elementary/efl_ui_focus_manager_calc.eo @@ -70,6 +70,7 @@ class @beta Efl.Ui.Focus.Manager_Calc extends Efl.Object implements Efl.Ui.Focus Efl.Ui.Focus.Manager.manager_focus {get; set;} Efl.Ui.Focus.Manager.redirect {set; get;} Efl.Ui.Focus.Manager.border_elements {get;} + Efl.Ui.Focus.Manager.border_elements_changed {get;} Efl.Ui.Focus.Manager.viewport_elements {get;} Efl.Ui.Focus.Manager.root {set; get;} Efl.Ui.Focus.Manager.request_subchild; diff --git a/src/lib/elementary/efl_ui_focus_manager_sub.c b/src/lib/elementary/efl_ui_focus_manager_sub.c index 7a2de74003..2d4a872d74 100644 --- a/src/lib/elementary/efl_ui_focus_manager_sub.c +++ b/src/lib/elementary/efl_ui_focus_manager_sub.c @@ -9,7 +9,6 @@ #define MY_DATA(o, p) Efl_Ui_Focus_Manager_Sub_Data *p = efl_data_scope_get(o, MY_CLASS); typedef struct { Efl_Ui_Focus_Manager *manager;//the manager where current_border is currently registered - Eina_Bool self_dirty; Eina_List *current_border; //the current set of widgets which is registered as borders } Efl_Ui_Focus_Manager_Sub_Data; @@ -94,7 +93,6 @@ _border_flush(Eo *obj, Efl_Ui_Focus_Manager_Sub_Data *pd) eina_list_free(pd->current_border); pd->current_border = selection; - pd->self_dirty = EINA_FALSE; } static void @@ -116,7 +114,7 @@ _parent_manager_pre_flush(void *data, const Efl_Event *ev EINA_UNUSED) { MY_DATA(data, pd); - if (!pd->self_dirty) return; //we are not interested + if (!efl_ui_focus_manager_border_elements_changed_get(data)) return; _border_flush(data, pd); } @@ -151,14 +149,6 @@ EFL_CALLBACKS_ARRAY_DEFINE(parent_manager, {EFL_UI_FOCUS_MANAGER_EVENT_DIRTY_LOGIC_FREEZE_CHANGED, _freeze_changed_cb} ); -static void -_self_manager_dirty(void *data EINA_UNUSED, const Efl_Event *ev EINA_UNUSED) -{ - MY_DATA(data, pd); - - pd->self_dirty = EINA_TRUE; -} - static void _logical_manager_change(void *data EINA_UNUSED, const Efl_Event *ev) { @@ -217,7 +207,6 @@ _manager_change(void *data, const Efl_Event *ev EINA_UNUSED) } EFL_CALLBACKS_ARRAY_DEFINE(self_manager, - {EFL_UI_FOCUS_MANAGER_EVENT_COORDS_DIRTY, _self_manager_dirty}, {EFL_UI_FOCUS_OBJECT_EVENT_FOCUS_PARENT_CHANGED, _logical_manager_change}, {EFL_UI_FOCUS_OBJECT_EVENT_FOCUS_MANAGER_CHANGED, _manager_change} ); @@ -228,8 +217,6 @@ _efl_ui_focus_manager_sub_efl_object_constructor(Eo *obj, Efl_Ui_Focus_Manager_S obj = efl_constructor(efl_super(obj, MY_CLASS)); efl_event_callback_array_add(obj, self_manager(), obj); - pd->self_dirty = EINA_TRUE; - return obj; }