[Bf-blender-cvs] [c2a6c3a4e24] blender-v3.3-release: Outliner: Refactor how lazy-building of children is done

Julian Eisel noreply at git.blender.org
Fri Aug 19 22:24:04 CEST 2022


Commit: c2a6c3a4e24193893626ebbf07b0f02ce250cc61
Author: Julian Eisel
Date:   Fri Aug 19 21:56:09 2022 +0200
Branches: blender-v3.3-release
https://developer.blender.org/rBc2a6c3a4e24193893626ebbf07b0f02ce250cc61

Outliner: Refactor how lazy-building of children is done

Makes the lazy-building (where children are only built when the parent
isn't collapsed) more generic, so more display modes can use it. So far
this was hardcoded for the "Data API" display mode.

This will be used to work around a big performance issue with the
Library Overrides Hierachies view in a complex production file, see
following commit.

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

M	source/blender/editors/space_outliner/outliner_draw.cc
M	source/blender/editors/space_outliner/outliner_edit.cc
M	source/blender/editors/space_outliner/outliner_intern.hh
M	source/blender/editors/space_outliner/outliner_select.cc
M	source/blender/editors/space_outliner/outliner_tree.cc
M	source/blender/editors/space_outliner/outliner_utils.cc
M	source/blender/editors/space_outliner/tree/tree_display.cc
M	source/blender/editors/space_outliner/tree/tree_display.hh
M	source/blender/editors/space_outliner/tree/tree_display_data.cc
M	source/blender/editors/space_outliner/tree/tree_element_rna.cc

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

diff --git a/source/blender/editors/space_outliner/outliner_draw.cc b/source/blender/editors/space_outliner/outliner_draw.cc
index f8fbddd6d9d..e8f205a711e 100644
--- a/source/blender/editors/space_outliner/outliner_draw.cc
+++ b/source/blender/editors/space_outliner/outliner_draw.cc
@@ -3339,7 +3339,7 @@ static void outliner_draw_tree_element(bContext *C,
       /* Scene collection in view layer can't expand/collapse. */
     }
     else if (te->subtree.first || ((tselem->type == TSE_SOME_ID) && (te->idcode == ID_SCE)) ||
-             (te->flag & TE_LAZY_CLOSED)) {
+             (te->flag & TE_PRETEND_HAS_CHILDREN)) {
       /* Open/close icon, only when sub-levels, except for scene. */
       int icon_x = startx;
 
diff --git a/source/blender/editors/space_outliner/outliner_edit.cc b/source/blender/editors/space_outliner/outliner_edit.cc
index 16da4f7b1dd..3b12f777572 100644
--- a/source/blender/editors/space_outliner/outliner_edit.cc
+++ b/source/blender/editors/space_outliner/outliner_edit.cc
@@ -144,14 +144,10 @@ void OUTLINER_OT_highlight_update(wmOperatorType *ot)
 /** \name Toggle Open/Closed Operator
  * \{ */
 
-void outliner_item_openclose(SpaceOutliner *space_outliner,
-                             TreeElement *te,
-                             bool open,
-                             bool toggle_all)
-{
-  /* Prevent opening leaf elements in the tree unless in the Data API display mode because in that
-   * mode subtrees are empty unless expanded. */
-  if (space_outliner->outlinevis != SO_DATA_API && BLI_listbase_is_empty(&te->subtree)) {
+void outliner_item_openclose(TreeElement *te, bool open, bool toggle_all)
+{
+  /* Only allow opening elements with children.  */
+  if (!(te->flag & TE_PRETEND_HAS_CHILDREN) && BLI_listbase_is_empty(&te->subtree)) {
     return;
   }
 
@@ -198,7 +194,7 @@ static int outliner_item_openclose_modal(bContext *C, wmOperator *op, const wmEv
 
       /* Only toggle openclose on the same level as the first clicked element */
       if (te->xs == data->x_location) {
-        outliner_item_openclose(space_outliner, te, data->open, false);
+        outliner_item_openclose(te, data->open, false);
 
         outliner_tag_redraw_avoid_rebuild_on_open_change(space_outliner, region);
       }
@@ -242,7 +238,7 @@ static int outliner_item_openclose_invoke(bContext *C, wmOperator *op, const wmE
     const bool open = (tselem->flag & TSE_CLOSED) ||
                       (toggle_all && (outliner_flag_is_any_test(&te->subtree, TSE_CLOSED, 1)));
 
-    outliner_item_openclose(space_outliner, te, open, toggle_all);
+    outliner_item_openclose(te, open, toggle_all);
     outliner_tag_redraw_avoid_rebuild_on_open_change(space_outliner, region);
 
     /* Only toggle once for single click toggling */
diff --git a/source/blender/editors/space_outliner/outliner_intern.hh b/source/blender/editors/space_outliner/outliner_intern.hh
index 5362782dd84..46585289b8c 100644
--- a/source/blender/editors/space_outliner/outliner_intern.hh
+++ b/source/blender/editors/space_outliner/outliner_intern.hh
@@ -153,7 +153,10 @@ enum {
   /* Closed items display their children as icon within the row. TE_ICONROW is for
    * these child-items that are visible but only within the row of the closed parent. */
   TE_ICONROW = (1 << 1),
-  TE_LAZY_CLOSED = (1 << 2),
+  /** Treat the element as if it had children, e.g. draw an icon to un-collapse it, even if it
+   * doesn't. Used where children are lazy-built only if the parent isn't collapsed (see
+   * #AbstractTreeDisplay::is_lazy_built()). */
+  TE_PRETEND_HAS_CHILDREN = (1 << 2),
   TE_FREE_NAME = (1 << 3),
   TE_DRAGGING = (1 << 4),
   TE_CHILD_NOT_IN_COLLECTION = (1 << 6),
@@ -276,11 +279,6 @@ struct TreeElement *outliner_add_collection_recursive(SpaceOutliner *space_outli
 
 bool outliner_requires_rebuild_on_select_or_active_change(
     const struct SpaceOutliner *space_outliner);
-/**
- * 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_requires_rebuild_on_open_change(const struct SpaceOutliner *space_outliner);
 
 typedef struct IDsSelectedData {
   struct ListBase selected_array;
@@ -461,10 +459,7 @@ void outliner_set_coordinates(const struct ARegion *region,
 /**
  * Open or close a tree element, optionally toggling all children recursively.
  */
-void outliner_item_openclose(struct SpaceOutliner *space_outliner,
-                             TreeElement *te,
-                             bool open,
-                             bool toggle_all);
+void outliner_item_openclose(TreeElement *te, bool open, bool toggle_all);
 
 /* outliner_dragdrop.c */
 
diff --git a/source/blender/editors/space_outliner/outliner_select.cc b/source/blender/editors/space_outliner/outliner_select.cc
index 877e0fc325c..080274997db 100644
--- a/source/blender/editors/space_outliner/outliner_select.cc
+++ b/source/blender/editors/space_outliner/outliner_select.cc
@@ -1886,7 +1886,7 @@ static TreeElement *outliner_walk_left(SpaceOutliner *space_outliner,
   TreeStoreElem *tselem = TREESTORE(te);
 
   if (TSELEM_OPEN(tselem, space_outliner)) {
-    outliner_item_openclose(space_outliner, te, false, toggle_all);
+    outliner_item_openclose(te, false, toggle_all);
   }
   /* Only walk up a level if the element is closed and not toggling expand */
   else if (!toggle_all && te->parent) {
@@ -1907,7 +1907,7 @@ static TreeElement *outliner_walk_right(SpaceOutliner *space_outliner,
     te = reinterpret_cast<TreeElement *>(te->subtree.first);
   }
   else {
-    outliner_item_openclose(space_outliner, te, true, toggle_all);
+    outliner_item_openclose(te, true, toggle_all);
   }
 
   return te;
diff --git a/source/blender/editors/space_outliner/outliner_tree.cc b/source/blender/editors/space_outliner/outliner_tree.cc
index 3357a456e30..cc610d1e777 100644
--- a/source/blender/editors/space_outliner/outliner_tree.cc
+++ b/source/blender/editors/space_outliner/outliner_tree.cc
@@ -221,11 +221,6 @@ bool outliner_requires_rebuild_on_select_or_active_change(const SpaceOutliner *s
   return exclude_flags & (SO_FILTER_OB_STATE_SELECTED | SO_FILTER_OB_STATE_ACTIVE);
 }
 
-bool outliner_requires_rebuild_on_open_change(const SpaceOutliner *space_outliner)
-{
-  return ELEM(space_outliner->outlinevis, SO_DATA_API);
-}
-
 /* special handling of hierarchical non-lib data */
 static void outliner_add_bone(SpaceOutliner *space_outliner,
                               ListBase *lb,
diff --git a/source/blender/editors/space_outliner/outliner_utils.cc b/source/blender/editors/space_outliner/outliner_utils.cc
index 0db612ce6db..8cbaead3876 100644
--- a/source/blender/editors/space_outliner/outliner_utils.cc
+++ b/source/blender/editors/space_outliner/outliner_utils.cc
@@ -27,6 +27,7 @@
 #include "UI_view2d.h"
 
 #include "outliner_intern.hh"
+#include "tree/tree_display.hh"
 #include "tree/tree_iterator.hh"
 
 using namespace blender::ed::outliner;
@@ -455,7 +456,7 @@ void outliner_tag_redraw_avoid_rebuild_on_open_change(const SpaceOutliner *space
                                                       ARegion *region)
 {
   /* Avoid rebuild if possible. */
-  if (outliner_requires_rebuild_on_open_change(space_outliner)) {
+  if (space_outliner->runtime->tree_display->is_lazy_built()) {
     ED_region_tag_redraw(region);
   }
   else {
diff --git a/source/blender/editors/space_outliner/tree/tree_display.cc b/source/blender/editors/space_outliner/tree/tree_display.cc
index 6ab497b3fbb..fe4937829d6 100644
--- a/source/blender/editors/space_outliner/tree/tree_display.cc
+++ b/source/blender/editors/space_outliner/tree/tree_display.cc
@@ -50,4 +50,9 @@ bool AbstractTreeDisplay::supportsModeColumn() const
   return false;
 }
 
+bool AbstractTreeDisplay::is_lazy_built() const
+{
+  return false;
+}
+
 }  // namespace blender::ed::outliner
diff --git a/source/blender/editors/space_outliner/tree/tree_display.hh b/source/blender/editors/space_outliner/tree/tree_display.hh
index f8e35655c26..84eafcc3dd6 100644
--- a/source/blender/editors/space_outliner/tree/tree_display.hh
+++ b/source/blender/editors/space_outliner/tree/tree_display.hh
@@ -84,6 +84,15 @@ class AbstractTreeDisplay {
    */
   virtual bool supportsModeColumn() const;
 
+  /**
+   * Some trees may want to skip building children of collapsed parents. This should be done if the
+   * tree type may become very complex, which could cause noticeable slowdowns.
+   * Problem: This doesn't address performance issues while searching, since all elements are
+   * constructed for that. Trees of this type have to be rebuilt for any change to the collapsed
+   * state of any element.
+   */
+  virtual bool is_lazy_built() const;
+
  protected:
   /** All derived classes will need a handle to this, so storing it in the base for convenience. */
   SpaceOutliner &space_outliner_;
@@ -232,6 +241,8 @@ class TreeDisplayDataAPI final : public AbstractTreeDisplay {
   TreeDisplayDataAPI(SpaceOutliner &space_outliner);
 
   ListBase buildTree(const TreeSourceData &source_data) override;
+
+  bool is_lazy_built() const override;
 };
 
 }  // namespace blender::ed::outliner
diff --git a/source/blender/editors/space_outliner/tree/tree_display_data.cc b/source/blender/editors/space_outliner/tree/tree_display_data.cc
index bfeb8ce2bdc..3d9b927fbf1 100644
--- a/source/blender/editors/space_outliner/tree/tree_display_data.cc
+++ b/source/blender/editors/space_outliner/tree/tree_display_data.cc
@@ -42,4 +42,9 @@ ListBase TreeDisplayDataAPI::buildTree(const TreeSourceData &source_data)
   return tree;
 }
 
+bool TreeDisplayDataAPI::is_lazy_built() const
+{
+  return true;
+}
+
 }  // namespace blender::ed::outliner
diff --git a/source/blender/editors/space_outliner/tree/tree_element_rna.cc b/source/blender/editors/space_outliner/tree/tree_element_rna.cc
index 914104f1f06..31d7708793a 100644
--- a/source/blender/editors/space_outliner/tree/tree_element_rna.cc
+++ b/source/blender/editors/space_outliner/tree/tree_element_rna.cc
@@ -124,7 +124,7 @@ void TreeElementRNAStruct::expand(SpaceOutliner &space_outliner) const
     }
   }
   else if (tot) {
-    leg

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list