[Bf-blender-cvs] [afde12e066e] master: Outliner performance: Only expand sub-trees if needed

Julian Eisel noreply at git.blender.org
Mon Jun 13 22:06:50 CEST 2022


Commit: afde12e066e2e38f0df4151e6d1e6e1c61bc6c94
Author: Julian Eisel
Date:   Mon Jun 13 15:38:03 2022 +0200
Branches: master
https://developer.blender.org/rBafde12e066e2e38f0df4151e6d1e6e1c61bc6c94

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

===================================================================

M	source/blender/editors/space_outliner/outliner_tree.cc
M	source/blender/editors/space_outliner/tree/tree_display_override_library_hierarchies.cc
M	source/blender/editors/space_outliner/tree/tree_display_view_layer.cc
M	source/blender/editors/space_outliner/tree/tree_element.hh

===================================================================

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);



More information about the Bf-blender-cvs mailing list