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.
This commit is contained in:
Sergey Sharybin 2016-04-28 12:29:42 +02:00
parent c01c47f79d
commit 94a6019a7b
Notes: blender-bot 2023-02-14 08:07:45 +01:00
Referenced by issue #47715, EXCEPTION_ACCESS_VIOLATION crash when removing modifiers or rendering
1 changed files with 33 additions and 2 deletions

View File

@ -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;