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
diff options
context:
space:
mode:
authorJulian Eisel <julian@blender.org>2020-08-20 21:17:00 +0300
committerJulian Eisel <julian@blender.org>2020-08-20 21:22:47 +0300
commitb077de086e14291fe5f7cdf6d3564a8f1cfb9cb3 (patch)
tree0213703881116dd624c6ed782c4759d16c00ee41 /source/blender/editors/space_outliner
parent2e6d5e6c6bd43e8cb806919c7bdc62637d031ff1 (diff)
Outliner: Avoid rebuilding tree on selection/active changes
We can avoid the rather expensive outliner tree rebuilds and only redraw if nothing but the selection or active item changes. This should give a bit of speedup for heavy scenes. For this to work I had to correct a few notifiers, some were only sending selection/active change notifiers that actually did things like adding objects. I also added a more precise notifier type for when the active collection changes. At the notifier subtype/action level we're not even close to running out of bits, so this should be fine. Also had to correct a wrong notifier check (was using `&` rather than `==`).
Diffstat (limited to 'source/blender/editors/space_outliner')
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c16
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h4
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c12
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c1
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c10
-rw-r--r--source/blender/editors/space_outliner/outliner_utils.c18
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c18
7 files changed, 50 insertions, 29 deletions
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index cd2fcd8e2cf..8567dd4da13 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -193,13 +193,7 @@ static int outliner_item_openclose_modal(bContext *C, wmOperator *op, const wmEv
if (te->xs == data->x_location) {
outliner_item_openclose(te, data->open, false);
- /* Avoid rebuild if possible. */
- if (outliner_element_needs_rebuild_on_open_change(TREESTORE(te))) {
- ED_region_tag_redraw(region);
- }
- else {
- ED_region_tag_redraw_no_rebuild(region);
- }
+ outliner_tag_redraw_avoid_rebuild_on_open_change(space_outliner, region);
}
}
@@ -239,13 +233,7 @@ static int outliner_item_openclose_invoke(bContext *C, wmOperator *op, const wmE
(toggle_all && (outliner_flag_is_any_test(&te->subtree, TSE_CLOSED, 1)));
outliner_item_openclose(te, open, toggle_all);
- /* Avoid rebuild if possible. */
- if (outliner_element_needs_rebuild_on_open_change(TREESTORE(te))) {
- ED_region_tag_redraw(region);
- }
- else {
- ED_region_tag_redraw_no_rebuild(region);
- }
+ outliner_tag_redraw_avoid_rebuild_on_open_change(space_outliner, region);
/* Only toggle once for single click toggling */
if (event->type == LEFTMOUSE) {
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index 33dbbb274c0..9795bb73efe 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -237,7 +237,7 @@ void outliner_build_tree(struct Main *mainvar,
struct SpaceOutliner *space_outliner,
struct ARegion *region);
-bool outliner_element_needs_rebuild_on_open_change(const TreeStoreElem *tselem);
+bool outliner_mode_requires_always_rebuild(const struct SpaceOutliner *space_outliner);
typedef struct IDsSelectedData {
struct ListBase selected_array;
@@ -515,6 +515,8 @@ float outliner_restrict_columns_width(const struct SpaceOutliner *space_outliner
TreeElement *outliner_find_element_with_flag(const ListBase *lb, short flag);
bool outliner_is_element_visible(const TreeElement *te);
void outliner_scroll_view(struct ARegion *region, int delta_y);
+void outliner_tag_redraw_avoid_rebuild_on_open_change(const struct SpaceOutliner *space_outliner,
+ struct ARegion *region);
/* outliner_sync.c ---------------------------------------------- */
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 1ac1b46f0d1..d720747e953 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -1000,7 +1000,9 @@ static eOLDrawState tree_element_active_master_collection(bContext *C,
ViewLayer *view_layer = CTX_data_view_layer(C);
LayerCollection *layer_collection = view_layer->layer_collections.first;
BKE_layer_collection_activate(view_layer, layer_collection);
- WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+ /* A very precise notifier - ND_LAYER alone is quite vague, we want to avoid unnecessary work
+ * when only the active collection changes. */
+ WM_main_add_notifier(NC_SCENE | ND_LAYER | NS_LAYER_COLLECTION | NA_ACTIVATED, NULL);
}
return OL_DRAWSEL_NONE;
@@ -1022,7 +1024,9 @@ static eOLDrawState tree_element_active_layer_collection(bContext *C,
LayerCollection *layer_collection = te->directdata;
ViewLayer *view_layer = BKE_view_layer_find_from_collection(scene, layer_collection);
BKE_layer_collection_activate(view_layer, layer_collection);
- WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+ /* A very precise notifier - ND_LAYER alone is quite vague, we want to avoid unnecessary work
+ * when only the active collection changes. */
+ WM_main_add_notifier(NC_SCENE | ND_LAYER | NS_LAYER_COLLECTION | NA_ACTIVATED, NULL);
}
return OL_DRAWSEL_NONE;
@@ -1507,7 +1511,7 @@ static int outliner_box_select_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- ED_region_tag_redraw(region);
+ ED_region_tag_redraw_no_rebuild(region);
ED_outliner_select_sync_from_outliner(C, space_outliner);
@@ -1729,7 +1733,7 @@ static int outliner_walk_select_invoke(bContext *C, wmOperator *op, const wmEven
outliner_walk_scroll(region, active_te);
ED_outliner_select_sync_from_outliner(C, space_outliner);
- ED_region_tag_redraw(region);
+ outliner_tag_redraw_avoid_rebuild_on_open_change(space_outliner, region);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index 4b037327038..2a13f9d6a66 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -1630,6 +1630,7 @@ static int outliner_delete_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
ED_outliner_select_sync_from_object_tag(C);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index 60058c82283..9e3cbabf283 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -244,14 +244,12 @@ static TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
/* -------------------------------------------------------- */
/**
- * Check if an element type needs a full rebuild if the open/collapsed state changes.
- * These element types don't add children if collapsed.
- *
- * This current check isn't great really. A per element-type flag would be preferable.
+ * Check if a display mode needs a full rebuild if the open/collapsed state changes.
+ * Element types in these modes don't actually add children if collapsed, so the rebuild is needed.
*/
-bool outliner_element_needs_rebuild_on_open_change(const TreeStoreElem *tselem)
+bool outliner_mode_requires_always_rebuild(const SpaceOutliner *space_outliner)
{
- return ELEM(tselem->type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_KEYMAP);
+ return ELEM(space_outliner->outlinevis, SO_DATA_API);
}
/* special handling of hierarchical non-lib data */
diff --git a/source/blender/editors/space_outliner/outliner_utils.c b/source/blender/editors/space_outliner/outliner_utils.c
index 1da44b5e51e..25dc7bc271e 100644
--- a/source/blender/editors/space_outliner/outliner_utils.c
+++ b/source/blender/editors/space_outliner/outliner_utils.c
@@ -37,6 +37,7 @@
#include "ED_armature.h"
#include "ED_outliner.h"
+#include "ED_screen.h"
#include "UI_interface.h"
#include "UI_view2d.h"
@@ -455,6 +456,23 @@ void outliner_scroll_view(ARegion *region, int delta_y)
}
}
+/**
+ * The outliner should generally use #ED_region_tag_redraw_no_rebuild() to avoid unnecessary tree
+ * rebuilds. If elements are open or closed, we may still have to rebuild.
+ * Upon changing the open/closed state, call this to avoid rebuilds if possible.
+ */
+void outliner_tag_redraw_avoid_rebuild_on_open_change(const SpaceOutliner *space_outliner,
+ ARegion *region)
+{
+ /* Avoid rebuild if possible. */
+ if (outliner_mode_requires_always_rebuild(space_outliner)) {
+ ED_region_tag_redraw(region);
+ }
+ else {
+ ED_region_tag_redraw_no_rebuild(region);
+ }
+}
+
/* Get base of object under cursor. Used for eyedropper tool */
Base *ED_outliner_give_base_under_cursor(bContext *C, const int mval[2])
{
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index b14afed81dd..6854367d975 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -114,6 +114,8 @@ static void outliner_main_region_listener(wmWindow *UNUSED(win),
switch (wmn->data) {
case ND_OB_ACTIVE:
case ND_OB_SELECT:
+ ED_region_tag_redraw_no_rebuild(region);
+ break;
case ND_OB_VISIBLE:
case ND_OB_RENDER:
case ND_MODE:
@@ -121,15 +123,23 @@ static void outliner_main_region_listener(wmWindow *UNUSED(win),
case ND_FRAME:
case ND_RENDER_OPTIONS:
case ND_SEQUENCER:
- case ND_LAYER:
case ND_LAYER_CONTENT:
case ND_WORLD:
case ND_SCENEBROWSE:
ED_region_tag_redraw(region);
break;
+ case ND_LAYER:
+ /* Avoid rebuild if only the active collection changes */
+ if ((wmn->subtype == NS_LAYER_COLLECTION) && (wmn->action == NA_ACTIVATED)) {
+ ED_region_tag_redraw_no_rebuild(region);
+ break;
+ }
+
+ ED_region_tag_redraw(region);
+ break;
}
- if (wmn->action & NA_EDITED) {
- ED_region_tag_redraw(region);
+ if (wmn->action == NA_EDITED) {
+ ED_region_tag_redraw_no_rebuild(region);
}
break;
case NC_OBJECT:
@@ -181,7 +191,7 @@ static void outliner_main_region_listener(wmWindow *UNUSED(win),
case NC_MATERIAL:
switch (wmn->data) {
case ND_SHADING_LINKS:
- ED_region_tag_redraw(region);
+ ED_region_tag_redraw_no_rebuild(region);
break;
}
break;