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>2016-04-28 13:29:42 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2016-04-28 13:32:59 +0300
commit94a6019a7ba94f8b46b737c185293ecce19cc6a6 (patch)
tree8772626163df886c4d966873dddb17c5e2ec5af0
parentc01c47f79d707289f96dfc052cf1b06c11227614 (diff)
Fix T47715: EXCEPTION_ACCESS_VIOLATION crash when removing modifiers or rendering
The issue was caused by missing indirect dependencies from other scenes in the current scene depsgraph, which was causing some threading conflicts. Not sure what would be ideal solution here, for now use stupid but rather robust approach to solve that. Maybe there's something better to do here tho.
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c35
1 files changed, 33 insertions, 2 deletions
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index a029c8c7748..14c230e4a45 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -937,6 +937,8 @@ DagForest *build_dag(Main *bmain, Scene *sce, short mask)
}
dag->need_update = false;
+ BKE_main_id_tag_idcode(bmain, ID_OB, LIB_TAG_DOIT, false);
+
/* clear "LIB_TAG_DOIT" flag from all materials, to prevent infinite recursion problems later [#32017] */
BKE_main_id_tag_idcode(bmain, ID_MA, LIB_TAG_DOIT, false);
BKE_main_id_tag_idcode(bmain, ID_LA, LIB_TAG_DOIT, false);
@@ -948,14 +950,43 @@ DagForest *build_dag(Main *bmain, Scene *sce, short mask)
/* add current scene objects */
for (base = sce->base.first; base; base = base->next) {
ob = base->object;
-
+ ob->id.tag |= LIB_TAG_DOIT;
build_dag_object(dag, scenenode, bmain, sce, ob, mask);
if (ob->proxy)
build_dag_object(dag, scenenode, bmain, sce, ob->proxy, mask);
if (ob->dup_group)
build_dag_group(dag, scenenode, bmain, sce, ob->dup_group, mask);
}
-
+
+ /* There might be situations when object from current scene depends on
+ * objects form other scene AND objects from other scene has own
+ * dependencies on objects from other scene.
+ *
+ * This is really important to include such indirect dependencies in order
+ * to keep threaded update safe but since we don't really know if object is
+ * coming from current scene or another scene we do rather stupid tag-based
+ * check here: all the objects for which build_dag_object() was called are
+ * getting tagged with LIB_TAG_DOIT. This way if some node has untagged
+ * object we know it's an object from other scene.
+ *
+ * It should be enough to to it once, because if there's longer chain of
+ * indirect dependencies, all the new nodes will be added to the end of the
+ * list, meaning we'll keep covering them in this for loop.
+ */
+ for (node = sce->theDag->DagNode.first; node != NULL; node = node->next) {
+ if (node->type == ID_OB) {
+ ob = node->ob;
+ if ((ob->id.tag & LIB_TAG_DOIT) == 0) {
+ ob->id.tag |= LIB_TAG_DOIT;
+ build_dag_object(dag, scenenode, bmain, sce, ob, mask);
+ if (ob->proxy)
+ build_dag_object(dag, scenenode, bmain, sce, ob->proxy, mask);
+ if (ob->dup_group)
+ build_dag_group(dag, scenenode, bmain, sce, ob->dup_group, mask);
+ }
+ }
+ }
+
BKE_main_id_tag_idcode(bmain, ID_GR, LIB_TAG_DOIT, false);
/* Now all relations were built, but we need to solve 1 exceptional case;