Fix #124335: Viewport compositor crash upon scene change

The viewport compositor crashes when the scene is changed in some
situations. That's because the viewport compositor tries to use node
tree data that was freed in the last depsgraph update, while it should
have invalidate those references based on the same depsgraph update.

The source of this issue is in the depsgraph itself. In particular, when
the depsgraph evaluation happens in two passes, the ID recalculate flags
are backed up for every pass then restored at the end of all passes,
however, this doesn't happen for the ID Type Update table. So whenever
evaluations happen in two passes, changes will not be propagated to
engines that require those information, like the viewport compositor
engine in that particular case.

To fix this, we backup and restore the ID Type Update table in a similar
manner to the ID recalculate flags.

Fixes #107235, #124335, #116142.

Pull Request: https://projects.blender.org/blender/blender/pulls/124409
This commit is contained in:
Omar Emara
2024-07-09 16:10:58 +02:00
committed by Omar Emara
parent 6d3b4f1c32
commit 0251db1447
3 changed files with 19 additions and 0 deletions
@@ -67,6 +67,7 @@ Depsgraph::Depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer, eEvaluati
{
BLI_spin_init(&lock);
memset(id_type_updated, 0, sizeof(id_type_updated));
memset(id_type_updated_backup, 0, sizeof(id_type_updated_backup));
memset(id_type_exist, 0, sizeof(id_type_exist));
memset(physics_relations, 0, sizeof(physics_relations));
@@ -108,6 +108,8 @@ struct Depsgraph {
/* Indicates which ID types were updated. */
char id_type_updated[INDEX_ID_MAX];
/* Accumulate id type updates from multiple update passes. */
char id_type_updated_backup[INDEX_ID_MAX];
/* Indicates type of IDs present in the depsgraph. */
char id_type_exist[INDEX_ID_MAX];
@@ -14,6 +14,7 @@
#include <cstring> /* required for memset */
#include <queue>
#include "BLI_index_range.hh"
#include "BLI_math_bits.h"
#include "BLI_task.h"
#include "BLI_utildefines.h"
@@ -968,6 +969,14 @@ void DEG_ids_clear_recalc(Depsgraph *depsgraph, const bool backup)
deg_graph_clear_id_recalc_flags(id_node->id_orig);
}
}
if (backup) {
for (const int64_t i : blender::IndexRange(INDEX_ID_MAX)) {
if (deg_graph->id_type_updated[i] != 0) {
deg_graph->id_type_updated_backup[i] = 1;
}
}
}
memset(deg_graph->id_type_updated, 0, sizeof(deg_graph->id_type_updated));
}
@@ -979,4 +988,11 @@ void DEG_ids_restore_recalc(Depsgraph *depsgraph)
id_node->id_cow->recalc |= id_node->id_cow_recalc_backup;
id_node->id_cow_recalc_backup = 0;
}
for (const int64_t i : blender::IndexRange(INDEX_ID_MAX)) {
if (deg_graph->id_type_updated_backup[i] != 0) {
deg_graph->id_type_updated[i] = 1;
}
}
memset(deg_graph->id_type_updated_backup, 0, sizeof(deg_graph->id_type_updated_backup));
}