diff options
author | Julian Eisel <julian@blender.org> | 2022-06-13 16:38:03 +0300 |
---|---|---|
committer | Julian Eisel <julian@blender.org> | 2022-06-13 23:06:08 +0300 |
commit | afde12e066e2e38f0df4151e6d1e6e1c61bc6c94 (patch) | |
tree | 9264f3c1e66702e230fc7c0f4da993100c2b50e2 /source/blender/editors | |
parent | 988fc2493052adfe84e492776370132ff098c358 (diff) |
Outliner performance: Only expand sub-trees if needed
Before this, we would build the sub-trees of some elements, just to
remove them afterwards. In big files, this would sometimes build ten
thousands of elements unnecessarily. Now support not building those
sub-trees in the first place.
Performance tests in a Sprite Fright production file (release build):
- View Layer display mode, reduced Outliner tree rebuilding from ~45ms
to 12-17ms
- Library Overrides display mode, Hierarchies view, reduced tree
rebuilding from 5-6s(!) to 220ms
Diffstat (limited to 'source/blender/editors')
4 files changed, 17 insertions, 18 deletions
diff --git a/source/blender/editors/space_outliner/outliner_tree.cc b/source/blender/editors/space_outliner/outliner_tree.cc index e6098631a68..aa739758ecb 100644 --- a/source/blender/editors/space_outliner/outliner_tree.cc +++ b/source/blender/editors/space_outliner/outliner_tree.cc @@ -802,7 +802,8 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner, void *idv, TreeElement *parent, short type, - short index) + short index, + const bool expand) { ID *id = reinterpret_cast<ID *>(idv); @@ -894,10 +895,10 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner, te->idcode = GS(id->name); } - if (te->abstract_element && te->abstract_element->isExpandValid()) { + if (expand && te->abstract_element && te->abstract_element->isExpandValid()) { tree_element_expand(*te->abstract_element, *space_outliner); } - else if (type == TSE_SOME_ID) { + else if (expand && (type == TSE_SOME_ID)) { /* ID types not (fully) ported to new design yet. */ if (te->abstract_element->expandPoll(*space_outliner)) { outliner_add_id_contents(space_outliner, te, tselem, id); diff --git a/source/blender/editors/space_outliner/tree/tree_display_override_library_hierarchies.cc b/source/blender/editors/space_outliner/tree/tree_display_override_library_hierarchies.cc index 38025b58fd2..67798e978ab 100644 --- a/source/blender/editors/space_outliner/tree/tree_display_override_library_hierarchies.cc +++ b/source/blender/editors/space_outliner/tree/tree_display_override_library_hierarchies.cc @@ -34,13 +34,6 @@ TreeDisplayOverrideLibraryHierarchies::TreeDisplayOverrideLibraryHierarchies( { } -/* XXX Remove expanded subtree, we add our own items here. Expanding should probably be - * optional. */ -static void remove_expanded_children(TreeElement &te) -{ - outliner_free_tree(&te.subtree); -} - ListBase TreeDisplayOverrideLibraryHierarchies::buildTree(const TreeSourceData &source_data) { ListBase tree = {nullptr}; @@ -114,8 +107,7 @@ ListBase TreeDisplayOverrideLibraryHierarchies::build_hierarchy_for_lib_or_main( }); TreeElement *new_id_te = outliner_add_element( - &space_outliner_, &new_base_te->subtree, iter_id, new_base_te, TSE_SOME_ID, 0); - remove_expanded_children(*new_id_te); + &space_outliner_, &new_base_te->subtree, iter_id, new_base_te, TSE_SOME_ID, 0, false); build_hierarchy_for_ID(bmain, *iter_id, *tree_element_cast<TreeElementID>(new_id_te)); } @@ -193,8 +185,8 @@ static int build_hierarchy_foreach_ID_cb(LibraryIDLinkCallbackData *cb_data) &id, &build_data.parent_te->getLegacyElement(), TSE_SOME_ID, - 0); - remove_expanded_children(*new_te); + 0, + false); build_data.sibling_ids.add(&id); BuildHierarchyForeachIDCbData child_build_data{build_data.bmain, diff --git a/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc b/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc index 80b3365766a..c8869d90eca 100644 --- a/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc +++ b/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc @@ -271,14 +271,14 @@ void ObjectsChildrenBuilder::make_object_parent_hierarchy_collections() if (!found) { /* We add the child in the tree even if it is not in the collection. - * We deliberately clear its sub-tree though, to make it less prominent. */ + * We don't expand its sub-tree though, to make it less prominent. */ TreeElement *child_ob_tree_element = outliner_add_element(&outliner_, &parent_ob_tree_element->subtree, child, parent_ob_tree_element, TSE_SOME_ID, - 0); - outliner_free_tree(&child_ob_tree_element->subtree); + 0, + false); child_ob_tree_element->flag |= TE_CHILD_NOT_IN_COLLECTION; child_ob_tree_elements.append(child_ob_tree_element); } diff --git a/source/blender/editors/space_outliner/tree/tree_element.hh b/source/blender/editors/space_outliner/tree/tree_element.hh index 0dcd75d340d..1098068d628 100644 --- a/source/blender/editors/space_outliner/tree/tree_element.hh +++ b/source/blender/editors/space_outliner/tree/tree_element.hh @@ -94,13 +94,19 @@ class AbstractTreeElement { * \note "ID" is not always a real ID. * \note If child items are only added to the tree if the item is open, * the `TSE_` type _must_ be added to #outliner_element_needs_rebuild_on_open_change(). + * + * \param expand: If true, the element may add its own sub-tree. E.g. objects will list their + * animation data, object data, constraints, modifiers, ... This often adds visual + * noise, and can be expensive to add in big scenes. So prefer setting this to + * false. */ struct TreeElement *outliner_add_element(SpaceOutliner *space_outliner, ListBase *lb, void *idv, struct TreeElement *parent, short type, - short index); + short index, + const bool expand = true); void tree_element_expand(const AbstractTreeElement &tree_element, SpaceOutliner &space_outliner); |