[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [60109] trunk/blender/source/blender/ compositor: Cleanup and improvements of the compositor debug output.

Lukas Toenne lukas.toenne at googlemail.com
Fri Sep 13 15:36:47 CEST 2013


Revision: 60109
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=60109
Author:   lukastoenne
Date:     2013-09-13 13:36:47 +0000 (Fri, 13 Sep 2013)
Log Message:
-----------
Cleanup and improvements of the compositor debug output.

Debug code for graphviz output moved to a dedicated file COM_Debug.h/cpp.

The DebugInfo class has only static functions, which are called from a number of places to keep track of what is happening in the compositor. If debugging is disabled these are just inline stubs, so we
don't need #ifdefs everywhere and don't get any overhead.

The graphviz output is much more useful now. DebugInfo keeps track of node names in a static string map for meaningful names. It uses a number of colors for various special operation classes.
ExecutionGroups are indicated in graphviz with clusters.

Currently the graphviz .dot files are stored in the BLI_temporary_dir() folder. A separate dot file is generated for each stage of the ExecutionGroup scheduling, this is intended to give some idea of the
compositor progress, but could still be improved.

Modified Paths:
--------------
    trunk/blender/source/blender/compositor/CMakeLists.txt
    trunk/blender/source/blender/compositor/intern/COM_ExecutionGroup.cpp
    trunk/blender/source/blender/compositor/intern/COM_ExecutionGroup.h
    trunk/blender/source/blender/compositor/intern/COM_ExecutionSystem.cpp
    trunk/blender/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp
    trunk/blender/source/blender/compositor/intern/COM_ExecutionSystemHelper.h
    trunk/blender/source/blender/compositor/intern/COM_NodeBase.h
    trunk/blender/source/blender/compositor/intern/COM_NodeOperation.h
    trunk/blender/source/blender/compositor/operations/COM_SetColorOperation.h
    trunk/blender/source/blender/compositor/operations/COM_SetValueOperation.h
    trunk/blender/source/blender/compositor/operations/COM_SetVectorOperation.h
    trunk/blender/source/blender/compositor/operations/COM_TrackPositionOperation.h

Added Paths:
-----------
    trunk/blender/source/blender/compositor/intern/COM_Debug.cpp
    trunk/blender/source/blender/compositor/intern/COM_Debug.h

Modified: trunk/blender/source/blender/compositor/CMakeLists.txt
===================================================================
--- trunk/blender/source/blender/compositor/CMakeLists.txt	2013-09-13 13:34:12 UTC (rev 60108)
+++ trunk/blender/source/blender/compositor/CMakeLists.txt	2013-09-13 13:36:47 UTC (rev 60109)
@@ -101,6 +101,8 @@
 	intern/COM_ChannelInfo.h
 	intern/COM_SingleThreadedNodeOperation.cpp
 	intern/COM_SingleThreadedNodeOperation.h
+	intern/COM_Debug.cpp
+	intern/COM_Debug.h
 
 	operations/COM_QualityStepHelper.h
 	operations/COM_QualityStepHelper.cpp

Added: trunk/blender/source/blender/compositor/intern/COM_Debug.cpp
===================================================================
--- trunk/blender/source/blender/compositor/intern/COM_Debug.cpp	                        (rev 0)
+++ trunk/blender/source/blender/compositor/intern/COM_Debug.cpp	2013-09-13 13:36:47 UTC (rev 60109)
@@ -0,0 +1,413 @@
+/*
+ * Copyright 2013, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor: 
+ *		Lukas Toenne
+ */
+
+#include "COM_Debug.h"
+
+#ifdef COM_DEBUG
+
+#include <typeinfo>
+#include <map>
+#include <vector>
+
+extern "C" {
+#include "BLI_fileops.h"
+#include "BLI_path_util.h"
+#include "BLI_string.h"
+#include "DNA_node_types.h"
+#include "BKE_node.h"
+}
+
+#include "COM_Node.h"
+#include "COM_ExecutionSystem.h"
+#include "COM_ExecutionGroup.h"
+
+#include "COM_ReadBufferOperation.h"
+#include "COM_ViewerOperation.h"
+#include "COM_WriteBufferOperation.h"
+
+
+int DebugInfo::m_file_index = 0;
+DebugInfo::NodeNameMap DebugInfo::m_node_names;
+std::string DebugInfo::m_current_node_name;
+DebugInfo::GroupStateMap DebugInfo::m_group_states;
+
+std::string DebugInfo::node_name(NodeBase *node)
+{
+	NodeNameMap::const_iterator it = m_node_names.find(node);
+	if (it != m_node_names.end())
+		return it->second;
+	else
+		return "";
+}
+
+void DebugInfo::convert_started()
+{
+	m_node_names.clear();
+}
+
+void DebugInfo::execute_started(ExecutionSystem *system)
+{
+	m_file_index = 1;
+	m_group_states.clear();
+	for (int i = 0; i < system->getExecutionGroups().size(); ++i)
+		m_group_states[system->getExecutionGroups()[i]] = EG_WAIT;
+}
+
+void DebugInfo::node_added(Node *node)
+{
+	m_node_names[node] = std::string(node->getbNode() ? node->getbNode()->name : "");
+}
+
+void DebugInfo::node_to_operations(Node *node)
+{
+	m_current_node_name = m_node_names[node];
+}
+
+void DebugInfo::operation_added(NodeOperation *operation)
+{
+	m_node_names[operation] = m_current_node_name;
+}
+
+void DebugInfo::operation_read_write_buffer(NodeOperation *operation)
+{
+	m_current_node_name = m_node_names[operation];
+}
+
+void DebugInfo::execution_group_started(ExecutionGroup *group)
+{
+	m_group_states[group] = EG_RUNNING;
+}
+
+void DebugInfo::execution_group_finished(ExecutionGroup *group)
+{
+	m_group_states[group] = EG_FINISHED;
+}
+
+int DebugInfo::graphviz_operation(ExecutionSystem *system, NodeOperation *operation, ExecutionGroup *group, char *str, int maxlen)
+{
+	int len = 0;
+	
+	std::string fillcolor = "gainsboro";
+	if (operation->isViewerOperation()) {
+		ViewerOperation *viewer = (ViewerOperation *)operation;
+		if (viewer->isActiveViewerOutput()) {
+			fillcolor = "lightskyblue1";
+		}
+		else {
+			fillcolor = "lightskyblue3";
+		}
+	}
+	else if (operation->isOutputOperation(system->getContext().isRendering())) {
+		fillcolor = "dodgerblue1";
+	}
+	else if (operation->isSetOperation()) {
+		fillcolor = "khaki1";
+	}
+	else if (operation->isReadBufferOperation()) {
+		fillcolor = "darkolivegreen3";
+	}
+	else if (operation->isWriteBufferOperation()) {
+		fillcolor = "darkorange";
+	}
+	
+	len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "// OPERATION: %p\r\n", operation);
+	if (group)
+		len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "\"O_%p_%p\"", operation, group);
+	else
+		len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "\"O_%p\"", operation);
+	len += snprintf(str+len, maxlen>len ? maxlen-len : 0, " [fillcolor=%s,style=filled,shape=record,label=\"{", fillcolor.c_str());
+	
+	int totinputs = operation->getNumberOfInputSockets();
+	if (totinputs != 0) {
+		len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "{");
+		for (int k = 0; k < totinputs; k++) {
+			InputSocket *socket = operation->getInputSocket(k);
+			if (k != 0) {
+				len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "|");
+			}
+			len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "<IN_%p>", socket);
+			switch (socket->getDataType()) {
+				case COM_DT_VALUE:
+					len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "Value");
+					break;
+				case COM_DT_VECTOR:
+					len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "Vector");
+					break;
+				case COM_DT_COLOR:
+					len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "Color");
+					break;
+			}
+		}
+		len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "}");
+		len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "|");
+	}
+	
+	len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "%s\\n(%s)", m_node_names[operation].c_str(), typeid(*operation).name());
+	
+	len += snprintf(str+len, maxlen>len ? maxlen-len : 0, " (%d,%d)", operation->getWidth(), operation->getHeight());
+	
+	int totoutputs = operation->getNumberOfOutputSockets();
+	if (totoutputs != 0) {
+		len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "|");
+		len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "{");
+		for (int k = 0; k < totoutputs; k++) {
+			OutputSocket *socket = operation->getOutputSocket(k);
+			if (k != 0) {
+				len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "|");
+			}
+			len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "<OUT_%p>", socket);
+			switch (socket->getDataType()) {
+				case COM_DT_VALUE:
+					len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "Value");
+					break;
+				case COM_DT_VECTOR:
+					len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "Vector");
+					break;
+				case COM_DT_COLOR:
+					len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "Color");
+					break;
+			}
+		}
+		len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "}");
+	}
+	len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "}\"]");
+	len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "\r\n");
+	
+	return len;
+}
+
+int DebugInfo::graphviz_legend_color(const char *name, const char *color, char *str, int maxlen)
+{
+	int len = 0;
+	len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "<TR><TD>%s</TD><TD BGCOLOR=\"%s\"></TD></TR>\r\n", name, color);
+	return len;
+}
+
+int DebugInfo::graphviz_legend_line(const char *name, const char *color, const char *style, char *str, int maxlen)
+{
+	/* XXX TODO */
+	int len = 0;
+	len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "\r\n");
+	return len;
+}
+
+int DebugInfo::graphviz_legend_group(const char *name, const char *color, const char *style, char *str, int maxlen)
+{
+	int len = 0;
+	len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "<TR><TD>%s</TD><TD CELLPADDING=\"4\"><TABLE BORDER=\"1\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\"><TR><TD BGCOLOR=\"%s\"></TD></TR></TABLE></TD></TR>\r\n", name, color);
+	return len;
+}
+
+int DebugInfo::graphviz_legend(char *str, int maxlen)
+{
+	int len = 0;
+	
+	len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "{\r\n");
+	len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "rank = sink;\r\n");
+	len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "Legend [shape=none, margin=0, label=<\r\n");
+	
+	len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "  <TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"4\">\r\n");
+	len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "<TR><TD COLSPAN=\"2\"><B>Legend</B></TD></TR>\r\n");
+	
+	len += graphviz_legend_color("Operation", "gainsboro", str+len, maxlen>len ? maxlen-len : 0);
+	len += graphviz_legend_color("Output", "dodgerblue1", str+len, maxlen>len ? maxlen-len : 0);
+	len += graphviz_legend_color("Viewer", "lightskyblue3", str+len, maxlen>len ? maxlen-len : 0);
+	len += graphviz_legend_color("Active Viewer", "lightskyblue1", str+len, maxlen>len ? maxlen-len : 0);
+	len += graphviz_legend_color("Write Buffer", "darkorange", str+len, maxlen>len ? maxlen-len : 0);
+	len += graphviz_legend_color("Read Buffer", "darkolivegreen3", str+len, maxlen>len ? maxlen-len : 0);
+	len += graphviz_legend_color("Input Value", "khaki1", str+len, maxlen>len ? maxlen-len : 0);
+
+	len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "<TR><TD></TD></TR>\r\n");
+
+	len += graphviz_legend_group("Group Waiting", "white", "dashed", str+len, maxlen>len ? maxlen-len : 0);
+	len += graphviz_legend_group("Group Running", "firebrick1", "solid", str+len, maxlen>len ? maxlen-len : 0);
+	len += graphviz_legend_group("Group Finished", "chartreuse4", "solid", str+len, maxlen>len ? maxlen-len : 0);
+	
+	len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "</TABLE>\r\n");
+	len += snprintf(str+len, maxlen>len ? maxlen-len : 0, ">];\r\n");
+	len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "}\r\n");
+
+	return len;
+}
+
+bool DebugInfo::graphviz_system(ExecutionSystem *system, char *str, int maxlen)
+{
+	char strbuf[64];
+	int len = 0;
+	
+	len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "digraph compositorexecution {\r\n");
+	len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "ranksep=1.5\r\n");
+	len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "splines=false\r\n");
+	
+	int totnodes = system->getNodes().size();
+	for (int i = 0; i < totnodes; i++) {
+		Node *node = system->getNodes()[i];
+		len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "// NODE: %s\r\n", node->getbNode()->typeinfo->ui_name);
+	}
+	
+	int totgroups = system->getExecutionGroups().size();

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list