diff options
Diffstat (limited to 'source/blender/depsgraph/intern/nodes')
5 files changed, 113 insertions, 68 deletions
diff --git a/source/blender/depsgraph/intern/nodes/deg_node.cc b/source/blender/depsgraph/intern/nodes/deg_node.cc index d72ca384044..fdcfc129073 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node.cc @@ -34,6 +34,7 @@ #include "BLI_utildefines.h" +#include "intern/eval/deg_eval_copy_on_write.h" #include "intern/nodes/deg_node_component.h" #include "intern/nodes/deg_node_id.h" #include "intern/nodes/deg_node_operation.h" @@ -41,6 +42,7 @@ #include "intern/depsgraph_intern.h" #include "util/deg_util_foreach.h" +#include "util/deg_util_function.h" namespace DEG { diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.cc b/source/blender/depsgraph/intern/nodes/deg_node_component.cc index 9450ed7f17d..1f56edd1f87 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_component.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node_component.cc @@ -124,8 +124,7 @@ static void comp_node_hash_value_free(void *value_v) ComponentDepsNode::ComponentDepsNode() : entry_operation(NULL), - exit_operation(NULL), - layers(0) + exit_operation(NULL) { operations_map = BLI_ghash_new(comp_node_hash_key, comp_node_hash_key_cmp, @@ -158,15 +157,12 @@ string ComponentDepsNode::identifier() const char typebuf[16]; sprintf(typebuf, "(%d)", type); - char layers[16]; - sprintf(layers, "%u", this->layers); - - return string(typebuf) + name + " : " + idname + " (Layers: " + layers + ")"; + return string(typebuf) + name + " : " + idname; } OperationDepsNode *ComponentDepsNode::find_operation(OperationIDKey key) const { - OperationDepsNode *node; + OperationDepsNode *node = NULL; if (operations_map != NULL) { node = (OperationDepsNode *)BLI_ghash_lookup(operations_map, &key); } @@ -233,7 +229,7 @@ OperationDepsNode *ComponentDepsNode::add_operation(const DepsEvalOperationCb& o OperationDepsNode *op_node = find_operation(opcode, name, name_tag); if (!op_node) { DepsNodeFactory *factory = deg_type_get_factory(DEG_NODE_TYPE_OPERATION); - op_node = (OperationDepsNode *)factory->create_node(this->owner->id, "", name); + op_node = (OperationDepsNode *)factory->create_node(this->owner->id_orig, "", name); /* register opnode in this component's operation set */ OperationIDKey *key = OBJECT_GUARDED_NEW(OperationIDKey, opcode, name, name_tag); @@ -346,7 +342,7 @@ OperationDepsNode *ComponentDepsNode::get_exit_operation() return NULL; } -void ComponentDepsNode::finalize_build() +void ComponentDepsNode::finalize_build(Depsgraph * /*graph*/) { operations.reserve(BLI_ghash_size(operations_map)); GHASH_FOREACH_BEGIN(OperationDepsNode *, op_node, operations_map) @@ -381,36 +377,41 @@ void BoneComponentDepsNode::init(const ID *id, const char *subdata) /* Register all components. =============================== */ -DEG_COMPONENT_NODE_DEFINE(Animation, ANIMATION, ID_RECALC_NONE); -DEG_COMPONENT_NODE_DEFINE(Bone, BONE, ID_RECALC_NONE); -DEG_COMPONENT_NODE_DEFINE(Cache, CACHE, ID_RECALC_NONE); -DEG_COMPONENT_NODE_DEFINE(Geometry, GEOMETRY, ID_RECALC_NONE); -DEG_COMPONENT_NODE_DEFINE(Parameters, PARAMETERS, ID_RECALC_NONE); -DEG_COMPONENT_NODE_DEFINE(Particles, EVAL_PARTICLES, ID_RECALC_NONE); -DEG_COMPONENT_NODE_DEFINE(Proxy, PROXY, ID_RECALC_NONE); -DEG_COMPONENT_NODE_DEFINE(Pose, EVAL_POSE, ID_RECALC_NONE); -DEG_COMPONENT_NODE_DEFINE(Sequencer, SEQUENCER, ID_RECALC_NONE); -DEG_COMPONENT_NODE_DEFINE(Shading, SHADING, ID_RECALC_NONE); -DEG_COMPONENT_NODE_DEFINE(Transform, TRANSFORM, ID_RECALC_NONE); +DEG_COMPONENT_NODE_DEFINE(Animation, ANIMATION, ID_RECALC_ANIMATION); +DEG_COMPONENT_NODE_DEFINE(BatchCache, BATCH_CACHE, ID_RECALC_DRAW_CACHE); +DEG_COMPONENT_NODE_DEFINE(Bone, BONE, ID_RECALC_GEOMETRY); +DEG_COMPONENT_NODE_DEFINE(Cache, CACHE, ID_RECALC); +DEG_COMPONENT_NODE_DEFINE(CopyOnWrite, COPY_ON_WRITE, ID_RECALC); +DEG_COMPONENT_NODE_DEFINE(Geometry, GEOMETRY, ID_RECALC_GEOMETRY); +DEG_COMPONENT_NODE_DEFINE(LayerCollections, LAYER_COLLECTIONS, ID_RECALC_COLLECTIONS); +DEG_COMPONENT_NODE_DEFINE(Parameters, PARAMETERS, ID_RECALC); +DEG_COMPONENT_NODE_DEFINE(Particles, EVAL_PARTICLES, ID_RECALC_GEOMETRY); +DEG_COMPONENT_NODE_DEFINE(Proxy, PROXY, ID_RECALC_GEOMETRY); +DEG_COMPONENT_NODE_DEFINE(Pose, EVAL_POSE, ID_RECALC_GEOMETRY); +DEG_COMPONENT_NODE_DEFINE(Sequencer, SEQUENCER, ID_RECALC); +DEG_COMPONENT_NODE_DEFINE(Shading, SHADING, ID_RECALC_DRAW); +DEG_COMPONENT_NODE_DEFINE(ShadingParameters, SHADING_PARAMETERS, ID_RECALC_DRAW); +DEG_COMPONENT_NODE_DEFINE(Transform, TRANSFORM, ID_RECALC_TRANSFORM); /* Node Types Register =================================== */ void deg_register_component_depsnodes() { - deg_register_node_typeinfo(&DNTI_PARAMETERS); - deg_register_node_typeinfo(&DNTI_PROXY); deg_register_node_typeinfo(&DNTI_ANIMATION); - deg_register_node_typeinfo(&DNTI_TRANSFORM); - deg_register_node_typeinfo(&DNTI_GEOMETRY); - deg_register_node_typeinfo(&DNTI_SEQUENCER); - - deg_register_node_typeinfo(&DNTI_EVAL_POSE); deg_register_node_typeinfo(&DNTI_BONE); - + deg_register_node_typeinfo(&DNTI_CACHE); + deg_register_node_typeinfo(&DNTI_BATCH_CACHE); + deg_register_node_typeinfo(&DNTI_COPY_ON_WRITE); + deg_register_node_typeinfo(&DNTI_GEOMETRY); + deg_register_node_typeinfo(&DNTI_LAYER_COLLECTIONS); + deg_register_node_typeinfo(&DNTI_PARAMETERS); deg_register_node_typeinfo(&DNTI_EVAL_PARTICLES); + deg_register_node_typeinfo(&DNTI_PROXY); + deg_register_node_typeinfo(&DNTI_EVAL_POSE); + deg_register_node_typeinfo(&DNTI_SEQUENCER); deg_register_node_typeinfo(&DNTI_SHADING); - - deg_register_node_typeinfo(&DNTI_CACHE); + deg_register_node_typeinfo(&DNTI_SHADING_PARAMETERS); + deg_register_node_typeinfo(&DNTI_TRANSFORM); } } // namespace DEG diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.h b/source/blender/depsgraph/intern/nodes/deg_node_component.h index 985716deaac..b8009cc0a7f 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_component.h +++ b/source/blender/depsgraph/intern/nodes/deg_node_component.h @@ -127,7 +127,7 @@ struct ComponentDepsNode : public DepsNode { OperationDepsNode *get_entry_operation(); OperationDepsNode *get_exit_operation(); - void finalize_build(); + void finalize_build(Depsgraph *graph); IDDepsNode *owner; @@ -147,9 +147,7 @@ struct ComponentDepsNode : public DepsNode { OperationDepsNode *exit_operation; // XXX: a poll() callback to check if component's first node can be started? - - /* Temporary bitmask, used during graph construction. */ - unsigned int layers; + virtual bool depends_on_cow() { return true; } }; /* ---------------------------------------- */ @@ -173,14 +171,18 @@ struct ComponentDepsNode : public DepsNode { } DEG_COMPONENT_NODE_DECLARE_GENERIC(Animation); +DEG_COMPONENT_NODE_DECLARE_GENERIC(BatchCache); DEG_COMPONENT_NODE_DECLARE_GENERIC(Cache); +DEG_COMPONENT_NODE_DECLARE_GENERIC(CopyOnWrite); DEG_COMPONENT_NODE_DECLARE_GENERIC(Geometry); +DEG_COMPONENT_NODE_DECLARE_GENERIC(LayerCollections); DEG_COMPONENT_NODE_DECLARE_GENERIC(Parameters); DEG_COMPONENT_NODE_DECLARE_GENERIC(Particles); DEG_COMPONENT_NODE_DECLARE_GENERIC(Proxy); DEG_COMPONENT_NODE_DECLARE_GENERIC(Pose); DEG_COMPONENT_NODE_DECLARE_GENERIC(Sequencer); DEG_COMPONENT_NODE_DECLARE_GENERIC(Shading); +DEG_COMPONENT_NODE_DECLARE_GENERIC(ShadingParameters); DEG_COMPONENT_NODE_DECLARE_GENERIC(Transform); /* Bone Component */ diff --git a/source/blender/depsgraph/intern/nodes/deg_node_id.cc b/source/blender/depsgraph/intern/nodes/deg_node_id.cc index 478cc2863b0..edc5c0114f9 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_id.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node_id.cc @@ -41,8 +41,12 @@ extern "C" { #include "DNA_anim_types.h" #include "BKE_animsys.h" +#include "BKE_library.h" } +#include "DEG_depsgraph.h" + +#include "intern/eval/deg_eval_copy_on_write.h" #include "intern/nodes/deg_node_time.h" #include "intern/depsgraph_intern.h" @@ -58,8 +62,8 @@ IDDepsNode::ComponentIDKey::ComponentIDKey(eDepsNode_Type type, bool IDDepsNode::ComponentIDKey::operator== (const ComponentIDKey &other) const { - return type == other.type && - STREQ(name, other.name); + return type == other.type && + STREQ(name, other.name); } static unsigned int id_deps_node_hash_key(const void *key_v) @@ -95,33 +99,77 @@ static void id_deps_node_hash_value_free(void *value_v) /* Initialize 'id' node - from pointer data given. */ void IDDepsNode::init(const ID *id, const char *UNUSED(subdata)) { - /* Store ID-pointer. */ BLI_assert(id != NULL); - this->id = (ID *)id; - this->layers = (1 << 20) - 1; - this->eval_flags = 0; - - /* For object we initialize layers to layer from base. */ - if (GS(id->name) == ID_OB) { - this->layers = 0; - } + /* Store ID-pointer. */ + id_orig = (ID *)id; + eval_flags = 0; + linked_state = DEG_ID_LINKED_INDIRECTLY; components = BLI_ghash_new(id_deps_node_hash_key, id_deps_node_hash_key_cmp, "Depsgraph id components hash"); +} - /* NOTE: components themselves are created if/when needed. - * This prevents problems with components getting added - * twice if an ID-Ref needs to be created to house it... +void IDDepsNode::init_copy_on_write(ID *id_cow_hint) +{ + /* Early output for non-copy-on-write case: we keep CoW pointer same as + * an original one. + */ + if (!DEG_depsgraph_use_copy_on_write()) { + UNUSED_VARS(id_cow_hint); + id_cow = id_orig; + return; + } + /* Create pointer as early as possible, so we can use it for function + * bindings. Rest of data we'll be copying to the new datablock when + * it is actually needed. */ + if (id_cow_hint != NULL) { + // BLI_assert(deg_copy_on_write_is_needed(id_orig)); + if (deg_copy_on_write_is_needed(id_orig)) { + id_cow = id_cow_hint; + } + else { + id_cow = id_orig; + } + } + else if (deg_copy_on_write_is_needed(id_orig)) { + id_cow = (ID *)BKE_libblock_alloc_notest(GS(id_orig->name)); + DEG_COW_PRINT("Create shallow copy for %s: id_orig=%p id_cow=%p\n", + id_orig->name, id_orig, id_cow); + deg_tag_copy_on_write_id(id_cow, id_orig); + } + else { + id_cow = id_orig; + } } /* Free 'id' node. */ IDDepsNode::~IDDepsNode() { + destroy(); +} + +void IDDepsNode::destroy() +{ + if (id_orig == NULL) { + return; + } + BLI_ghash_free(components, id_deps_node_hash_key_free, id_deps_node_hash_value_free); + + /* Free memory used by this CoW ID. */ + if (id_cow != id_orig && id_cow != NULL) { + deg_free_copy_on_write_datablock(id_cow); + MEM_freeN(id_cow); + DEG_COW_PRINT("Destroy CoW for %s: id_orig=%p id_cow=%p\n", + id_orig->name, id_orig, id_cow); + } + + /* Tag that the node is freed. */ + id_orig = NULL; } ComponentDepsNode *IDDepsNode::find_component(eDepsNode_Type type, @@ -137,7 +185,7 @@ ComponentDepsNode *IDDepsNode::add_component(eDepsNode_Type type, ComponentDepsNode *comp_node = find_component(type, name); if (!comp_node) { DepsNodeFactory *factory = deg_type_get_factory(type); - comp_node = (ComponentDepsNode *)factory->create_node(this->id, "", name); + comp_node = (ComponentDepsNode *)factory->create_node(this->id_orig, "", name); /* Register. */ ComponentIDKey *key = OBJECT_GUARDED_NEW(ComponentIDKey, type, name); @@ -151,27 +199,17 @@ void IDDepsNode::tag_update(Depsgraph *graph) { GHASH_FOREACH_BEGIN(ComponentDepsNode *, comp_node, components) { - /* TODO(sergey): What about drievrs? */ - bool do_component_tag = comp_node->type != DEG_NODE_TYPE_ANIMATION; - if (comp_node->type == DEG_NODE_TYPE_ANIMATION) { - AnimData *adt = BKE_animdata_from_id(id); - /* Animation data might be null if relations are tagged for update. */ - if (adt != NULL && (adt->recalc & ADT_RECALC_ANIM)) { - do_component_tag = true; - } - } - if (do_component_tag) { - comp_node->tag_update(graph); - } + comp_node->tag_update(graph); } GHASH_FOREACH_END(); } -void IDDepsNode::finalize_build() +void IDDepsNode::finalize_build(Depsgraph *graph) { + /* Finalize build of all components. */ GHASH_FOREACH_BEGIN(ComponentDepsNode *, comp_node, components) { - comp_node->finalize_build(); + comp_node->finalize_build(graph); } GHASH_FOREACH_END(); } diff --git a/source/blender/depsgraph/intern/nodes/deg_node_id.h b/source/blender/depsgraph/intern/nodes/deg_node_id.h index 55022916c4d..505a1129192 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_id.h +++ b/source/blender/depsgraph/intern/nodes/deg_node_id.h @@ -47,7 +47,9 @@ struct IDDepsNode : public DepsNode { }; void init(const ID *id, const char *subdata); + void init_copy_on_write(ID *id_cow_hint = NULL); ~IDDepsNode(); + void destroy(); ComponentDepsNode *find_component(eDepsNode_Type type, const char *name = "") const; @@ -56,23 +58,23 @@ struct IDDepsNode : public DepsNode { void tag_update(Depsgraph *graph); - void finalize_build(); + void finalize_build(Depsgraph *graph); /* ID Block referenced. */ - ID *id; + ID *id_orig; + ID *id_cow; /* Hash to make it faster to look up components. */ GHash *components; - /* Layers of this node with accumulated layers of it's output relations. */ - unsigned int layers; - /* Additional flags needed for scene evaluation. * TODO(sergey): Only needed for until really granular updates * of all the entities. */ int eval_flags; + eDepsNode_LinkedState_Type linked_state; + DEG_DEPSNODE_DECLARE; }; |