Depsgraph: Replace LIB_TAG_DOIT with hash lookup
authorSergey Sharybin <sergey.vfx@gmail.com>
Thu, 22 Feb 2018 10:03:39 +0000 (11:03 +0100)
committerSergey Sharybin <sergey.vfx@gmail.com>
Thu, 22 Feb 2018 10:03:39 +0000 (11:03 +0100)
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 :)

source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
source/blender/depsgraph/intern/builder/deg_builder_nodes.h
source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
source/blender/depsgraph/intern/builder/deg_builder_relations.cc
source/blender/depsgraph/intern/builder/deg_builder_relations.h
source/blender/depsgraph/intern/depsgraph.cc

index 27bcc224ef5f7d551da573ade1c74e319e1d16f2..7572ee90c0b8acb0d08ec5df85aa3def38899cb0 100644 (file)
@@ -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,
index 2fa9ba01cc74b980991bccbf29e5fb61f752cdbc..825015194e2a24592ed7c1a829479dcc8b29bd19 100644 (file)
@@ -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
index 1a6b3f89f2642b20d2d5e82aeb043ac9e1a94206..63ffc95f336570bf6bf1bd51edc80fac4abe0879 100644 (file)
@@ -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,
index bcb70792af12841ba62cf8a1d92cd1dbd9251b29..c47006a78956e8f8a0da19b23b24910cd8b79531 100644 (file)
@@ -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);
index aa8dc2a4982233a7011cc4a187d5865a8175fa96..c4d77d97232876b17b3ea9d72974261685a422b9 100644 (file)
@@ -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
index 13b9f746e6b21e9904b39a52d8dd2b60213c40cf..1dbbd0cb89f1a367fc5f8a6bb7c74e42981fa749 100644 (file)
@@ -290,7 +290,6 @@ IDDepsNode *Depsgraph::add_id_node(ID *id, const char *name)
        if (!id_node) {
                DepsNodeFactory *factory = deg_type_get_factory(DEG_NODE_TYPE_ID_REF);
                id_node = (IDDepsNode *)factory->create_node(id, "", name);
-               id->tag |= LIB_TAG_DOIT;
                /* register */
                BLI_ghash_insert(id_hash, id, id_node);
                id_nodes.push_back(id_node);