diff options
11 files changed, 244 insertions, 200 deletions
diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt index c42d06bd0a2..c2f69343456 100644 --- a/source/blender/depsgraph/CMakeLists.txt +++ b/source/blender/depsgraph/CMakeLists.txt @@ -42,6 +42,7 @@ set(INC_SYS set(SRC intern/builder/deg_builder.cc intern/builder/deg_builder_cycle.cc + intern/builder/deg_builder_map.cc intern/builder/deg_builder_nodes.cc intern/builder/deg_builder_nodes_layer_collection.cc intern/builder/deg_builder_nodes_rig.cc @@ -81,6 +82,7 @@ set(SRC intern/builder/deg_builder.h intern/builder/deg_builder_cycle.h + intern/builder/deg_builder_map.h intern/builder/deg_builder_nodes.h intern/builder/deg_builder_pchanmap.h intern/builder/deg_builder_relations.h diff --git a/source/blender/depsgraph/intern/builder/deg_builder_map.cc b/source/blender/depsgraph/intern/builder/deg_builder_map.cc new file mode 100644 index 00000000000..8c8446c1686 --- /dev/null +++ b/source/blender/depsgraph/intern/builder/deg_builder_map.cc @@ -0,0 +1,64 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2018 Blender Foundation. + * All rights reserved. + * + * Original Author: Sergey Sharybin + * Contributor(s): None Yet + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/depsgraph/intern/builder/deg_builder.cc + * \ingroup depsgraph + */ + +#include "intern/builder/deg_builder_map.h" + +#include "BLI_utildefines.h" +#include "BLI_ghash.h" + +namespace DEG { + +BuilderMap::BuilderMap() { + set = BLI_gset_ptr_new("deg builder gset"); +} + + +BuilderMap::~BuilderMap() { + BLI_gset_free(set, NULL); +} + +bool BuilderMap::checkIsBuilt(ID *id) { + return BLI_gset_haskey(set, id); +} + +void BuilderMap::tagBuild(ID *id) { + BLI_gset_insert(set, id); +} + +bool BuilderMap::checkIsBuiltAndTag(ID *id) { + void **key_p; + if (!BLI_gset_ensure_p_ex(set, id, &key_p)) { + *key_p = id; + return false; + } + return true; +} + +} // namespace DEG diff --git a/source/blender/depsgraph/intern/builder/deg_builder_map.h b/source/blender/depsgraph/intern/builder/deg_builder_map.h new file mode 100644 index 00000000000..0e6d7c81396 --- /dev/null +++ b/source/blender/depsgraph/intern/builder/deg_builder_map.h @@ -0,0 +1,69 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2018 Blender Foundation. + * All rights reserved. + * + * Original Author: Sergey Sharybin + * Contributor(s): None Yet + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/depsgraph/intern/builder/deg_builder.h + * \ingroup depsgraph + */ + +#pragma once + +struct GSet; +struct ID; + +namespace DEG { + +class BuilderMap { +public: + BuilderMap(); + ~BuilderMap(); + + /* Check whether given ID is already handled by builder (or if it's being + * handled). + */ + bool checkIsBuilt(ID *id); + + /* Tag given ID as handled/built. */ + void tagBuild(ID *id); + + /* Combination of previous two functions, returns truth if ID was already + * handled, or tags is handled otherwise and return false. + */ + bool checkIsBuiltAndTag(ID *id); + + template<typename T> bool checkIsBuilt(T *datablock) { + return checkIsBuilt(&datablock->id); + } + template<typename T> void tagBuild(T *datablock) { + tagBuild(&datablock->id); + } + template<typename T> bool checkIsBuiltAndTag(T *datablock) { + return checkIsBuiltAndTag(&datablock->id); + } + + GSet *set; +}; + +} // namespace DEG diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index b65c16591dc..d115111b7e8 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -179,10 +179,10 @@ DepsgraphNodeBuilder::~DepsgraphNodeBuilder() } } -IDDepsNode *DepsgraphNodeBuilder::add_id_node(ID *id, bool do_tag) +IDDepsNode *DepsgraphNodeBuilder::add_id_node(ID *id) { if (!DEG_depsgraph_use_copy_on_write()) { - return graph_->add_id_node(id, do_tag); + return graph_->add_id_node(id); } IDDepsNode *id_node = NULL; ID *id_cow = (ID *)BLI_ghash_lookup(cow_id_hash_, id); @@ -192,7 +192,7 @@ IDDepsNode *DepsgraphNodeBuilder::add_id_node(ID *id, bool do_tag) */ BLI_ghash_remove(cow_id_hash_, id, NULL, NULL); } - id_node = graph_->add_id_node(id, do_tag, id_cow); + id_node = graph_->add_id_node(id, id_cow); /* Currently all ID nodes are supposed to have copy-on-write logic. * * NOTE: Zero number of components indicates that ID node was just created. @@ -333,7 +333,7 @@ ID *DepsgraphNodeBuilder::ensure_cow_id(ID *id_orig) /* ID is already remapped to copy-on-write. */ return id_orig; } - IDDepsNode *id_node = add_id_node(id_orig, false); + IDDepsNode *id_node = add_id_node(id_orig); return id_node->id_cow; } @@ -351,23 +351,6 @@ ID *DepsgraphNodeBuilder::expand_cow_id(ID *id_orig) /* **** Build functions for entity nodes **** */ void DepsgraphNodeBuilder::begin_build() { - /* LIB_TAG_DOIT is used to indicate whether node for given ID was already - * created or not. This flag is being set in add_id_node(), so functions - * shouldn't bother with setting it, they only might query this flag when - * needed. - */ - BKE_main_id_tag_all(bmain_, LIB_TAG_DOIT, false); - /* XXX nested node trees are not included in tag-clearing above, - * so we need to do this manually. - */ - FOREACH_NODETREE(bmain_, nodetree, id) - { - if (id != (ID *)nodetree) { - nodetree->id.tag &= ~LIB_TAG_DOIT; - } - } - FOREACH_NODETREE_END; - if (DEG_depsgraph_use_copy_on_write()) { /* Store existing copy-on-write versions of datablock, so we can re-use * them for new ID nodes. @@ -424,11 +407,9 @@ void DepsgraphNodeBuilder::end_build() void DepsgraphNodeBuilder::build_group(Group *group) { - ID *group_id = &group->id; - if (group_id->tag & LIB_TAG_DOIT) { + if (built_map_.checkIsBuiltAndTag(group)) { return; } - group_id->tag |= LIB_TAG_DOIT; /* Build group objects. */ LISTBASE_FOREACH (Base *, base, &group->view_layer->object_bases) { build_object(NULL, base->object, DEG_ID_LINKED_INDIRECTLY); @@ -439,9 +420,9 @@ void DepsgraphNodeBuilder::build_group(Group *group) * This way we wouldn't need to worry about possible relations from DONE, * regardless whether it's a group or scene or something else. */ - add_id_node(group_id); + add_id_node(&group->id); Group *group_cow = get_cow_datablock(group); - add_operation_node(group_id, + add_operation_node(&group->id, DEG_NODE_TYPE_LAYER_COLLECTIONS, function_bind(BKE_group_eval_view_layers, _1, @@ -453,8 +434,9 @@ void DepsgraphNodeBuilder::build_object(Base *base, Object *object, eDepsNode_LinkedState_Type linked_state) { + const bool has_object = built_map_.checkIsBuiltAndTag(object); /* Skip rest of components if the ID node was already there. */ - if (object->id.tag & LIB_TAG_DOIT) { + if (has_object) { IDDepsNode *id_node = find_id_node(&object->id); /* We need to build some extra stuff if object becomes linked * directly. @@ -465,7 +447,6 @@ void DepsgraphNodeBuilder::build_object(Base *base, id_node->linked_state = max(id_node->linked_state, linked_state); return; } - object->id.tag |= LIB_TAG_DOIT; /* Create ID node for object and begin init. */ IDDepsNode *id_node = add_id_node(&object->id); id_node->linked_state = linked_state; @@ -581,7 +562,7 @@ void DepsgraphNodeBuilder::build_object_data(Object *object) default: { ID *obdata = (ID *)object->data; - if ((obdata->tag & LIB_TAG_DOIT) == 0) { + if (built_map_.checkIsBuilt(obdata) == 0) { build_animdata(obdata); } break; @@ -748,14 +729,13 @@ OperationDepsNode *DepsgraphNodeBuilder::build_driver(ID *id, FCurve *fcu) /* Recursively build graph for world */ void DepsgraphNodeBuilder::build_world(World *world) { - ID *world_id = &world->id; - if (world_id->tag & LIB_TAG_DOIT) { + if (built_map_.checkIsBuiltAndTag(world)) { return; } /* Animation. */ - build_animdata(world_id); + build_animdata(&world->id); /* world itself */ - add_operation_node(world_id, + add_operation_node(&world->id, DEG_NODE_TYPE_SHADING, function_bind(BKE_world_eval, _1, @@ -916,19 +896,17 @@ void DepsgraphNodeBuilder::build_particles(Object *object) } void DepsgraphNodeBuilder::build_particle_settings(ParticleSettings *part) { - ID *part_id = &part->id; - if (part_id->tag & LIB_TAG_DOIT) { + if (built_map_.checkIsBuiltAndTag(part)) { return; } - part_id->tag |= LIB_TAG_DOIT; /* Animation data. */ - build_animdata(part_id); + build_animdata(&part->id); /* Parameters change. */ - add_operation_node(part_id, + add_operation_node(&part->id, DEG_NODE_TYPE_PARAMETERS, NULL, DEG_OPCODE_PARTICLE_SETTINGS_EVAL); - add_operation_node(part_id, + add_operation_node(&part->id, DEG_NODE_TYPE_PARAMETERS, function_bind(BKE_particle_system_settings_recalc_clear, _1, @@ -1035,10 +1013,9 @@ void DepsgraphNodeBuilder::build_obdata_geom(Object *object) } ID *obdata = (ID *)object->data; - if (obdata->tag & LIB_TAG_DOIT) { + if (built_map_.checkIsBuiltAndTag(obdata)) { return; } - obdata->tag |= LIB_TAG_DOIT; /* Make sure we've got an ID node before requesting CoW pointer. */ (void) add_id_node((ID *)obdata); ID *obdata_cow = get_cow_id(obdata); @@ -1172,18 +1149,14 @@ void DepsgraphNodeBuilder::build_camera(Object *object) NULL, DEG_OPCODE_PARAMETERS_EVAL, "Camera Parameters"); - /* Object data. */ - /* TODO: Link scene-camera links in somehow. */ - Camera *cam = (Camera *)object->data; - ID *camera_id = &cam->id; - if (camera_id->tag & LIB_TAG_DOIT) { + /* TODO: Link scene-camera links in somehow... */ + Camera *camera = (Camera *)object->data; + if (built_map_.checkIsBuiltAndTag(camera)) { return; } - - build_animdata(&cam->id); - - add_operation_node(camera_id, + build_animdata(&camera->id); + add_operation_node(&camera->id, DEG_NODE_TYPE_PARAMETERS, NULL, DEG_OPCODE_PARAMETERS_EVAL); @@ -1198,28 +1171,20 @@ void DepsgraphNodeBuilder::build_lamp(Object *object) NULL, DEG_OPCODE_PARAMETERS_EVAL, "Lamp Parameters"); - /* Object data. */ - Lamp *la = (Lamp *)object->data; - ID *lamp_id = &la->id; - if (lamp_id->tag & LIB_TAG_DOIT) { + Lamp *lamp = (Lamp *)object->data; + if (built_map_.checkIsBuiltAndTag(lamp)) { return; } - - build_animdata(&la->id); - - add_operation_node(lamp_id, + build_animdata(&lamp->id); + add_operation_node(&lamp->id, DEG_NODE_TYPE_PARAMETERS, NULL, DEG_OPCODE_PARAMETERS_EVAL); - /* lamp's nodetree */ - if (la->nodetree) { - build_nodetree(la->nodetree); - } - + build_nodetree(lamp->nodetree); /* textures */ - build_texture_stack(la->mtex); + build_texture_stack(lamp->mtex); } void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree) @@ -1227,21 +1192,23 @@ void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree) if (ntree == NULL) { return; } + if (built_map_.checkIsBuiltAndTag(ntree)) { + return; + } /* nodetree itself */ - ID *ntree_id = &ntree->id; - add_id_node(ntree_id); + add_id_node(&ntree->id); bNodeTree *ntree_cow = get_cow_datablock(ntree); /* Animation, */ - build_animdata(ntree_id); + build_animdata(&ntree->id); /* Shading update. */ - add_operation_node(ntree_id, + add_operation_node(&ntree->id, DEG_NODE_TYPE_SHADING, NULL, DEG_OPCODE_MATERIAL_UPDATE); /* NOTE: We really pass original and CoW node trees here, this is how the * callback works. Ideally we need to find a better way for that. */ - add_operation_node(ntree_id, + add_operation_node(&ntree->id, DEG_NODE_TYPE_SHADING_PARAMETERS, function_bind(BKE_nodetree_shading_params_eval, _1, @@ -1277,9 +1244,7 @@ void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree) } else if (bnode->type == NODE_GROUP) { bNodeTree *group_ntree = (bNodeTree *)id; - if ((group_ntree->id.tag & LIB_TAG_DOIT) == 0) { - build_nodetree(group_ntree); - } + build_nodetree(group_ntree); } else { BLI_assert(!"Unknown ID type used for node"); @@ -1292,23 +1257,21 @@ void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree) /* Recursively build graph for material */ void DepsgraphNodeBuilder::build_material(Material *material) { - ID *material_id = &material->id; - if (material_id->tag & LIB_TAG_DOIT) { + if (built_map_.checkIsBuiltAndTag(material)) { return; } - material_id->tag |= LIB_TAG_DOIT; /* Material itself. */ - add_id_node(material_id); + add_id_node(&material->id); Material *material_cow = get_cow_datablock(material); /* Shading update. */ - add_operation_node(material_id, + add_operation_node(&material->id, DEG_NODE_TYPE_SHADING, function_bind(BKE_material_eval, _1, material_cow), DEG_OPCODE_MATERIAL_UPDATE); /* Material animation. */ - build_animdata(material_id); + build_animdata(&material->id); /* Textures. */ build_texture_stack(material->mtex); /* Material's nodetree. */ @@ -1328,33 +1291,29 @@ void DepsgraphNodeBuilder::build_texture_stack(MTex **texture_stack) } /* Recursively build graph for texture */ -void DepsgraphNodeBuilder::build_texture(Tex *tex) +void DepsgraphNodeBuilder::build_texture(Tex *texture) { - ID *tex_id = &tex->id; - if (tex_id->tag & LIB_TAG_DOIT) { + if (built_map_.checkIsBuiltAndTag(texture)) { return; } - tex_id->tag |= LIB_TAG_DOIT; /* Texture itself. */ - build_animdata(tex_id); + build_animdata(&texture->id); /* Texture's nodetree. */ - build_nodetree(tex->nodetree); + build_nodetree(texture->nodetree); /* Special cases for different IDs which texture uses. */ - if (tex->type == TEX_IMAGE) { - if (tex->ima != NULL) { - build_image(tex->ima); + if (texture->type == TEX_IMAGE) { + if (texture->ima != NULL) { + build_image(texture->ima); } } } void DepsgraphNodeBuilder::build_image(Image *image) { - ID *image_id = &image->id; - if (image_id->tag & LIB_TAG_DOIT) { + if (built_map_.checkIsBuiltAndTag(image)) { return; } - image_id->tag |= LIB_TAG_DOIT; /* Placeholder so we can add relations and tag ID node for update. */ - add_operation_node(image_id, + add_operation_node(&image->id, DEG_NODE_TYPE_PARAMETERS, NULL, DEG_OPCODE_PLACEHOLDER, @@ -1433,13 +1392,11 @@ void DepsgraphNodeBuilder::build_movieclip(MovieClip *clip) void DepsgraphNodeBuilder::build_lightprobe(Object *object) { LightProbe *probe = (LightProbe *)object->data; - ID *probe_id = &probe->id; - if (probe_id->tag & LIB_TAG_DOIT) { + if (built_map_.checkIsBuiltAndTag(probe)) { return; } - probe_id->tag |= LIB_TAG_DOIT; /* Placeholder so we can add relations and tag ID node for update. */ - add_operation_node(probe_id, + add_operation_node(&probe->id, DEG_NODE_TYPE_PARAMETERS, NULL, DEG_OPCODE_PLACEHOLDER, @@ -1450,7 +1407,7 @@ void DepsgraphNodeBuilder::build_lightprobe(Object *object) DEG_OPCODE_PLACEHOLDER, "LightProbe Eval"); - build_animdata(probe_id); + build_animdata(&probe->id); } } // namespace DEG diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index cc8ad08ea3b..ce0ad1e2037 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h @@ -30,6 +30,7 @@ #pragma once +#include "intern/builder/deg_builder_map.h" #include "intern/depsgraph_types.h" #include "DEG_depsgraph.h" /* used for DEG_depsgraph_use_copy_on_write() */ @@ -112,7 +113,7 @@ struct DepsgraphNodeBuilder { void begin_build(); void end_build(); - IDDepsNode *add_id_node(ID *id, bool do_tag = true); + IDDepsNode *add_id_node(ID *id); IDDepsNode *find_id_node(ID *id); TimeSourceDepsNode *add_time_source(); @@ -231,6 +232,7 @@ protected: Scene *scene_; GHash *cow_id_hash_; + BuilderMap built_map_; }; } // namespace DEG diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc index c3116db6146..0892a48caaf 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc @@ -135,7 +135,6 @@ void DepsgraphNodeBuilder::build_splineik_pose(Object *object, void DepsgraphNodeBuilder::build_rig(Object *object) { bArmature *armature = (bArmature *)object->data; - const short armature_tag = armature->id.tag; Scene *scene_cow; Object *object_cow; bArmature *armature_cow; @@ -163,9 +162,8 @@ void DepsgraphNodeBuilder::build_rig(Object *object) * mechanism in-between here to ensure that we can use same rig * multiple times in same scene. */ - if ((armature_tag & LIB_TAG_DOIT) == 0) { + if (built_map_.checkIsBuilt(armature)) { build_animdata(&armature->id); - /* Make sure pose is up-to-date with armature updates. */ add_operation_node(&armature->id, DEG_NODE_TYPE_PARAMETERS, diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc index 7a0fc790780..859ad36d06d 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc @@ -86,13 +86,13 @@ void DepsgraphNodeBuilder::build_view_layer( */ LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) { Object *object = base->object; - add_id_node(&object->id, false); + add_id_node(&object->id); } /* Create ID node for nested ID of nodetree as well, otherwise remapping * will not work correct either. */ if (scene->nodetree != NULL) { - add_id_node(&scene->nodetree->id, false); + add_id_node(&scene->nodetree->id); } /* Make sure we've got ID node, so we can get pointer to CoW datablock. */ diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 170efd5e8c6..0fd8f30557a 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -403,26 +403,11 @@ Depsgraph *DepsgraphRelationBuilder::getGraph() void DepsgraphRelationBuilder::begin_build() { - /* LIB_TAG_DOIT is used to indicate whether node for given ID was already - * created or not. - */ - BKE_main_id_tag_all(bmain_, LIB_TAG_DOIT, false); - /* XXX nested node trees are notr included in tag-clearing above, - * so we need to do this manually. - */ - FOREACH_NODETREE(bmain_, nodetree, id) - { - if (id != (ID *)nodetree) { - nodetree->id.tag &= ~LIB_TAG_DOIT; - } - } - FOREACH_NODETREE_END } void DepsgraphRelationBuilder::build_group(Object *object, Group *group) { - ID *group_id = &group->id; - bool group_done = (group_id->tag & LIB_TAG_DOIT) != 0; + const bool group_done = built_map_.checkIsBuiltAndTag(group); OperationKey object_local_transform_key(object != NULL ? &object->id : NULL, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_LOCAL); @@ -430,7 +415,6 @@ void DepsgraphRelationBuilder::build_group(Object *object, Group *group) LISTBASE_FOREACH (Base *, base, &group->view_layer->object_bases) { build_object(NULL, base->object); } - group_id->tag |= LIB_TAG_DOIT; } if (object != NULL) { LISTBASE_FOREACH (Base *, base, &group->view_layer->object_bases) { @@ -442,13 +426,12 @@ void DepsgraphRelationBuilder::build_group(Object *object, Group *group) void DepsgraphRelationBuilder::build_object(Base *base, Object *object) { - if (object->id.tag & LIB_TAG_DOIT) { + if (built_map_.checkIsBuiltAndTag(object)) { if (base != NULL) { build_object_flags(base, object); } return; } - object->id.tag |= LIB_TAG_DOIT; /* Object Transforms */ eDepsOperation_Code base_op = (object->parent) ? DEG_OPCODE_TRANSFORM_PARENT : DEG_OPCODE_TRANSFORM_LOCAL; @@ -1284,24 +1267,18 @@ void DepsgraphRelationBuilder::build_driver_variables(ID *id, FCurve *fcu) void DepsgraphRelationBuilder::build_world(World *world) { - ID *world_id = &world->id; - if (world_id->tag & LIB_TAG_DOIT) { + if (built_map_.checkIsBuiltAndTag(world)) { return; } - world_id->tag |= LIB_TAG_DOIT; - - build_animdata(world_id); - + build_animdata(&world->id); /* TODO: other settings? */ - /* textures */ build_texture_stack(world->mtex); - /* world's nodetree */ if (world->nodetree != NULL) { build_nodetree(world->nodetree); ComponentKey ntree_key(&world->nodetree->id, DEG_NODE_TYPE_SHADING); - ComponentKey world_key(world_id, DEG_NODE_TYPE_SHADING); + ComponentKey world_key(&world->id, DEG_NODE_TYPE_SHADING); add_relation(ntree_key, world_key, "NTree->World Shading Update"); } } @@ -1541,19 +1518,16 @@ void DepsgraphRelationBuilder::build_particles(Object *object) void DepsgraphRelationBuilder::build_particle_settings(ParticleSettings *part) { - ID *part_id = &part->id; - if (part_id->tag & LIB_TAG_DOIT) { + if (built_map_.checkIsBuiltAndTag(part)) { return; } - part_id->tag |= LIB_TAG_DOIT; - /* Animation data relations. */ build_animdata(&part->id); - OperationKey eval_key(part_id, + OperationKey eval_key(&part->id, DEG_NODE_TYPE_PARAMETERS, DEG_OPCODE_PARTICLE_SETTINGS_EVAL); - OperationKey recalc_clear_key(part_id, + 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"); @@ -1722,10 +1696,9 @@ void DepsgraphRelationBuilder::build_obdata_geom(Object *object) add_relation(geom_init_key, obdata_ubereval_key, "Object Geometry UberEval"); } - if (obdata->tag & LIB_TAG_DOIT) { + if (built_map_.checkIsBuiltAndTag(obdata)) { return; } - obdata->tag |= LIB_TAG_DOIT; /* Link object data evaluation node to exit operation. */ OperationKey obdata_geom_eval_key(obdata, DEG_NODE_TYPE_GEOMETRY, DEG_OPCODE_PLACEHOLDER, "Geometry Eval"); @@ -1821,22 +1794,20 @@ void DepsgraphRelationBuilder::build_obdata_geom(Object *object) // TODO: Link scene-camera links in somehow... void DepsgraphRelationBuilder::build_camera(Object *object) { - Camera *cam = (Camera *)object->data; - ID *camera_id = &cam->id; - if (camera_id->tag & LIB_TAG_DOIT) { + Camera *camera = (Camera *)object->data; + if (built_map_.checkIsBuiltAndTag(camera)) { 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); + 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 != NULL) { - ComponentKey dof_ob_key(&cam->dof_ob->id, DEG_NODE_TYPE_TRANSFORM); + if (camera->dof_ob != NULL) { + ComponentKey dof_ob_key(&camera->dof_ob->id, DEG_NODE_TYPE_TRANSFORM); add_relation(dof_ob_key, object_parameters_key, "Camera DOF"); } } @@ -1844,27 +1815,25 @@ void DepsgraphRelationBuilder::build_camera(Object *object) /* Lamps */ void DepsgraphRelationBuilder::build_lamp(Object *object) { - Lamp *la = (Lamp *)object->data; - ID *lamp_id = &la->id; - if (lamp_id->tag & LIB_TAG_DOIT) { + Lamp *lamp = (Lamp *)object->data; + if (built_map_.checkIsBuiltAndTag(lamp)) { 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); + 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 nodetree_key(&la->nodetree->id, DEG_NODE_TYPE_SHADING); + if (lamp->nodetree != NULL) { + build_nodetree(lamp->nodetree); + ComponentKey nodetree_key(&lamp->nodetree->id, DEG_NODE_TYPE_SHADING); add_relation(nodetree_key, lamp_parameters_key, "NTree->Lamp Parameters"); } /* textures */ - build_texture_stack(la->mtex); + build_texture_stack(lamp->mtex); if (DEG_depsgraph_use_copy_on_write()) { /* Make sure copy on write of lamp data is always properly updated for @@ -1873,7 +1842,7 @@ void DepsgraphRelationBuilder::build_lamp(Object *object) 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, + 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"); @@ -1885,9 +1854,11 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree) if (ntree == NULL) { return; } - ID *ntree_id = &ntree->id; - build_animdata(ntree_id); - ComponentKey shading_key(ntree_id, DEG_NODE_TYPE_SHADING); + if (built_map_.checkIsBuiltAndTag(ntree)) { + return; + } + build_animdata(&ntree->id); + ComponentKey shading_key(&ntree->id, DEG_NODE_TYPE_SHADING); /* nodetree's nodes... */ LISTBASE_FOREACH (bNode *, bnode, &ntree->nodes) { ID *id = bnode->id; @@ -1917,10 +1888,7 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree) } else if (bnode->type == NODE_GROUP) { bNodeTree *group_ntree = (bNodeTree *)id; - if ((group_ntree->id.tag & LIB_TAG_DOIT) == 0) { - build_nodetree(group_ntree); - group_ntree->id.tag |= LIB_TAG_DOIT; - } + build_nodetree(group_ntree); ComponentKey group_shading_key(&group_ntree->id, DEG_NODE_TYPE_SHADING); add_relation(group_shading_key, shading_key, "Group Node"); @@ -1930,37 +1898,32 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree) } } - OperationKey shading_update_key(ntree_id, + OperationKey shading_update_key(&ntree->id, DEG_NODE_TYPE_SHADING, DEG_OPCODE_MATERIAL_UPDATE); - OperationKey shading_parameters_key(ntree_id, + 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 */ -void DepsgraphRelationBuilder::build_material(Material *ma) +void DepsgraphRelationBuilder::build_material(Material *material) { - ID *ma_id = &ma->id; - if (ma_id->tag & LIB_TAG_DOIT) { + if (built_map_.checkIsBuiltAndTag(material)) { return; } - ma_id->tag |= LIB_TAG_DOIT; - /* animation */ - build_animdata(ma_id); - + build_animdata(&material->id); /* textures */ - build_texture_stack(ma->mtex); - + build_texture_stack(material->mtex); /* material's nodetree */ - if (ma->nodetree != NULL) { - build_nodetree(ma->nodetree); - OperationKey ntree_key(&ma->nodetree->id, + if (material->nodetree != NULL) { + build_nodetree(material->nodetree); + OperationKey ntree_key(&material->nodetree->id, DEG_NODE_TYPE_SHADING, DEG_OPCODE_MATERIAL_UPDATE); - OperationKey material_key(&ma->id, + OperationKey material_key(&material->id, DEG_NODE_TYPE_SHADING, DEG_OPCODE_MATERIAL_UPDATE); add_relation(ntree_key, material_key, "Material's NTree"); @@ -1968,28 +1931,22 @@ void DepsgraphRelationBuilder::build_material(Material *ma) } /* Recursively build graph for texture */ -void DepsgraphRelationBuilder::build_texture(Tex *tex) +void DepsgraphRelationBuilder::build_texture(Tex *texture) { - ID *tex_id = &tex->id; - if (tex_id->tag & LIB_TAG_DOIT) { + if (built_map_.checkIsBuiltAndTag(texture)) { return; } - tex_id->tag |= LIB_TAG_DOIT; - /* texture itself */ - build_animdata(tex_id); - + build_animdata(&texture->id); /* texture's nodetree */ - build_nodetree(tex->nodetree); + build_nodetree(texture->nodetree); } /* Texture-stack attached to some shading datablock */ void DepsgraphRelationBuilder::build_texture_stack(MTex **texture_stack) { - int i; - /* for now assume that all texture-stacks have same number of max items */ - for (i = 0; i < MAX_MTEX; i++) { + for (int i = 0; i < MAX_MTEX; i++) { MTex *mtex = texture_stack[i]; if (mtex && mtex->tex) build_texture(mtex->tex); @@ -2041,14 +1998,12 @@ void DepsgraphRelationBuilder::build_movieclip(MovieClip *clip) void DepsgraphRelationBuilder::build_lightprobe(Object *object) { LightProbe *probe = (LightProbe *)object->data; - ID *probe_id = &probe->id; - if (probe_id->tag & LIB_TAG_DOIT) { + if (built_map_.checkIsBuiltAndTag(probe)) { return; } - probe_id->tag |= LIB_TAG_DOIT; build_animdata(&probe->id); - OperationKey probe_key(probe_id, + OperationKey probe_key(&probe->id, DEG_NODE_TYPE_PARAMETERS, DEG_OPCODE_PLACEHOLDER, "LightProbe Eval"); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index ea7e23eca79..1720f19eb22 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -43,6 +43,7 @@ #include "BLI_utildefines.h" #include "BLI_string.h" +#include "intern/builder/deg_builder_map.h" #include "intern/nodes/deg_node.h" #include "intern/nodes/deg_node_component.h" #include "intern/nodes/deg_node_operation.h" @@ -339,6 +340,8 @@ private: /* State which demotes currently built entities. */ Scene *scene_; + + BuilderMap built_map_; }; struct DepsNodeHandle diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc index 0ae5f44c3ed..987a0654cca 100644 --- a/source/blender/depsgraph/intern/depsgraph.cc +++ b/source/blender/depsgraph/intern/depsgraph.cc @@ -294,7 +294,7 @@ IDDepsNode *Depsgraph::find_id_node(const ID *id) const return reinterpret_cast<IDDepsNode *>(BLI_ghash_lookup(id_hash, id)); } -IDDepsNode *Depsgraph::add_id_node(ID *id, bool do_tag, ID *id_cow_hint) +IDDepsNode *Depsgraph::add_id_node(ID *id, ID *id_cow_hint) { BLI_assert((id->tag & LIB_TAG_COPY_ON_WRITE) == 0); IDDepsNode *id_node = find_id_node(id); @@ -302,9 +302,6 @@ IDDepsNode *Depsgraph::add_id_node(ID *id, bool do_tag, ID *id_cow_hint) DepsNodeFactory *factory = deg_type_get_factory(DEG_NODE_TYPE_ID_REF); id_node = (IDDepsNode *)factory->create_node(id, "", id->name); id_node->init_copy_on_write(id_cow_hint); - if (do_tag) { - id->tag |= LIB_TAG_DOIT; - } /* Register node in ID hash. * * NOTE: We address ID nodes by the original ID pointer they are @@ -313,9 +310,6 @@ IDDepsNode *Depsgraph::add_id_node(ID *id, bool do_tag, ID *id_cow_hint) BLI_ghash_insert(id_hash, id, id_node); id_nodes.push_back(id_node); } - else if (do_tag) { - id->tag |= LIB_TAG_DOIT; - } return id_node; } diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h index f18b93c9807..985991e91e3 100644 --- a/source/blender/depsgraph/intern/depsgraph.h +++ b/source/blender/depsgraph/intern/depsgraph.h @@ -119,7 +119,7 @@ struct Depsgraph { TimeSourceDepsNode *find_time_source() const; IDDepsNode *find_id_node(const ID *id) const; - IDDepsNode *add_id_node(ID *id, bool do_tag = true, ID *id_cow_hint = NULL); + IDDepsNode *add_id_node(ID *id, ID *id_cow_hint = NULL); void clear_id_nodes(); /* Add new relationship between two nodes. */ |