diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-02-22 13:03:39 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-02-22 13:03:39 +0300 |
commit | 93072e44d11efe9528d2bb7a3a62784331bf0a08 (patch) | |
tree | b9b466b5e6f8526189057f458cdbdfb95af71623 /source/blender/depsgraph/intern/builder | |
parent | 76953a6ebd6d595df95277b3e3d5fa37fb1a9462 (diff) |
Depsgraph: Replace LIB_TAG_DOIT with hash lookup
This allows us to:
- Not mock around with tags stored in a global space,
and not to iterate over all datablocks in the database
to clear the tags.
- Properly deal with datablocks which might not be in main database.
While it sounds crazy, it might be handy when dealing with preview,
or some partial scene updates, such as motion paths.
- Avoids majority of places where depsgraph construction needed bmain.
This is something what could help in blender2.8 branch.
From tests with production file here did not see any measurable slowdown.
Hopefully, there is no functional changes :)
Diffstat (limited to 'source/blender/depsgraph/intern/builder')
5 files changed, 85 insertions, 168 deletions
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 27bcc224ef5..7572ee90c0b 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -279,32 +279,13 @@ OperationDepsNode *DepsgraphNodeBuilder::find_operation_node( /* **** 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; } void DepsgraphNodeBuilder::build_group(Base *base, 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; - LISTBASE_FOREACH (GroupObject *, go, &group->gobject) { build_object(base, go->ob); } @@ -312,7 +293,7 @@ void DepsgraphNodeBuilder::build_group(Base *base, Group *group) void DepsgraphNodeBuilder::build_object(Base *base, Object *object) { - const bool has_object = (object->id.tag & LIB_TAG_DOIT); + const bool has_object = built_map_.checkIsBuiltAndTag(object); IDDepsNode *id_node = (has_object) ? graph_->find_id_node(&object->id) : add_id_node(&object->id); @@ -334,7 +315,6 @@ void DepsgraphNodeBuilder::build_object(Base *base, Object *object) if (has_object) { return; } - object->id.tag |= LIB_TAG_DOIT; object->customdata_mask = 0; /* Transform. */ build_object_transform(object); @@ -424,7 +404,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; @@ -565,22 +545,18 @@ 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; } - + ID *world_id = &world->id; build_animdata(world_id); - /* world itself */ add_operation_node(world_id, DEG_NODE_TYPE_PARAMETERS, NULL, DEG_OPCODE_PARAMETERS_EVAL); - /* textures */ build_texture_stack(world->mtex); - /* world's nodetree */ if (world->nodetree) { build_nodetree(world->nodetree); @@ -785,7 +761,7 @@ void DepsgraphNodeBuilder::build_obdata_geom(Object *object) // add geometry collider relations } - if (obdata->tag & LIB_TAG_DOIT) { + if (built_map_.checkIsBuiltAndTag(obdata)) { return; } @@ -905,20 +881,16 @@ void DepsgraphNodeBuilder::build_obdata_geom(Object *object) void DepsgraphNodeBuilder::build_camera(Object *object) { /* TODO: Link scene-camera links in somehow... */ - 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; } - - 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); - - if (cam->dof_ob != NULL) { + if (camera->dof_ob != NULL) { /* TODO(sergey): For now parametrs are on object level. */ add_operation_node(&object->id, DEG_NODE_TYPE_PARAMETERS, NULL, DEG_OPCODE_PLACEHOLDER, "Camera DOF"); @@ -928,47 +900,40 @@ void DepsgraphNodeBuilder::build_camera(Object *object) /* Lamps */ void DepsgraphNodeBuilder::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; } - - build_animdata(&la->id); - + build_animdata(&lamp->id); /* TODO(sergey): Is it really how we're supposed to work with drivers? */ - add_operation_node(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) { - if (!ntree) + if (ntree == NULL) { return; + } + if (built_map_.checkIsBuiltAndTag(ntree)) { + return; + } /* nodetree itself */ - ID *ntree_id = &ntree->id; OperationDepsNode *op_node; - - build_animdata(ntree_id); - + build_animdata(&ntree->id); /* Parameters for drivers. */ - op_node = add_operation_node(ntree_id, + op_node = add_operation_node(&ntree->id, DEG_NODE_TYPE_PARAMETERS, NULL, DEG_OPCODE_PARAMETERS_EVAL); op_node->set_as_exit(); - /* nodetree's nodes... */ LISTBASE_FOREACH (bNode *, bnode, &ntree->nodes) { ID *id = bnode->id; @@ -998,9 +963,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"); @@ -1011,24 +974,20 @@ void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree) } /* Recursively build graph for material */ -void DepsgraphNodeBuilder::build_material(Material *ma) +void DepsgraphNodeBuilder::build_material(Material *material) { - ID *ma_id = &ma->id; - if (ma_id->tag & LIB_TAG_DOIT) { + if (built_map_.checkIsBuiltAndTag(material)) { return; } - - add_operation_node(ma_id, DEG_NODE_TYPE_SHADING, NULL, + add_operation_node(&material->id, DEG_NODE_TYPE_SHADING, NULL, DEG_OPCODE_PLACEHOLDER, "Material Update"); /* material animation */ - build_animdata(ma_id); - + build_animdata(&material->id); /* textures */ - build_texture_stack(ma->mtex); - + build_texture_stack(material->mtex); /* material's nodetree */ - build_nodetree(ma->nodetree); + build_nodetree(material->nodetree); } /* Texture-stack attached to some shading datablock */ @@ -1045,33 +1004,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, diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index 2fa9ba01cc7..825015194e2 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" struct Base; @@ -161,6 +162,8 @@ protected: /* State which demotes currently built entities. */ Scene *scene_; + + 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 1a6b3f89f26..63ffc95f336 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc @@ -123,9 +123,8 @@ void DepsgraphNodeBuilder::build_rig(Object *object) * Eventually, we need some type of proxy/isolation mechanism in-between here * to ensure that we can use same rig multiple times in same scene... */ - if ((arm->id.tag & LIB_TAG_DOIT) == 0) { + if (built_map_.checkIsBuilt(arm)) { build_animdata(&arm->id); - /* Make sure pose is up-to-date with armature updates. */ add_operation_node(&arm->id, DEG_NODE_TYPE_PARAMETERS, diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index bcb70792af1..c47006a7895 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -406,26 +406,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); @@ -438,15 +423,13 @@ void DepsgraphRelationBuilder::build_group(Object *object, Group *group) add_relation(dupli_transform_key, object_local_transform_key, "Dupligroup"); } } - group_id->tag |= LIB_TAG_DOIT; } void DepsgraphRelationBuilder::build_object(Object *object) { - if (object->id.tag & LIB_TAG_DOIT) { + if (built_map_.checkIsBuiltAndTag(object)) { return; } - object->id.tag |= LIB_TAG_DOIT; /* Object Transforms */ eDepsOperation_Code base_op = (object->parent) ? DEG_OPCODE_TRANSFORM_PARENT : DEG_OPCODE_TRANSFORM_LOCAL; @@ -1233,24 +1216,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_PARAMETERS); - ComponentKey world_key(world_id, DEG_NODE_TYPE_PARAMETERS); + ComponentKey world_key(&world->id, DEG_NODE_TYPE_PARAMETERS); add_relation(ntree_key, world_key, "NTree->World Parameters"); } } @@ -1609,10 +1586,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"); @@ -1708,16 +1684,14 @@ 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; /* DOF */ - if (cam->dof_ob) { + if (camera->dof_ob) { ComponentKey ob_param_key(&object->id, DEG_NODE_TYPE_PARAMETERS); - ComponentKey dof_ob_key(&cam->dof_ob->id, DEG_NODE_TYPE_TRANSFORM); + ComponentKey dof_ob_key(&camera->dof_ob->id, DEG_NODE_TYPE_TRANSFORM); add_relation(dof_ob_key, ob_param_key, "Camera DOF"); } } @@ -1725,36 +1699,33 @@ 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; /* 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); + if (lamp->nodetree != NULL) { + build_nodetree(lamp->nodetree); + ComponentKey parameters_key(&lamp->id, DEG_NODE_TYPE_PARAMETERS); + ComponentKey nodetree_key(&lamp->nodetree->id, DEG_NODE_TYPE_PARAMETERS); add_relation(nodetree_key, parameters_key, "NTree->Lamp Parameters"); } /* textures */ - build_texture_stack(la->mtex); + build_texture_stack(lamp->mtex); } 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, + } + if (built_map_.checkIsBuiltAndTag(ntree)) { + return; + } + build_animdata(&ntree->id); + OperationKey parameters_key(&ntree->id, DEG_NODE_TYPE_PARAMETERS, DEG_OPCODE_PARAMETERS_EVAL); - /* nodetree's nodes... */ LISTBASE_FOREACH (bNode *, bnode, &ntree->nodes) { ID *id = bnode->id; @@ -1784,10 +1755,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); OperationKey group_parameters_key(&group_ntree->id, DEG_NODE_TYPE_PARAMETERS, DEG_OPCODE_PARAMETERS_EVAL); @@ -1800,27 +1768,22 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree) } /* 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_PARAMETERS, DEG_OPCODE_PARAMETERS_EVAL); - OperationKey material_key(&ma->id, + OperationKey material_key(&material->id, DEG_NODE_TYPE_SHADING, DEG_OPCODE_PLACEHOLDER, "Material Update"); @@ -1829,28 +1792,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); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index aa8dc2a4982..c4d77d97232 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" @@ -318,6 +319,8 @@ private: /* State which demotes currently built entities. */ Scene *scene_; + + BuilderMap built_map_; }; struct DepsNodeHandle |