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
This commit is contained in:
Marcel Hollerbach 2020-07-29 12:01:43 +02:00
parent 4e24854f46
commit 8d034f08e8
4 changed files with 27 additions and 18 deletions

View File

@ -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

View File

@ -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)
{

View File

@ -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;

View File

@ -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;
}