diff options
Diffstat (limited to 'source/blender/depsgraph/intern/nodes/deg_node_id.cc')
-rw-r--r-- | source/blender/depsgraph/intern/nodes/deg_node_id.cc | 96 |
1 files changed, 67 insertions, 29 deletions
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(); } |