[Bf-blender-cvs] [63d3819] depsgraph_refactor: Depsgraph: Add graph consistency check function

Sergey Sharybin noreply at git.blender.org
Fri Jan 9 12:20:14 CET 2015


Commit: 63d38190566e5e43a1676f92016ed6c2ca0ac742
Author: Sergey Sharybin
Date:   Fri Jan 9 16:18:58 2015 +0500
Branches: depsgraph_refactor
https://developer.blender.org/rB63d38190566e5e43a1676f92016ed6c2ca0ac742

Depsgraph: Add graph consistency check function

It might be not so much advanced atm, but allowed to nail previous issue down.

Commented out, so no impact on speed at all. Plus i've kept it aborting blender
which might be too rude for other developers/users.

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

M	source/blender/depsgraph/DEG_depsgraph_debug.h
M	source/blender/depsgraph/intern/depsgraph_build.cpp
M	source/blender/depsgraph/intern/depsgraph_debug.cpp

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

diff --git a/source/blender/depsgraph/DEG_depsgraph_debug.h b/source/blender/depsgraph/DEG_depsgraph_debug.h
index 1b27f67..53dd205 100644
--- a/source/blender/depsgraph/DEG_depsgraph_debug.h
+++ b/source/blender/depsgraph/DEG_depsgraph_debug.h
@@ -95,10 +95,13 @@ bool DEG_debug_compare(const struct Depsgraph *graph1,
                        const struct Depsgraph *graph2);
 
 /* Check that dependnecies in the graph are really up to date. */
