[Bf-blender-cvs] [bb3a021427f] master: Fix T101004: Crash when invisible object becomes visible

Sergey Sharybin noreply at git.blender.org
Tue Sep 13 11:00:42 CEST 2022


Commit: bb3a021427f2132f1db62a76eeca2ca4be1601da
Author: Sergey Sharybin
Date:   Mon Sep 12 16:30:07 2022 +0200
Branches: master
https://developer.blender.org/rBbb3a021427f2132f1db62a76eeca2ca4be1601da

Fix T101004: Crash when invisible object becomes visible

A regression since ac20970bc208

The issue was caused by depsgraph clearing all id->recalc flags
wrongly assuming that all IDs are fully evaluated.

This change makes it so the depsgraph becomes aware of possibly
incompletely evaluated IDs.

Differential Revision: https://developer.blender.org/D15946

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

M	source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
M	source/blender/depsgraph/intern/builder/deg_builder_nodes.h
M	source/blender/depsgraph/intern/depsgraph_tag.cc
M	source/blender/depsgraph/intern/eval/deg_eval_flush.cc
M	source/blender/depsgraph/intern/node/deg_node_id.cc
M	source/blender/depsgraph/intern/node/deg_node_id.h

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

diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index dcefb5528b2..324197118d2 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -155,12 +155,14 @@ IDNode *DepsgraphNodeBuilder::add_id_node(ID *id)
   IDComponentsMask previously_visible_components_mask = 0;
   uint32_t previous_eval_flags = 0;
   DEGCustomDataMeshMasks previous_customdata_masks;
+  int id_invisible_recalc = 0;
   IDInfo *id_info = id_info_hash_.lookup_default(id->session_uuid, nullptr);
   if (id_info != nullptr) {
     id_cow = id_info->id_cow;
     previously_visible_components_mask = id_info->previously_visible_components_mask;
     previous_eval_flags = id_info->previous_eval_flags;
     previous_customdata_masks = id_info->previous_customdata_masks;
+    id_invisible_recalc = id_info->id_invisible_recalc;
     /* Tag ID info to not free the CoW ID pointer. */
     id_info->id_cow = nullptr;
   }
@@ -168,6 +170,7 @@ IDNode *DepsgraphNodeBuilder::add_id_node(ID *id)
   id_node->previously_visible_components_mask = previously_visible_components_mask;
   id_node->previous_eval_flags = previous_eval_flags;
   id_node->previous_customdata_masks = previous_customdata_masks;
+  id_node->id_invisible_recalc = id_invisible_recalc;
 
   /* NOTE: Zero number of components indicates that ID node was just created. */
   const bool is_newly_created = id_node->components.is_empty();
@@ -366,6 +369,7 @@ void DepsgraphNodeBuilder::begin_build()
     id_info->previously_visible_components_mask = id_node->visible_components_mask;
     id_info->previous_eval_flags = id_node->eval_flags;
     id_info->previous_customdata_masks = id_node->customdata_masks;
+    id_info->id_invisible_recalc = id_node->id_invisible_recalc;
     BLI_assert(!id_info_hash_.contains(id_node->id_orig_session_uuid));
     id_info_hash_.add_new(id_node->id_orig_session_uuid, id_info);
     id_node->id_cow = nullptr;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
index d5ac601ebff..29cca0a8ddd 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
@@ -250,6 +250,8 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder {
     IDComponentsMask previously_visible_components_mask;
     /* Special evaluation flag mask from the previous depsgraph. */
     uint32_t previous_eval_flags;
+    /* Recalculation flags which were not evaluated for the ID in the previous depsgraph. */
+    int id_invisible_recalc;
     /* Mesh CustomData mask from the previous depsgraph. */
     DEGCustomDataMeshMasks previous_customdata_masks;
   };
diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc
index cc742b98866..a8c8b4a6538 100644
--- a/source/blender/depsgraph/intern/depsgraph_tag.cc
+++ b/source/blender/depsgraph/intern/depsgraph_tag.cc
@@ -890,6 +890,13 @@ void DEG_ids_clear_recalc(Depsgraph *depsgraph, const bool backup)
   }
   /* Go over all ID nodes, clearing tags. */
   for (deg::IDNode *id_node : deg_graph->id_nodes) {
+    if (!id_node->is_enabled_on_eval) {
+      id_node->id_invisible_recalc |= id_node->id_cow->recalc;
+    }
+    else {
+      id_node->id_invisible_recalc = 0;
+    }
+
     if (backup) {
       id_node->id_cow_recalc_backup |= id_node->id_cow->recalc;
     }
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
index 30ee626f0f8..3f42d1a80c1 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
@@ -31,6 +31,7 @@
 #include "intern/debug/deg_debug.h"
 #include "intern/depsgraph.h"
 #include "intern/depsgraph_relation.h"
+#include "intern/depsgraph_tag.h"
 #include "intern/depsgraph_type.h"
 #include "intern/depsgraph_update.h"
 #include "intern/node/deg_node.h"
@@ -99,6 +100,18 @@ inline void flush_prepare(Depsgraph *graph)
 
 inline void flush_schedule_entrypoints(Depsgraph *graph, FlushQueue *queue)
 {
+  /* Something changed in the scene, so re-tag IDs with flags which were previously ignored due to
+   * ID being hidden. This will ensure the ID is properly evaluated when it becomes visible. */
+  for (IDNode *node : graph->id_nodes) {
+    if (node->id_invisible_recalc) {
+      graph_id_tag_update(graph->bmain,
+                          graph,
+                          node->id_orig,
+                          node->id_invisible_recalc,
+                          DEG_UPDATE_SOURCE_VISIBILITY);
+    }
+  }
+
   for (OperationNode *op_node : graph->entry_tags) {
     queue->push_back(op_node);
     op_node->scheduled = true;
diff --git a/source/blender/depsgraph/intern/node/deg_node_id.cc b/source/blender/depsgraph/intern/node/deg_node_id.cc
index 735d606ac9e..9a7d27808be 100644
--- a/source/blender/depsgraph/intern/node/deg_node_id.cc
+++ b/source/blender/depsgraph/intern/node/deg_node_id.cc
@@ -75,6 +75,7 @@ void IDNode::init(const ID *id, const char *UNUSED(subdata))
   has_base = false;
   is_user_modified = false;
   id_cow_recalc_backup = 0;
+  id_invisible_recalc = 0;
 
   visible_components_mask = 0;
   previously_visible_components_mask = 0;
diff --git a/source/blender/depsgraph/intern/node/deg_node_id.h b/source/blender/depsgraph/intern/node/deg_node_id.h
index 7f0a656cb8d..e9bbc816907 100644
--- a/source/blender/depsgraph/intern/node/deg_node_id.h
+++ b/source/blender/depsgraph/intern/node/deg_node_id.h
@@ -123,6 +123,9 @@ struct IDNode : public Node {
   /* Accumulate recalc flags from multiple update passes. */
   int id_cow_recalc_backup;
 
+  /* Flags which components were not evaluated due to ID being invisible. */
+  int id_invisible_recalc;
+
   IDComponentsMask visible_components_mask;
   IDComponentsMask previously_visible_components_mask;



More information about the Bf-blender-cvs mailing list