Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorErik <ecke101@gmail.com>2021-11-15 19:10:53 +0300
committerErik <ecke101@gmail.com>2021-11-22 20:23:54 +0300
commit012917837649676e9ec4b9c2d7d4f7bdfd408739 (patch)
treec028b70718bf6312c5d7e64812d7198f7d867258 /source
parent55c82d8380ea3fd37a9d966fad10f42cc5b365d5 (diff)
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
Diffstat (limited to 'source')
-rw-r--r--source/blender/editors/include/UI_interface.h4
-rw-r--r--source/blender/editors/interface/interface.c24
-rw-r--r--source/blender/editors/interface/interface_handlers.c3
-rw-r--r--source/blender/editors/interface/interface_region_popup.c2
-rw-r--r--source/blender/editors/interface/interface_template_search_menu.cc2
-rw-r--r--source/blender/editors/screen/area.c6
-rw-r--r--source/blender/editors/screen/screen_edit.c3
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c2
-rw-r--r--source/blender/makesdna/DNA_screen_types.h3
9 files changed, 35 insertions, 14 deletions
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 = &region->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 = &region->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, &region->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, &region->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(&region->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(&region->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(&region->drawrct, 0, sizeof(region->drawrct));
- UI_blocklist_free_inactive(C, &region->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, &region->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, &region->uiblocks);
+ UI_blocklist_free(C, region);
UI_panels_free_instanced(C, region);
BKE_area_region_panels_free(&region->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, &region->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, &region_copy->uiblocks);
+ UI_blocklist_free(C, region_copy);
}
BKE_area_region_free(area_copy.type, region_copy);
diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index 03110f6e1be..f15767ff692 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -458,6 +458,9 @@ typedef struct ARegion_Runtime {
/* The offset needed to not overlap with window scrollbars. Only used by HUD regions for now. */
int offset_x, offset_y;
+
+ /* Maps uiBlock->name to uiBlock for faster lookups. */
+ struct GHash *block_name_map;
} ARegion_Runtime;
typedef struct ARegion {