Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/depsgraph/intern/nodes/deg_node_id.cc')
-rw-r--r--source/blender/depsgraph/intern/nodes/deg_node_id.cc96
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();
}