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:
authorSergey Sharybin <sergey@blender.org>2022-09-12 17:30:07 +0300
committerSergey Sharybin <sergey@blender.org>2022-09-13 12:00:37 +0300
commitbb3a021427f2132f1db62a76eeca2ca4be1601da (patch)
tree0532c51e51801104721b5d6204e8d2943c55c273
parenta45c36efae07f22dd1da1ebac728324aeafce85e (diff)
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
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc4
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.h2
-rw-r--r--source/blender/depsgraph/intern/depsgraph_tag.cc7
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_flush.cc13
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_id.cc1
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_id.h3
6 files changed, 30 insertions, 0 deletions
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;