From 012917837649676e9ec4b9c2d7d4f7bdfd408739 Mon Sep 17 00:00:00 2001 From: Erik Date: Mon, 15 Nov 2021 17:10:53 +0100 Subject: UI: Use a map for block name lookups Use a map to speed up search for UI block names. Time to redraw the node editor was decreased from around 75-120ms to 40-70ms in a tree with many Geometry Nodes. Differential Revision: https://developer.blender.org/D13225 --- source/blender/editors/include/UI_interface.h | 4 ++-- source/blender/editors/interface/interface.c | 24 +++++++++++++++++++--- .../blender/editors/interface/interface_handlers.c | 3 +-- .../editors/interface/interface_region_popup.c | 2 +- .../interface/interface_template_search_menu.cc | 2 ++ source/blender/editors/screen/area.c | 6 +++--- source/blender/editors/screen/screen_edit.c | 3 +-- .../blender/editors/space_buttons/space_buttons.c | 2 +- 8 files changed, 32 insertions(+), 14 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index f0f267a3cb4..c587425c47f 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -731,8 +731,8 @@ bool UI_block_is_search_only(const uiBlock *block); void UI_block_set_search_only(uiBlock *block, bool search_only); void UI_block_free(const struct bContext *C, uiBlock *block); -void UI_blocklist_free(const struct bContext *C, struct ListBase *lb); -void UI_blocklist_free_inactive(const struct bContext *C, struct ListBase *lb); +void UI_blocklist_free(const struct bContext *C, struct ARegion *region); +void UI_blocklist_free_inactive(const struct bContext *C, struct ARegion *region); void UI_screen_free_active_but(const struct bContext *C, struct bScreen *screen); void UI_block_region_set(uiBlock *block, struct ARegion *region); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index c753c06b791..55fab04e9a4 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -37,6 +37,7 @@ #include "DNA_workspace_types.h" #include "BLI_alloca.h" +#include "BLI_ghash.h" #include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_rect.h" @@ -3521,22 +3522,35 @@ void UI_blocklist_draw(const bContext *C, const ListBase *lb) } /* can be called with C==NULL */ -void UI_blocklist_free(const bContext *C, ListBase *lb) +void UI_blocklist_free(const bContext *C, ARegion *region) { + ListBase *lb = ®ion->uiblocks; uiBlock *block; while ((block = BLI_pophead(lb))) { UI_block_free(C, block); } + if (region->runtime.block_name_map != NULL) { + BLI_ghash_free(region->runtime.block_name_map, NULL, NULL); + region->runtime.block_name_map = NULL; + } } -void UI_blocklist_free_inactive(const bContext *C, ListBase *lb) +void UI_blocklist_free_inactive(const bContext *C, ARegion *region) { + ListBase *lb = ®ion->uiblocks; + LISTBASE_FOREACH_MUTABLE (uiBlock *, block, lb) { if (!block->handle) { if (block->active) { block->active = false; } else { + if (region->runtime.block_name_map != NULL) { + uiBlock *b = BLI_ghash_lookup(region->runtime.block_name_map, block->name); + if (b == block) { + BLI_ghash_remove(region->runtime.block_name_map, b->name, NULL, NULL); + } + } BLI_remlink(lb, block); UI_block_free(C, block); } @@ -3552,7 +3566,10 @@ void UI_block_region_set(uiBlock *block, ARegion *region) /* each listbase only has one block with this name, free block * if is already there so it can be rebuilt from scratch */ if (lb) { - oldblock = BLI_findstring(lb, block->name, offsetof(uiBlock, name)); + if (region->runtime.block_name_map == NULL) { + region->runtime.block_name_map = BLI_ghash_str_new(__func__); + } + oldblock = (uiBlock *)BLI_ghash_lookup(region->runtime.block_name_map, block->name); if (oldblock) { oldblock->active = false; @@ -3562,6 +3579,7 @@ void UI_block_region_set(uiBlock *block, ARegion *region) /* at the beginning of the list! for dynamical menus/blocks */ BLI_addhead(lb, block); + BLI_ghash_reinsert(region->runtime.block_name_map, block->name, block, NULL, NULL); } block->oldblock = oldblock; diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 555b699872b..d18b3fdf505 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -11340,8 +11340,7 @@ static void ui_region_handler_remove(bContext *C, void *UNUSED(userdata)) return; } - UI_blocklist_free(C, ®ion->uiblocks); - + UI_blocklist_free(C, region); bScreen *screen = CTX_wm_screen(C); if (screen == NULL) { return; diff --git a/source/blender/editors/interface/interface_region_popup.c b/source/blender/editors/interface/interface_region_popup.c index 0e53100f91b..0f903bd4af9 100644 --- a/source/blender/editors/interface/interface_region_popup.c +++ b/source/blender/editors/interface/interface_region_popup.c @@ -743,7 +743,7 @@ uiBlock *ui_popup_block_refresh(bContext *C, if (block_old) { block->oldblock = block_old; UI_block_update_from_old(C, block); - UI_blocklist_free_inactive(C, ®ion->uiblocks); + UI_blocklist_free_inactive(C, region); } /* checks which buttons are visible, sets flags to prevent draw (do after region init) */ diff --git a/source/blender/editors/interface/interface_template_search_menu.cc b/source/blender/editors/interface/interface_template_search_menu.cc index 64468f4a812..f846eebb457 100644 --- a/source/blender/editors/interface/interface_template_search_menu.cc +++ b/source/blender/editors/interface/interface_template_search_menu.cc @@ -787,12 +787,14 @@ static MenuSearch_Data *menu_items_from_ui_create( } if (region) { + BLI_ghash_remove(region->runtime.block_name_map, sub_block->name, NULL, NULL); BLI_remlink(®ion->uiblocks, sub_block); } UI_block_free(nullptr, sub_block); } } if (region) { + BLI_ghash_remove(region->runtime.block_name_map, block->name, NULL, NULL); BLI_remlink(®ion->uiblocks, block); } UI_block_free(nullptr, block); diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 8523496bdbd..38eadf95bde 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -594,7 +594,7 @@ void ED_region_do_draw(bContext *C, ARegion *region) memset(®ion->drawrct, 0, sizeof(region->drawrct)); - UI_blocklist_free_inactive(C, ®ion->uiblocks); + UI_blocklist_free_inactive(C, region); if (area) { const bScreen *screen = WM_window_get_active_screen(win); @@ -1985,7 +1985,7 @@ void ED_area_init(wmWindowManager *wm, wmWindow *win, ScrArea *area) } else { /* prevent uiblocks to run */ - UI_blocklist_free(NULL, ®ion->uiblocks); + UI_blocklist_free(NULL, region); } /* Some AZones use View2D data which is only updated in region init, so call that first! */ @@ -3323,7 +3323,7 @@ bool ED_region_property_search(const bContext *C, } /* Free the panels and blocks, as they are only used for search. */ - UI_blocklist_free(C, ®ion->uiblocks); + UI_blocklist_free(C, region); UI_panels_free_instanced(C, region); BKE_area_region_panels_free(®ion->panels); diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index fa0cfd16817..3c8fb2e7446 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -1495,8 +1495,7 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *area, const * switching screens with tooltip open because region and tooltip * are no longer in the same screen */ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { - UI_blocklist_free(C, ®ion->uiblocks); - + UI_blocklist_free(C, region); if (region->regiontimer) { WM_event_remove_timer(wm, NULL, region->regiontimer); region->regiontimer = NULL; diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index b04291b7ab4..bc701bd7aa5 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -445,7 +445,7 @@ static void property_search_all_tabs(const bContext *C, i, property_search_for_context(C, region_copy, &sbuts_copy)); - UI_blocklist_free(C, ®ion_copy->uiblocks); + UI_blocklist_free(C, region_copy); } BKE_area_region_free(area_copy.type, region_copy); -- cgit v1.2.3