From c1e6197b2117c1d3607fef62dd4b0d13b75839c4 Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Wed, 7 Aug 2019 17:20:38 +0200 Subject: [PATCH] efl_ui_focus_manager_calc: optimize item deletion if there is high frequency adding and deleting of items, the deletion here can be quite heavy, this makes freeing a little bit faster. Reviewed-by: Cedric BAIL Differential Revision: https://phab.enlightenment.org/D9616 --- .../elementary/efl_ui_focus_manager_calc.c | 46 +++++++++++-------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/src/lib/elementary/efl_ui_focus_manager_calc.c b/src/lib/elementary/efl_ui_focus_manager_calc.c index 29b52f2eb6..aaa41fc90d 100644 --- a/src/lib/elementary/efl_ui_focus_manager_calc.c +++ b/src/lib/elementary/efl_ui_focus_manager_calc.c @@ -68,6 +68,7 @@ struct _Node{ } graph; Eina_Bool on_list : 1; + Eina_Bool unused : 1; }; #define T(n) (n->tree) @@ -237,42 +238,49 @@ node_item_free(Node *item) /*cleanup graph parts*/ //add all neighbors of the node to the dirty list - for(int i = EFL_UI_FOCUS_DIRECTION_UP; i < EFL_UI_FOCUS_DIRECTION_LAST; i++) + if (!item->unused) { - Node *partner; + for(int i = EFL_UI_FOCUS_DIRECTION_UP; i < EFL_UI_FOCUS_DIRECTION_LAST; i++) + { + Node *partner; #define MAKE_LIST_DIRTY(node, field) \ - EINA_LIST_FOREACH(DIRECTION_ACCESS(node, i).field, l, partner) \ - { \ - if (partner->type != NODE_TYPE_ONLY_LOGICAL) \ + EINA_LIST_FOREACH(DIRECTION_ACCESS(node, i).field, l, partner) \ { \ - dirty_add(obj, pd, partner); \ - dirty_added = EINA_TRUE; \ - } \ + if (partner->type != NODE_TYPE_ONLY_LOGICAL) \ + { \ + dirty_add(obj, pd, partner); \ + dirty_added = EINA_TRUE; \ + } \ + } + + MAKE_LIST_DIRTY(item, one_direction) + MAKE_LIST_DIRTY(item, cleanup_nodes) + + border_onedirection_cleanup(item, i); + border_onedirection_set(item, i, NULL); } - MAKE_LIST_DIRTY(item, one_direction) - MAKE_LIST_DIRTY(item, cleanup_nodes) - - border_onedirection_cleanup(item, i); - border_onedirection_set(item, i, NULL); } //the unregistering of a item should ever result in atleast a coords_dirty call - if (!dirty_added) + if (dirty_added) efl_event_callback_call(obj, EFL_UI_FOCUS_MANAGER_EVENT_COORDS_DIRTY, NULL); /*cleanup manager householdings*/ //remove from the focus stack - pd->focus_stack = eina_list_remove(pd->focus_stack, item); + + if (!item->unused) + pd->focus_stack = eina_list_remove(pd->focus_stack, item); //if this is the entry for redirect, NULL them out! if (pd->redirect_entry == item->focusable) pd->redirect_entry = NULL; //remove from the dirty parts - pd->dirty = eina_list_remove(pd->dirty, item); + if (item->on_list) + pd->dirty = eina_list_remove(pd->dirty, item); item->on_list = EINA_FALSE; /*merge tree items*/ @@ -375,7 +383,7 @@ dirty_flush_node(Efl_Ui_Focus_Manager *obj EINA_UNUSED, Efl_Ui_Focus_Manager_Cal Efl_Ui_Focus_Graph_Calc_Result result; efl_ui_focus_graph_calc(&pd->graph_ctx, eina_iterator_filter_new(eina_hash_iterator_data_new(pd->node_hash), _no_logical, NULL, NULL) , (Opaque_Graph_Member*) node, &result); - + node->unused = EINA_FALSE; for (int i = 0; i < 4; ++i) { Efl_Ui_Focus_Direction direction = -1; @@ -506,7 +514,7 @@ _register(Eo *obj, Efl_Ui_Focus_Manager_Calc_Data *pd, Efl_Ui_Focus_Object *chil node = node_new(child, obj); eina_hash_add(pd->node_hash, &child, node); - + node->unused = EINA_TRUE; //add the parent if (parent) { @@ -1496,6 +1504,7 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_manager_focus_set(Eo *obj, Efl_U //make sure this manager is in the chain of redirects _manager_in_chain_set(obj, pd); + node->unused = EINA_FALSE; node_type = node->type; new_focusable = node->focusable; @@ -1508,6 +1517,7 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_manager_focus_set(Eo *obj, Efl_U //remove the object from the list and add it again if (node_type == NODE_TYPE_NORMAL) { + EINA_SAFETY_ON_TRUE_RETURN(node->unused); pd->focus_stack = eina_list_remove(pd->focus_stack, node); pd->focus_stack = eina_list_append(pd->focus_stack, node); }