-void DEG_debug_scene_relations_validate(struct Main *bmain,
+bool DEG_debug_scene_relations_validate(struct Main *bmain,
                                         struct Scene *scene);
 
 
+/* Perform consistency check on the graph. */
+bool DEG_debug_consistency_check(struct Depsgraph *graph);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
diff --git a/source/blender/depsgraph/intern/depsgraph_build.cpp b/source/blender/depsgraph/intern/depsgraph_build.cpp
index 5944f18..a99f22a 100644
--- a/source/blender/depsgraph/intern/depsgraph_build.cpp
+++ b/source/blender/depsgraph/intern/depsgraph_build.cpp
@@ -84,6 +84,7 @@ extern "C" {
 #include "BKE_world.h"
 
 #include "DEG_depsgraph.h"
+#include "DEG_depsgraph_debug.h"
 #include "DEG_depsgraph_build.h"
 
 #include "RNA_access.h"
@@ -570,6 +571,12 @@ void DEG_graph_build_from_scene(Depsgraph *graph, Main *bmain, Scene *scene)
 	deg_graph_transitive_reduction(graph);
 	
 	deg_graph_flush_node_layers(graph);
+#if 0
+	if (!DEG_debug_consistency_check(graph)) {
+		printf("Consistency validation failed, ABORTING!\n");
+		abort();
+	}
+#endif
 }
 
 /* Tag graph relations for update. */
diff --git a/source/blender/depsgraph/intern/depsgraph_debug.cpp b/source/blender/depsgraph/intern/depsgraph_debug.cpp
index 525ba87..57a4d1a 100644
--- a/source/blender/depsgraph/intern/depsgraph_debug.cpp
+++ b/source/blender/depsgraph/intern/depsgraph_debug.cpp
@@ -948,16 +948,159 @@ bool DEG_debug_compare(const struct Depsgraph *graph1,
 	return true;
 }
 
-void DEG_debug_scene_relations_validate(Main *bmain,
+bool DEG_debug_scene_relations_validate(Main *bmain,
                                         Scene *scene)
 {
 	Depsgraph *depsgraph = DEG_graph_new();
+	bool valid = true;
 	DEG_graph_build_from_scene(depsgraph, bmain, scene);
 	if (!DEG_debug_compare(depsgraph, scene->depsgraph)) {
 		fprintf(stderr, "ERROR! Depsgraph wasn't tagged for update when it should have!\n");
 		BLI_assert(!"This should not happen!");
+		valid = false;
 	}
 	DEG_graph_free(depsgraph);
+	return valid;
+}
+
+bool DEG_debug_consistency_check(Depsgraph *graph)
+{
+	/* Validate links exists in both directions. */
+	for (Depsgraph::OperationNodes::const_iterator it_op = graph->operations.begin();
+	     it_op != graph->operations.end();
+	     ++it_op)
+	{
+		OperationDepsNode *node = *it_op;
+		for (OperationDepsNode::Relations::const_iterator it_rel = node->outlinks.begin();
+		     it_rel != node->outlinks.end();
+		     ++it_rel)
+		{
+			DepsRelation *rel = *it_rel;
+
+			int counter1 = 0;
+			for (OperationDepsNode::Relations::const_iterator tmp_rel = node->outlinks.begin();
+			     tmp_rel != node->outlinks.end();
+			     ++tmp_rel)
+			{
+				if (*tmp_rel == rel) {
+					++counter1;
+				}
+			}
+
+			int counter2 = 0;
+			for (OperationDepsNode::Relations::const_iterator tmp_rel = rel->to->inlinks.begin();
+			     tmp_rel != rel->to->inlinks.end();
+			     ++tmp_rel)
+			{
+				if (*tmp_rel == rel) {
+					++counter2;
+				}
+			}
+
+			if (counter1 != counter2) {
+				printf("Relation exists in outgoing direction but not in incoming (%d vs. %d).\n",
+				       counter1, counter2);
+				return false;
+			}
+		}
+	}
+
+	for (Depsgraph::OperationNodes::const_iterator it_op = graph->operations.begin();
+	     it_op != graph->operations.end();
+	     ++it_op)
+	{
+		OperationDepsNode *node = *it_op;
+		for (OperationDepsNode::Relations::const_iterator it_rel = node->inlinks.begin();
+		     it_rel != node->inlinks.end();
+		     ++it_rel)
+		{
+			DepsRelation *rel = *it_rel;
+
+			int counter1 = 0;
+			for (OperationDepsNode::Relations::const_iterator tmp_rel = node->inlinks.begin();
+			     tmp_rel != node->inlinks.end();
+			     ++tmp_rel)
+			{
+				if (*tmp_rel == rel) {
+					++counter1;
+				}
+			}
+
+			int counter2 = 0;
+			for (OperationDepsNode::Relations::const_iterator tmp_rel = rel->from->outlinks.begin();
+			     tmp_rel != rel->from->outlinks.end();
+			     ++tmp_rel)
+			{
+				if (*tmp_rel == rel) {
+					++counter2;
+				}
+			}
+
+			if (counter1 != counter2) {
+				printf("Relation exists in incoming direction but not in outcoming (%d vs. %d).\n",
+				       counter1, counter2);
+			}
+		}
+	}
+
+	/* Validate node valency calculated in both directions. */
+	for (Depsgraph::OperationNodes::const_iterator it_op = graph->operations.begin();
+	     it_op != graph->operations.end();
+	     ++it_op)
+	{
+		OperationDepsNode *node = *it_op;
+		node->num_links_pending = 0;
+		node->done = 0;
+	}
+
+	for (Depsgraph::OperationNodes::const_iterator it_op = graph->operations.begin();
+	     it_op != graph->operations.end();
+	     ++it_op)
+	{
+		OperationDepsNode *node = *it_op;
+		if (node->done) {
+			printf("Node %s is twice in the operations!\n",
+			       node->identifier().c_str());
+			return false;
+		}
+		for (OperationDepsNode::Relations::const_iterator it_rel = node->outlinks.begin();
+		     it_rel != node->outlinks.end();
+		     ++it_rel)
+		{
+			DepsRelation *rel = *it_rel;
+			if (rel->to->type == DEPSNODE_TYPE_OPERATION) {
+				OperationDepsNode *to = (OperationDepsNode *)rel->to;
+				BLI_assert(to->num_links_pending < to->inlinks.size());
+				++to->num_links_pending;
+			}
+		}
+		node->done = 1;
+	}
+
+	for (Depsgraph::OperationNodes::const_iterator it_op = graph->operations.begin();
+	     it_op != graph->operations.end();
+	     ++it_op)
+	{
+		OperationDepsNode *node = *it_op;
+		int num_links_pending = 0;
+		for (OperationDepsNode::Relations::const_iterator it_rel = node->inlinks.begin();
+		     it_rel != node->inlinks.end();
+		     ++it_rel)
+		{
+			DepsRelation *rel = *it_rel;
+			if (rel->from->type == DEPSNODE_TYPE_OPERATION) {
+				++num_links_pending;
+			}
+		}
+		if (node->num_links_pending != num_links_pending) {
+			printf("Valency mismatch: %s, %d != %d\n",
+			       node->identifier().c_str(),
+			       node->num_links_pending, num_links_pending);
+			printf("Number of inlinks: %lu\n", node->inlinks.size());
+			return false;
+		}
+	}
+	return true;
 }
 
 /* ------------------------------------------------ */




More information about the Bf-blender-cvs mailing list