[Bf-blender-cvs] [53c1d15675b] blender2.8: Depsgraph: Fix particle system freeing accessing freed particle settings

Sergey Sharybin noreply at git.blender.org
Wed Jul 19 17:34:14 CEST 2017


Commit: 53c1d15675bf6240369ee0dbdc6f06780f7b68ba
Author: Sergey Sharybin
Date:   Wed Jul 19 15:50:49 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB53c1d15675bf6240369ee0dbdc6f06780f7b68ba

Depsgraph: Fix particle system freeing accessing freed particle settings

Need to ensure CoW IDs are freed in the right order.

===================================================================

M	source/blender/depsgraph/intern/depsgraph.cc
M	source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
M	source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.h
M	source/blender/depsgraph/intern/nodes/deg_node.cc
M	source/blender/depsgraph/intern/nodes/deg_node.h

===================================================================

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;




More information about the Bf-blender-cvs mailing list