From fe18d9ba11efa32f9c6a9122c3422ec38ebada76 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 24 Jan 2018 11:00:37 +0100 Subject: Depsgraph: Fix evaluaiton order with nested animation and copy on write It is possible to have animation (or driver) to modify nested datablock, such as shape key value for example (where animation is on Mesh level, but shape key is it's own datablock). To deal with such cases we need to create relation from nested datablock CoW to animaiton/driver operation. --- .../intern/builder/deg_builder_relations.cc | 32 +++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'source') diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 3cd239bff28..cfb73ecc2ad 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -989,6 +989,18 @@ void DepsgraphRelationBuilder::build_animdata_curves_targets(ID *id) graph_->add_new_relation(operation_from, operation_to, "Animation -> Prop", true); + /* It is possible that animation is writing to a nested ID datablock, + * need to make sure animation is evaluated after target ID is copied. + */ + if (DEG_depsgraph_use_copy_on_write()) { + const IDDepsNode *id_node_from = operation_from->owner->owner; + const IDDepsNode *id_node_to = operation_to->owner->owner; + if (id_node_from != id_node_to) { + ComponentKey cow_key(id_node_to->id_orig, + DEG_NODE_TYPE_COPY_ON_WRITE); + add_relation(cow_key, adt_key, "Target CoW -> Animation", true); + } + } } } @@ -1008,7 +1020,6 @@ void DepsgraphRelationBuilder::build_animdata_drivers(ID *id) /* create the driver's relations to targets */ build_driver(id, fcu); - /* Special case for array drivers: we can not multithread them because * of the way how they work internally: animation system will write the * whole array back to RNA even when changing individual array value. @@ -1139,6 +1150,25 @@ void DepsgraphRelationBuilder::build_driver_data(ID *id, FCurve *fcu) else { RNAPathKey target_key(id, rna_path); add_relation(driver_key, target_key, "Driver -> Target"); + /* Similar to the case with f-curves, driver might drive a nested + * datablock, which means driver execution should wait for that + * datablock to be copied. + */ + if (DEG_depsgraph_use_copy_on_write()) { + PointerRNA id_ptr; + PointerRNA ptr; + RNA_id_pointer_create(id, &id_ptr); + if (RNA_path_resolve_full(&id_ptr, fcu->rna_path, &ptr, NULL, NULL)) { + if (id_ptr.id.data != ptr.id.data) { + ComponentKey cow_key((ID *)ptr.id.data, + DEG_NODE_TYPE_COPY_ON_WRITE); + add_relation(cow_key, + driver_key, + "Target CoW -> Driver", + true); + } + } + } } } -- cgit v1.2.3