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.vfx@gmail.com>2019-03-01 20:51:16 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2019-03-01 21:03:51 +0300
commitd16386e50bc104f9446a30e041a7b74f38b51ae9 (patch)
tree06a5211905abf63359e92e2da571481f6fd6d3ea
parentfaec3655d8bfddf510ee9330fa6c9511086ba79d (diff)
Fix T62087: Crash when rendering in Cycles
The issue was discovered only after recent changes, but roots back to much older changes. What was happening is scene's ID recalc flags where never cleared, which caused ensure_view_layer() to always run copy-on-write on the scene. This resulted in certain runtime data being cleared, without proper flag stored in the dependency graph. This was caused by ID recalc clear function checking whether any ID was tagged for recalc in that graph or not. This was happening due to all areas using DEG_id_type_tag() which can only set flags on the graph from viewport scenes, and could not inform render dependency graph. Now ID tyoe tagging is happening on per-graph level, which avoids possibility of flags running out of sync. In a bit longer term we also need to get rid of two functions which are clearing flags: DEG_id_type_tag() and deg_graph_clear_tags().
-rw-r--r--source/blender/depsgraph/DEG_depsgraph.h1
-rw-r--r--source/blender/depsgraph/intern/depsgraph_tag.cc30
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_flush.cc8
3 files changed, 23 insertions, 16 deletions
diff --git a/source/blender/depsgraph/DEG_depsgraph.h b/source/blender/depsgraph/DEG_depsgraph.h
index a7e2bcbe292..9770c7d49a3 100644
--- a/source/blender/depsgraph/DEG_depsgraph.h
+++ b/source/blender/depsgraph/DEG_depsgraph.h
@@ -126,6 +126,7 @@ void DEG_graph_id_tag_update(struct Main *bmain,
/* Mark a particular datablock type as having changing. This does
* not cause any updates but is used by external render engines to detect if for
* example a datablock was removed. */
+void DEG_graph_id_type_tag(struct Depsgraph *depsgraph, short id_type);
void DEG_id_type_tag(struct Main *bmain, short id_type);
void DEG_ids_clear_recalc(struct Main *bmain, Depsgraph *depsgraph);
diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc
index 788db521923..031ae7bb697 100644
--- a/source/blender/depsgraph/intern/depsgraph_tag.cc
+++ b/source/blender/depsgraph/intern/depsgraph_tag.cc
@@ -603,8 +603,11 @@ void graph_id_tag_update(Main *bmain,
update_source_as_string(update_source));
}
IDNode *id_node = (graph != NULL) ? graph->find_id_node(id)
- : NULL;
- DEG_id_type_tag(bmain, GS(id->name));
+ : NULL;
+ if (graph != NULL) {
+ DEG_graph_id_type_tag(reinterpret_cast<::Depsgraph*>(graph),
+ GS(id->name));
+ }
if (flag == 0) {
deg_graph_node_tag_zero(bmain, graph, id_node, update_source);
}
@@ -680,20 +683,24 @@ void DEG_graph_id_tag_update(struct Main *bmain,
}
/* Mark a particular datablock type as having changing. */
-void DEG_id_type_tag(Main *bmain, short id_type)
+void DEG_graph_id_type_tag(Depsgraph *depsgraph, short id_type)
{
if (id_type == ID_NT) {
/* Stupid workaround so parent datablocks of nested nodetree get looped
* over when we loop over tagged datablock types. */
- DEG_id_type_tag(bmain, ID_MA);
- DEG_id_type_tag(bmain, ID_TE);
- DEG_id_type_tag(bmain, ID_LA);
- DEG_id_type_tag(bmain, ID_WO);
- DEG_id_type_tag(bmain, ID_SCE);
+ DEG_graph_id_type_tag(depsgraph, ID_MA);
+ DEG_graph_id_type_tag(depsgraph, ID_TE);
+ DEG_graph_id_type_tag(depsgraph, ID_LA);
+ DEG_graph_id_type_tag(depsgraph, ID_WO);
+ DEG_graph_id_type_tag(depsgraph, ID_SCE);
}
+ const int id_type_index = BKE_idcode_to_index(id_type);
+ DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(depsgraph);
+ deg_graph->id_type_updated[id_type_index] = 1;
+}
- int id_type_index = BKE_idcode_to_index(id_type);
-
+void DEG_id_type_tag(Main *bmain, short id_type)
+{
LISTBASE_FOREACH (Scene *, scene, &bmain->scene) {
LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
Depsgraph *depsgraph =
@@ -701,8 +708,7 @@ void DEG_id_type_tag(Main *bmain, short id_type)
view_layer,
false);
if (depsgraph != NULL) {
- DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(depsgraph);
- deg_graph->id_type_updated[id_type_index] = 1;
+ DEG_graph_id_type_tag(depsgraph, id_type);
}
}
}
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
index a5bfab2bce1..5498e75ade0 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
@@ -237,15 +237,15 @@ void flush_engine_data_update(ID *id)
}
/* NOTE: It will also accumulate flags from changed components. */
-void flush_editors_id_update(Main *bmain,
- Depsgraph *graph,
+void flush_editors_id_update(Depsgraph *graph,
const DEGEditorUpdateContext *update_ctx)
{
for (IDNode *id_node : graph->id_nodes) {
if (id_node->custom_flags != ID_STATE_MODIFIED) {
continue;
}
- DEG_id_type_tag(bmain, GS(id_node->id_orig->name));
+ DEG_graph_id_type_tag(reinterpret_cast<::Depsgraph*>(graph),
+ GS(id_node->id_orig->name));
/* TODO(sergey): Do we need to pass original or evaluated ID here? */
ID *id_orig = id_node->id_orig;
ID *id_cow = id_node->id_cow;
@@ -398,7 +398,7 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph)
}
}
/* Inform editors about all changes. */
- flush_editors_id_update(bmain, graph, &update_ctx);
+ flush_editors_id_update(graph, &update_ctx);
/* Reset evaluation result tagged which is tagged for update to some state
* which is obvious to catch. */
invalidate_tagged_evaluated_data(graph);