diff options
Diffstat (limited to 'source/blender/depsgraph/intern/builder/deg_builder_relations.cc')
-rw-r--r-- | source/blender/depsgraph/intern/builder/deg_builder_relations.cc | 386 |
1 files changed, 309 insertions, 77 deletions
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index c30d3fecdd5..8afb23f08fa 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -61,6 +61,7 @@ extern "C" { #include "DNA_movieclip_types.h" #include "DNA_node_types.h" #include "DNA_particle_types.h" +#include "DNA_lightprobe_types.h" #include "DNA_object_types.h" #include "DNA_rigidbody_types.h" #include "DNA_scene_types.h" @@ -127,7 +128,7 @@ void modifier_walk(void *user_data, { BuilderWalkUserData *data = (BuilderWalkUserData *)user_data; if (*obpoin) { - data->builder->build_object(*obpoin); + data->builder->build_object(NULL, *obpoin); } } @@ -140,7 +141,7 @@ void constraint_walk(bConstraint * /*con*/, if (*idpoin) { ID *id = *idpoin; if (GS(id->name) == ID_OB) { - data->builder->build_object((Object *)id); + data->builder->build_object(NULL, (Object *)id); } } } @@ -312,19 +313,16 @@ void DepsgraphRelationBuilder::add_collision_relations( Scene *scene, Object *object, Group *group, - int layer, bool dupli, const char *name) { unsigned int numcollobj; - Object **collobjs = get_collisionobjects_ext( - scene, - object, - group, - layer, - &numcollobj, - eModifierType_Collision, - dupli); + Object **collobjs = get_collisionobjects_ext(scene, + object, + group, + &numcollobj, + eModifierType_Collision, + dupli); for (unsigned int i = 0; i < numcollobj; i++) { Object *ob1 = collobjs[i]; @@ -348,9 +346,9 @@ void DepsgraphRelationBuilder::add_forcefield_relations( bool add_absorption, const char *name) { - ListBase *effectors = pdInitEffectors(scene, object, psys, eff, false); + ListBase *effectors = pdInitEffectors(NULL, scene, object, psys, eff, false); if (effectors != NULL) { - BLI_LISTBASE_FOREACH(EffectorCache *, eff, effectors) { + BLI_LISTBASE_FOREACH (EffectorCache *, eff, effectors) { if (eff->ob != object) { ComponentKey eff_key(&eff->ob->id, DEG_NODE_TYPE_TRANSFORM); add_relation(eff_key, key, name); @@ -388,7 +386,6 @@ void DepsgraphRelationBuilder::add_forcefield_relations( scene, object, NULL, - eff->ob->lay, true, "Force Absorption"); } @@ -420,7 +417,7 @@ void DepsgraphRelationBuilder::begin_build() nodetree->id.tag &= ~LIB_TAG_DOIT; } } - FOREACH_NODETREE_END; + FOREACH_NODETREE_END } void DepsgraphRelationBuilder::build_group(Object *object, Group *group) @@ -430,21 +427,26 @@ void DepsgraphRelationBuilder::build_group(Object *object, Group *group) OperationKey object_local_transform_key(object != NULL ? &object->id : NULL, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_LOCAL); - BLI_LISTBASE_FOREACH (GroupObject *, go, &group->gobject) { - if (!group_done) { - build_object(go->ob); + if (!group_done) { + BLI_LISTBASE_FOREACH (Base *, base, &group->view_layer->object_bases) { + build_object(NULL, base->object); } - if (object != NULL) { - ComponentKey dupli_transform_key(&go->ob->id, DEG_NODE_TYPE_TRANSFORM); + group_id->tag |= LIB_TAG_DOIT; + } + if (object != NULL) { + BLI_LISTBASE_FOREACH (Base *, base, &group->view_layer->object_bases) { + ComponentKey dupli_transform_key(&base->object->id, DEG_NODE_TYPE_TRANSFORM); add_relation(dupli_transform_key, object_local_transform_key, "Dupligroup"); } } - group_id->tag |= LIB_TAG_DOIT; } -void DepsgraphRelationBuilder::build_object(Object *object) +void DepsgraphRelationBuilder::build_object(Base *base, Object *object) { if (object->id.tag & LIB_TAG_DOIT) { + if (base != NULL) { + build_object_flags(base, object); + } return; } object->id.tag |= LIB_TAG_DOIT; @@ -464,6 +466,8 @@ void DepsgraphRelationBuilder::build_object(Object *object) OperationKey ob_ubereval_key(&object->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_OBJECT_UBEREVAL); + /* Various flags, flushing from bases/collections. */ + build_object_flags(base, object); /* Parenting. */ if (object->parent != NULL) { /* Parent relationship. */ @@ -531,7 +535,7 @@ void DepsgraphRelationBuilder::build_object(Object *object) /* Object that this is a proxy for. */ if (object->proxy != NULL) { object->proxy->proxy_from = object; - build_object(object->proxy); + build_object(NULL, object->proxy); /* TODO(sergey): This is an inverted relation, matches old depsgraph * behavior and need to be investigated if it still need to be inverted. */ @@ -545,6 +549,20 @@ void DepsgraphRelationBuilder::build_object(Object *object) } } +void DepsgraphRelationBuilder::build_object_flags(Base *base, Object *object) +{ + if (base == NULL) { + return; + } + OperationKey view_layer_done_key(&scene_->id, + DEG_NODE_TYPE_LAYER_COLLECTIONS, + DEG_OPCODE_VIEW_LAYER_DONE); + OperationKey object_flags_key(&object->id, + DEG_NODE_TYPE_LAYER_COLLECTIONS, + DEG_OPCODE_OBJECT_BASE_FLAGS); + add_relation(view_layer_done_key, object_flags_key, "Base flags flush"); +} + void DepsgraphRelationBuilder::build_object_data(Object *object) { if (object->data == NULL) { @@ -579,6 +597,9 @@ void DepsgraphRelationBuilder::build_object_data(Object *object) case OB_CAMERA: build_camera(object); break; + case OB_LIGHTPROBE: + build_lightprobe(object); + break; } Key *key = BKE_key_from_object(object); if (key != NULL) { @@ -976,6 +997,18 @@ void DepsgraphRelationBuilder::build_animdata_curves_targets( 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); + } + } } } @@ -1014,7 +1047,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. @@ -1109,18 +1141,18 @@ void DepsgraphRelationBuilder::build_driver_data(ID *id, FCurve *fcu) */ IDDepsNode *arm_node = graph_->find_id_node(id); char *bone_name = BLI_str_quoted_substrN(rna_path, "bones["); - if (arm_node && bone_name) { + if (arm_node != NULL && bone_name != NULL) { /* Find objects which use this, and make their eval callbacks * depend on this. */ foreach (DepsRelation *rel, arm_node->outlinks) { IDDepsNode *to_node = (IDDepsNode *)rel->to; /* We only care about objects with pose data which use this. */ - if (GS(to_node->id->name) == ID_OB) { - Object *object = (Object *)to_node->id; - /* NOTE: object->pose may be NULL. */ - bPoseChannel *pchan = BKE_pose_channel_find_name( - object->pose, bone_name); + if (GS(to_node->id_orig->name) == ID_OB) { + Object *object = (Object *)to_node->id_orig; + // NOTE: object->pose may be NULL + bPoseChannel *pchan = BKE_pose_channel_find_name(object->pose, + bone_name); if (pchan != NULL) { OperationKey bone_key(&object->id, DEG_NODE_TYPE_BONE, @@ -1145,6 +1177,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); + } + } + } } } @@ -1250,9 +1301,9 @@ void DepsgraphRelationBuilder::build_world(World *world) /* world's nodetree */ if (world->nodetree != NULL) { build_nodetree(world->nodetree); - ComponentKey ntree_key(&world->nodetree->id, DEG_NODE_TYPE_PARAMETERS); - ComponentKey world_key(world_id, DEG_NODE_TYPE_PARAMETERS); - add_relation(ntree_key, world_key, "NTree->World Parameters"); + ComponentKey ntree_key(&world->nodetree->id, DEG_NODE_TYPE_SHADING); + ComponentKey world_key(world_id, DEG_NODE_TYPE_SHADING); + add_relation(ntree_key, world_key, "NTree->World Shading Update"); } } @@ -1274,8 +1325,8 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) /* objects - simulation participants */ if (rbw->group) { - BLI_LISTBASE_FOREACH (GroupObject *, go, &rbw->group->gobject) { - Object *object = go->ob; + BLI_LISTBASE_FOREACH (Base *, base, &rbw->group->view_layer->object_bases) { + Object *object = base->object; if (object == NULL || object->type != OB_MESH) { continue; } @@ -1328,8 +1379,8 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) /* constraints */ if (rbw->constraints) { - BLI_LISTBASE_FOREACH (GroupObject *, go, &rbw->constraints->gobject) { - Object *object = go->ob; + BLI_LISTBASE_FOREACH (Base *, base, &rbw->constraints->view_layer->object_bases) { + Object *object = base->object; if (object == NULL || !object->rigidbody_constraint) { continue; } @@ -1366,13 +1417,36 @@ void DepsgraphRelationBuilder::build_particles(Object *object) /* Particle systems. */ BLI_LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) { ParticleSettings *part = psys->part; - /* Animation of particle settings, */ - build_animdata(&part->id); + + /* Build particle settings relations. + * + * NOTE: The call itself ensures settings are only build once. + */ + build_particle_settings(part); + /* This particle system. */ OperationKey psys_key(&object->id, DEG_NODE_TYPE_EVAL_PARTICLES, DEG_OPCODE_PARTICLE_SYSTEM_EVAL, psys->name); + + /* Update particle system when settings changes. */ + OperationKey particle_settings_key(&part->id, + DEG_NODE_TYPE_PARAMETERS, + DEG_OPCODE_PARTICLE_SETTINGS_EVAL); + OperationKey particle_settings_recalc_clear_key( + &part->id, + DEG_NODE_TYPE_PARAMETERS, + DEG_OPCODE_PARTICLE_SETTINGS_RECALC_CLEAR); + OperationKey psys_settings_key(&object->id, + DEG_NODE_TYPE_EVAL_PARTICLES, + DEG_OPCODE_PARTICLE_SETTINGS_EVAL, + psys->name); + add_relation(particle_settings_key, psys_settings_key, "Particle Settings Change"); + add_relation(psys_settings_key, psys_key, "Particle Settings Update"); + add_relation(psys_key, + particle_settings_recalc_clear_key, + "Particle Settings Recalc Clear"); add_relation(eval_init_key, psys_key, "Init -> PSys"); /* TODO(sergey): Currently particle update is just a placeholder, * hook it to the ubereval node so particle system is getting updated @@ -1385,18 +1459,17 @@ void DepsgraphRelationBuilder::build_particles(Object *object) scene_, object, part->collision_group, - object->lay, true, "Particle Collision"); } else if ((psys->flag & PSYS_HAIR_DYNAMICS) && - psys->clmd && psys->clmd->coll_parms) + psys->clmd != NULL && + psys->clmd->coll_parms != NULL) { add_collision_relations(psys_key, scene_, object, psys->clmd->coll_parms->group, - object->lay | scene_->lay, true, "Hair Collision"); } @@ -1408,7 +1481,7 @@ void DepsgraphRelationBuilder::build_particles(Object *object) part->effector_weights, part->type == PART_HAIR, "Particle Field"); - /* Boids. */ + /* Boids .*/ if (part->boids) { BLI_LISTBASE_FOREACH (BoidState *, state, &part->boids->states) { BLI_LISTBASE_FOREACH (BoidRule *, rule, &state->rules) { @@ -1427,12 +1500,11 @@ void DepsgraphRelationBuilder::build_particles(Object *object) } } } - switch (part->ren_as) { case PART_DRAW_OB: if (part->dup_ob != NULL) { /* Make sure object's relations are all built. */ - build_object(part->dup_ob); + build_object(NULL, part->dup_ob); /* Build relation for the particle visualization. */ build_particles_visualization_object(object, psys, @@ -1461,8 +1533,27 @@ void DepsgraphRelationBuilder::build_particles(Object *object) ComponentKey transform_key(&object->id, DEG_NODE_TYPE_TRANSFORM); add_relation(transform_key, obdata_ubereval_key, "Partcile Eval"); - /* pointcache */ - // TODO... + /* TODO(sergey): Do we need a point cache operations here? */ +} + +void DepsgraphRelationBuilder::build_particle_settings(ParticleSettings *part) +{ + ID *part_id = &part->id; + if (part_id->tag & LIB_TAG_DOIT) { + return; + } + part_id->tag |= LIB_TAG_DOIT; + + /* Animation data relations. */ + build_animdata(&part->id); + + OperationKey eval_key(part_id, + DEG_NODE_TYPE_PARAMETERS, + DEG_OPCODE_PARTICLE_SETTINGS_EVAL); + OperationKey recalc_clear_key(part_id, + DEG_NODE_TYPE_PARAMETERS, + DEG_OPCODE_PARTICLE_SETTINGS_RECALC_CLEAR); + add_relation(eval_key, recalc_clear_key, "Particle Settings Clear Recalc"); } void DepsgraphRelationBuilder::build_particles_visualization_object( @@ -1558,12 +1649,22 @@ void DepsgraphRelationBuilder::build_obdata_geom(Object *object) /* link components to each other */ add_relation(obdata_geom_key, geom_key, "Object Geometry Base Data"); + OperationKey obdata_ubereval_key(&object->id, + DEG_NODE_TYPE_GEOMETRY, + DEG_OPCODE_GEOMETRY_UBEREVAL); + + /* Special case: modifiers and DerivedMesh creation queries scene for various + * things like data mask to be used. We add relation here to ensure object is + * never evaluated prior to Scene's CoW is ready. + */ + OperationKey scene_key(&scene_->id, + DEG_NODE_TYPE_PARAMETERS, + DEG_OPCODE_PLACEHOLDER, + "Scene Eval"); + add_relation(scene_key, obdata_ubereval_key, "CoW Relation"); + /* Modifiers */ if (object->modifiers.first != NULL) { - OperationKey obdata_ubereval_key(&object->id, - DEG_NODE_TYPE_GEOMETRY, - DEG_OPCODE_GEOMETRY_UBEREVAL); - BLI_LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { const ModifierTypeInfo *mti = modifierType_getInfo((ModifierType)md->type); if (mti->updateDepsgraph) { @@ -1591,6 +1692,14 @@ void DepsgraphRelationBuilder::build_obdata_geom(Object *object) Material *ma = give_current_material(object, a); if (ma != NULL) { build_material(ma); + + if (object->type == OB_MESH) { + OperationKey material_key(&ma->id, + DEG_NODE_TYPE_SHADING, + DEG_OPCODE_MATERIAL_UPDATE); + OperationKey shading_key(&object->id, DEG_NODE_TYPE_SHADING, DEG_OPCODE_SHADING); + add_relation(material_key, shading_key, "Material Update"); + } } } } @@ -1669,18 +1778,18 @@ void DepsgraphRelationBuilder::build_obdata_geom(Object *object) // XXX: these needs geom data, but where is geom stored? if (cu->bevobj) { ComponentKey bevob_key(&cu->bevobj->id, DEG_NODE_TYPE_GEOMETRY); - build_object(cu->bevobj); + build_object(NULL, cu->bevobj); add_relation(bevob_key, geom_key, "Curve Bevel"); } if (cu->taperobj) { ComponentKey taperob_key(&cu->taperobj->id, DEG_NODE_TYPE_GEOMETRY); - build_object(cu->taperobj); + build_object(NULL, cu->taperobj); add_relation(taperob_key, geom_key, "Curve Taper"); } if (object->type == OB_FONT) { if (cu->textoncurve) { ComponentKey textoncurve_key(&cu->textoncurve->id, DEG_NODE_TYPE_GEOMETRY); - build_object(cu->textoncurve); + build_object(NULL, cu->textoncurve); add_relation(textoncurve_key, geom_key, "Text on Curve"); } } @@ -1715,11 +1824,17 @@ void DepsgraphRelationBuilder::build_camera(Object *object) return; } camera_id->tag |= LIB_TAG_DOIT; + + ComponentKey object_parameters_key(&object->id, DEG_NODE_TYPE_PARAMETERS); + ComponentKey camera_parameters_key(camera_id, DEG_NODE_TYPE_PARAMETERS); + + add_relation(camera_parameters_key, object_parameters_key, + "Camera -> Object"); + /* DOF */ - if (cam->dof_ob) { - ComponentKey ob_param_key(&object->id, DEG_NODE_TYPE_PARAMETERS); + if (cam->dof_ob != NULL) { ComponentKey dof_ob_key(&cam->dof_ob->id, DEG_NODE_TYPE_TRANSFORM); - add_relation(dof_ob_key, ob_param_key, "Camera DOF"); + add_relation(dof_ob_key, object_parameters_key, "Camera DOF"); } } @@ -1732,30 +1847,44 @@ void DepsgraphRelationBuilder::build_lamp(Object *object) return; } lamp_id->tag |= LIB_TAG_DOIT; + + ComponentKey object_parameters_key(&object->id, DEG_NODE_TYPE_PARAMETERS); + ComponentKey lamp_parameters_key(lamp_id, DEG_NODE_TYPE_PARAMETERS); + + add_relation(lamp_parameters_key, object_parameters_key, + "Lamp -> Object"); + /* lamp's nodetree */ if (la->nodetree != NULL) { build_nodetree(la->nodetree); - ComponentKey parameters_key(lamp_id, DEG_NODE_TYPE_PARAMETERS); - ComponentKey nodetree_key(&la->nodetree->id, DEG_NODE_TYPE_PARAMETERS); - add_relation(nodetree_key, parameters_key, "NTree->Lamp Parameters"); + ComponentKey nodetree_key(&la->nodetree->id, DEG_NODE_TYPE_SHADING); + add_relation(nodetree_key, lamp_parameters_key, "NTree->Lamp Parameters"); } /* textures */ build_texture_stack(la->mtex); + + if (DEG_depsgraph_use_copy_on_write()) { + /* Make sure copy on write of lamp data is always properly updated for + * visible lamps. + */ + OperationKey ob_copy_on_write_key(&object->id, + DEG_NODE_TYPE_COPY_ON_WRITE, + DEG_OPCODE_COPY_ON_WRITE); + OperationKey lamp_copy_on_write_key(lamp_id, + DEG_NODE_TYPE_COPY_ON_WRITE, + DEG_OPCODE_COPY_ON_WRITE); + add_relation(lamp_copy_on_write_key, ob_copy_on_write_key, "Eval Order"); + } } void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree) { - if (!ntree) + if (ntree == NULL) { return; - + } ID *ntree_id = &ntree->id; - build_animdata(ntree_id); - - OperationKey parameters_key(ntree_id, - DEG_NODE_TYPE_PARAMETERS, - DEG_OPCODE_PARAMETERS_EVAL); - + ComponentKey shading_key(ntree_id, DEG_NODE_TYPE_SHADING); /* nodetree's nodes... */ BLI_LISTBASE_FOREACH (bNode *, bnode, &ntree->nodes) { ID *id = bnode->id; @@ -1773,7 +1902,7 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree) /* nothing for now. */ } else if (id_type == ID_OB) { - build_object((Object *)id); + build_object(NULL, (Object *)id); } else if (id_type == ID_SCE) { /* Scenes are used by compositor trees, and handled by render @@ -1789,15 +1918,22 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree) build_nodetree(group_ntree); group_ntree->id.tag |= LIB_TAG_DOIT; } - OperationKey group_parameters_key(&group_ntree->id, - DEG_NODE_TYPE_PARAMETERS, - DEG_OPCODE_PARAMETERS_EVAL); - add_relation(group_parameters_key, parameters_key, "Group Node"); + ComponentKey group_shading_key(&group_ntree->id, + DEG_NODE_TYPE_SHADING); + add_relation(group_shading_key, shading_key, "Group Node"); } else { BLI_assert(!"Unknown ID type used for node"); } } + + OperationKey shading_update_key(ntree_id, + DEG_NODE_TYPE_SHADING, + DEG_OPCODE_MATERIAL_UPDATE); + OperationKey shading_parameters_key(ntree_id, + DEG_NODE_TYPE_SHADING_PARAMETERS, + DEG_OPCODE_MATERIAL_UPDATE); + add_relation(shading_parameters_key, shading_update_key, "NTree Shading Parameters"); } /* Recursively build graph for material */ @@ -1819,12 +1955,11 @@ void DepsgraphRelationBuilder::build_material(Material *ma) if (ma->nodetree != NULL) { build_nodetree(ma->nodetree); OperationKey ntree_key(&ma->nodetree->id, - DEG_NODE_TYPE_PARAMETERS, - DEG_OPCODE_PARAMETERS_EVAL); + DEG_NODE_TYPE_SHADING, + DEG_OPCODE_MATERIAL_UPDATE); OperationKey material_key(&ma->id, DEG_NODE_TYPE_SHADING, - DEG_OPCODE_PLACEHOLDER, - "Material Update"); + DEG_OPCODE_MATERIAL_UPDATE); add_relation(ntree_key, material_key, "Material's NTree"); } } @@ -1900,4 +2035,101 @@ void DepsgraphRelationBuilder::build_movieclip(MovieClip *clip) build_animdata(&clip->id); } +void DepsgraphRelationBuilder::build_lightprobe(Object *object) +{ + LightProbe *probe = (LightProbe *)object->data; + ID *probe_id = &probe->id; + if (probe_id->tag & LIB_TAG_DOIT) { + return; + } + probe_id->tag |= LIB_TAG_DOIT; + build_animdata(&probe->id); + + OperationKey probe_key(probe_id, + DEG_NODE_TYPE_PARAMETERS, + DEG_OPCODE_PLACEHOLDER, + "LightProbe Eval"); + OperationKey object_key(&object->id, + DEG_NODE_TYPE_PARAMETERS, + DEG_OPCODE_PLACEHOLDER, + "LightProbe Eval"); + add_relation(probe_key, object_key, "LightProbe Update"); +} + +void DepsgraphRelationBuilder::build_copy_on_write_relations() +{ + foreach (IDDepsNode *id_node, graph_->id_nodes) { + build_copy_on_write_relations(id_node); + } +} + +void DepsgraphRelationBuilder::build_copy_on_write_relations(IDDepsNode *id_node) +{ + ID *id_orig = id_node->id_orig; + + TimeSourceKey time_source_key; + OperationKey copy_on_write_key(id_orig, + DEG_NODE_TYPE_COPY_ON_WRITE, + DEG_OPCODE_COPY_ON_WRITE); + /* XXX: This is a quick hack to make Alt-A to work. */ + // add_relation(time_source_key, copy_on_write_key, "Fluxgate capacitor hack"); + /* Resat of code is using rather low level trickery, so need to get some + * explicit pointers. + */ + DepsNode *node_cow = find_node(copy_on_write_key); + OperationDepsNode *op_cow = node_cow->get_exit_operation(); + /* Plug any other components to this one. */ + GHASH_FOREACH_BEGIN(ComponentDepsNode *, comp_node, id_node->components) + { + if (comp_node->type == DEG_NODE_TYPE_COPY_ON_WRITE) { + /* Copy-on-write component never depends on itself. */ + continue; + } + if (!comp_node->depends_on_cow()) { + /* Component explicitly requests to not add relation. */ + continue; + } + /* All entry operations of each component should wait for a proper + * copy of ID. + */ + OperationDepsNode *op_entry = comp_node->get_entry_operation(); + if (op_entry != NULL) { + graph_->add_new_relation(op_cow, op_entry, "CoW Dependency"); + } + /* All dangling operations should also be executed after copy-on-write. */ + GHASH_FOREACH_BEGIN(OperationDepsNode *, op_node, comp_node->operations_map) + { + if (op_node->inlinks.size() == 0) { + graph_->add_new_relation(op_cow, op_node, "CoW Dependency"); + } + } + GHASH_FOREACH_END(); + /* NOTE: We currently ignore implicit relations to an external + * datablocks for copy-on-write operations. This means, for example, + * copy-on-write component of Object will not wait for copy-on-write + * component of it's Mesh. This is because pointers are all known + * already so remapping will happen all correct. And then If some object + * evaluation step needs geometry, it will have transitive dependency + * to Mesh copy-on-write already. + */ + } + GHASH_FOREACH_END(); + /* TODO(sergey): This solves crash for now, but causes too many + * updates potentially. + */ + if (GS(id_orig->name) == ID_OB) { + Object *object = (Object *)id_orig; + ID *object_data_id = (ID *)object->data; + if (object_data_id != NULL) { + OperationKey data_copy_on_write_key(object_data_id, + DEG_NODE_TYPE_COPY_ON_WRITE, + DEG_OPCODE_COPY_ON_WRITE); + add_relation(data_copy_on_write_key, copy_on_write_key, "Eval Order"); + } + else { + BLI_assert(object->type == OB_EMPTY); + } + } +} + } // namespace DEG |