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:
authorSergey Sharybin <sergey.vfx@gmail.com>2017-07-19 16:50:49 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2017-07-19 17:21:12 +0300
commit53c1d15675bf6240369ee0dbdc6f06780f7b68ba (patch)
treef2cadec793c170f57bf7b908d9b25e964cc58779 /source/blender
parent496d18614f1487c62f55dde13b211e7d12fc45ab (diff)
Depsgraph: Fix particle system freeing accessing freed particle settings
Need to ensure CoW IDs are freed in the right order.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/depsgraph/intern/depsgraph.cc24
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc5
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.h6
-rw-r--r--source/blender/depsgraph/intern/nodes/deg_node.cc11
-rw-r--r--source/blender/depsgraph/intern/nodes/deg_node.h1
5 files changed, 47 insertions, 0 deletions
diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc
index 1b94216d706..e1fdb2daf29 100644
--- a/source/blender/depsgraph/intern/depsgraph.cc
+++ b/source/blender/depsgraph/intern/depsgraph.cc
@@ -53,6 +53,8 @@ extern "C" {
#include "DEG_depsgraph.h"
+#include "intern/eval/deg_eval_copy_on_write.h"
+
#include "intern/nodes/deg_node.h"
#include "intern/nodes/deg_node_component.h"
#include "intern/nodes/deg_node_operation.h"
@@ -250,11 +252,13 @@ DepsNode *Depsgraph::find_node_from_pointer(const PointerRNA *ptr,
/* Node Management ---------------------------- */
+#ifndef WITH_COPY_ON_WRITE
static void id_node_deleter(void *value)
{
IDDepsNode *id_node = reinterpret_cast<IDDepsNode *>(value);
OBJECT_GUARDED_DELETE(id_node, IDDepsNode);
}
+#endif
TimeSourceDepsNode *Depsgraph::add_time_source()
{
@@ -299,7 +303,27 @@ IDDepsNode *Depsgraph::add_id_node(ID *id, const char *name, bool do_tag)
void Depsgraph::clear_id_nodes()
{
+#ifndef WITH_COPY_ON_WRITE
BLI_ghash_clear(id_hash, NULL, id_node_deleter);
+#else
+ /* Stupid workaround to ensure we free IDs in a proper order. */
+ GHASH_FOREACH_BEGIN(IDDepsNode *, id_node, id_hash)
+ {
+ if (!deg_copy_on_write_is_expanded(id_node->id_cow)) {
+ continue;
+ }
+ const short id_type = GS(id_node->id_cow->name);
+ if (id_type != ID_PA) {
+ id_node->destroy();
+ }
+ }
+ GHASH_FOREACH_END();
+ GHASH_FOREACH_BEGIN(IDDepsNode *, id_node, id_hash)
+ {
+ OBJECT_GUARDED_DELETE(id_node, IDDepsNode);
+ }
+ GHASH_FOREACH_END();
+#endif
}
/* Add new relationship between two nodes. */
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
index f7e08915531..10547da2505 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
@@ -742,4 +742,9 @@ void deg_tag_copy_on_write_id(ID *id_cow, const ID *id_orig)
id_cow->newid = (ID *)id_orig;
}
+bool deg_copy_on_write_is_expanded(const struct ID *id_cow)
+{
+ return check_datablock_expanded(id_cow);
+}
+
} // namespace DEG
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.h b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.h
index c5668ed4271..4ae1de3fdbc 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.h
@@ -86,4 +86,10 @@ bool deg_validate_copy_on_write_datablock(ID *id_cow);
/* Tag given ID block as being copy-on-wtritten. */
void deg_tag_copy_on_write_id(struct ID *id_cow, const struct ID *id_orig);
+/* Check whether ID datablock is expanded.
+ *
+ * TODO(sergey): Make it an inline function or a macro.
+ */
+bool deg_copy_on_write_is_expanded(const struct ID *id_cow);
+
} // namespace DEG
diff --git a/source/blender/depsgraph/intern/nodes/deg_node.cc b/source/blender/depsgraph/intern/nodes/deg_node.cc
index b01fa502b36..b80d95e9076 100644
--- a/source/blender/depsgraph/intern/nodes/deg_node.cc
+++ b/source/blender/depsgraph/intern/nodes/deg_node.cc
@@ -191,6 +191,15 @@ void IDDepsNode::init(const ID *id, const char *UNUSED(subdata))
/* 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);
@@ -202,6 +211,8 @@ IDDepsNode::~IDDepsNode()
DEG_COW_PRINT("Destroy CoW for %s: id_orig=%p id_cow=%p\n",
id_orig->name, id_orig, id_cow);
#endif
+ /* Tag that the node is freed. */
+ id_orig = NULL;
}
ComponentDepsNode *IDDepsNode::find_component(eDepsNode_Type type,
diff --git a/source/blender/depsgraph/intern/nodes/deg_node.h b/source/blender/depsgraph/intern/nodes/deg_node.h
index 4e03072d486..a12a43d8658 100644
--- a/source/blender/depsgraph/intern/nodes/deg_node.h
+++ b/source/blender/depsgraph/intern/nodes/deg_node.h
@@ -139,6 +139,7 @@ struct IDDepsNode : public DepsNode {
void init(const ID *id, const char *subdata);
~IDDepsNode();
+ void destroy();
ComponentDepsNode *find_component(eDepsNode_Type type,
const char *name = "") const;