47 int DebugInfo::m_file_index = 0;
50 std::string DebugInfo::m_current_node_name;
51 std::string DebugInfo::m_current_op_name;
56 NodeNameMap::const_iterator it = m_node_names.find(
node);
57 if (it != m_node_names.end()) {
65 OpNameMap::const_iterator it = m_op_names.find(op);
66 if (it != m_op_names.end()) {
80 m_group_states.clear();
81 for (ExecutionGroup *execution_group : system->m_groups) {
82 m_group_states[execution_group] =
EG_WAIT;
88 m_node_names[
node] = std::string(
node->getbNode() ?
node->getbNode()->name :
"");
93 m_current_node_name = m_node_names[
node];
98 m_op_names[operation] = m_current_node_name;
103 m_current_op_name = m_op_names[operation];
116 int DebugInfo::graphviz_operation(
const ExecutionSystem *system,
117 NodeOperation *operation,
118 const ExecutionGroup *group,
124 std::string fillcolor =
"gainsboro";
125 if (operation->get_flags().is_viewer_operation) {
126 const ViewerOperation *viewer = (
const ViewerOperation *)operation;
127 if (viewer->isActiveViewerOutput()) {
128 fillcolor =
"lightskyblue1";
131 fillcolor =
"lightskyblue3";
134 else if (operation->isOutputOperation(system->getContext().isRendering())) {
135 fillcolor =
"dodgerblue1";
137 else if (operation->get_flags().is_set_operation) {
138 fillcolor =
"khaki1";
140 else if (operation->get_flags().is_read_buffer_operation) {
141 fillcolor =
"darkolivegreen3";
143 else if (operation->get_flags().is_write_buffer_operation) {
144 fillcolor =
"darkorange";
155 maxlen >
len ? maxlen -
len : 0,
156 " [fillcolor=%s,style=filled,shape=record,label=\"{",
159 int totinputs = operation->getNumberOfInputSockets();
160 if (totinputs != 0) {
162 for (
int k = 0; k < totinputs; k++) {
163 NodeOperationInput *socket = operation->getInputSocket(k);
168 switch (socket->getDataType()) {
185 maxlen >
len ? maxlen -
len : 0,
187 m_op_names[operation].c_str(),
188 typeid(*operation).name());
191 maxlen >
len ? maxlen -
len : 0,
193 operation->getWidth(),
194 operation->getHeight());
196 int totoutputs = operation->getNumberOfOutputSockets();
197 if (totoutputs != 0) {
200 for (
int k = 0; k < totoutputs; k++) {
201 NodeOperationOutput *socket = operation->getOutputSocket(k);
206 switch (socket->getDataType()) {
226 int DebugInfo::graphviz_legend_color(
const char *name,
const char *color,
char *
str,
int maxlen)
230 maxlen >
len ? maxlen -
len : 0,
231 "<TR><TD>%s</TD><TD BGCOLOR=\"%s\"></TD></TR>\r\n",
237 int DebugInfo::graphviz_legend_line(
238 const char * ,
const char * ,
const char * ,
char *
str,
int maxlen)
246 int DebugInfo::graphviz_legend_group(
247 const char *name,
const char *color,
const char * ,
char *
str,
int maxlen)
251 maxlen >
len ? maxlen -
len : 0,
252 "<TR><TD>%s</TD><TD CELLPADDING=\"4\"><TABLE BORDER=\"1\" CELLBORDER=\"0\" "
253 "CELLSPACING=\"0\" CELLPADDING=\"0\"><TR><TD "
254 "BGCOLOR=\"%s\"></TD></TR></TABLE></TD></TR>\r\n",
260 int DebugInfo::graphviz_legend(
char *
str,
int maxlen)
267 str +
len, maxlen >
len ? maxlen -
len : 0,
"Legend [shape=none, margin=0, label=<\r\n");
271 maxlen >
len ? maxlen -
len : 0,
272 " <TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"4\">\r\n");
274 maxlen >
len ? maxlen -
len : 0,
275 "<TR><TD COLSPAN=\"2\"><B>Legend</B></TD></TR>\r\n");
277 len += graphviz_legend_color(
278 "NodeOperation",
"gainsboro",
str +
len, maxlen >
len ? maxlen -
len : 0);
279 len += graphviz_legend_color(
280 "Output",
"dodgerblue1",
str +
len, maxlen >
len ? maxlen -
len : 0);
281 len += graphviz_legend_color(
282 "Viewer",
"lightskyblue3",
str +
len, maxlen >
len ? maxlen -
len : 0);
283 len += graphviz_legend_color(
284 "Active Viewer",
"lightskyblue1",
str +
len, maxlen >
len ? maxlen -
len : 0);
285 len += graphviz_legend_color(
286 "Write Buffer",
"darkorange",
str +
len, maxlen >
len ? maxlen -
len : 0);
287 len += graphviz_legend_color(
288 "Read Buffer",
"darkolivegreen3",
str +
len, maxlen >
len ? maxlen -
len : 0);
289 len += graphviz_legend_color(
290 "Input Value",
"khaki1",
str +
len, maxlen >
len ? maxlen -
len : 0);
294 len += graphviz_legend_group(
295 "Group Waiting",
"white",
"dashed",
str +
len, maxlen >
len ? maxlen -
len : 0);
296 len += graphviz_legend_group(
297 "Group Running",
"firebrick1",
"solid",
str +
len, maxlen >
len ? maxlen -
len : 0);
298 len += graphviz_legend_group(
299 "Group Finished",
"chartreuse4",
"solid",
str +
len, maxlen >
len ? maxlen -
len : 0);
308 bool DebugInfo::graphviz_system(
const ExecutionSystem *system,
char *
str,
int maxlen)
318 std::map<NodeOperation *, std::vector<std::string>> op_groups;
320 for (
const ExecutionGroup *group : system->m_groups) {
324 if (m_group_states[group] ==
EG_WAIT) {
327 else if (m_group_states[group] ==
EG_RUNNING) {
338 for (NodeOperation *operation : group->m_operations) {
340 sprintf(strbuf,
"_%p", group);
341 op_groups[operation].push_back(std::string(strbuf));
343 len += graphviz_operation(
344 system, operation, group,
str +
len, maxlen >
len ? maxlen -
len : 0);
352 for (NodeOperation *operation : system->m_operations) {
353 if (op_groups.find(operation) != op_groups.end()) {
357 op_groups[operation].push_back(std::string(
""));
359 len += graphviz_operation(
360 system, operation,
nullptr,
str +
len, maxlen >
len ? maxlen -
len : 0);
363 for (NodeOperation *operation : system->m_operations) {
364 if (operation->get_flags().is_read_buffer_operation) {
365 ReadBufferOperation *read = (ReadBufferOperation *)operation;
366 WriteBufferOperation *write = read->getMemoryProxy()->getWriteBufferOperation();
367 std::vector<std::string> &read_groups = op_groups[read];
368 std::vector<std::string> &write_groups = op_groups[write];
370 for (
int k = 0; k < write_groups.size(); k++) {
371 for (
int l = 0;
l < read_groups.size();
l++) {
373 maxlen >
len ? maxlen -
len : 0,
374 "\"O_%p%s\" -> \"O_%p%s\" [style=dotted]\r\n",
376 write_groups[k].c_str(),
378 read_groups[
l].c_str());
384 for (NodeOperation *op : system->m_operations) {
385 for (NodeOperationInput &to : op->m_inputs) {
386 NodeOperationOutput *
from = to.getLink();
393 switch (
from->getDataType()) {
405 NodeOperation *to_op = &to.getOperation();
406 NodeOperation *from_op = &
from->getOperation();
407 std::vector<std::string> &from_groups = op_groups[from_op];
408 std::vector<std::string> &to_groups = op_groups[to_op];
411 maxlen >
len ? maxlen -
len : 0,
412 "// CONNECTION: %p.%p -> %p.%p\r\n",
417 for (
int k = 0; k < from_groups.size(); k++) {
418 for (
int l = 0;
l < to_groups.size();
l++) {
420 maxlen >
len ? maxlen -
len : 0,
421 R
"("O_%p%s":"OUT_%p":e -> "O_%p%s":"IN_%p":w)",
423 from_groups[k].c_str(),
426 to_groups[l].c_str(),
429 str + len, maxlen > len ? maxlen - len : 0, " [color=%s]", color.c_str());
440 return (
len < maxlen);
446 if (graphviz_system(system,
str,
sizeof(
str) - 1)) {
454 std::cout <<
"Writing compositor debug to: " << filename <<
"\n";
File and directory operations.
FILE * BLI_fopen(const char *filename, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void BLI_join_dirfile(char *__restrict dst, const size_t maxlen, const char *__restrict dir, const char *__restrict file) ATTR_NONNULL()
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
ATTR_WARN_UNUSED_RESULT const BMLoop * l
static void convert_started()
static std::string node_name(const Node *node)
static void node_added(const Node *node)
static void operation_read_write_buffer(const NodeOperation *operation)
static void execute_started(const ExecutionSystem *system)
static void execution_group_started(const ExecutionGroup *group)
static std::string operation_name(const NodeOperation *op)
static void operation_added(const NodeOperation *operation)
std::map< const Node *, std::string > NodeNameMap
std::map< const NodeOperation *, std::string > OpNameMap
static void graphviz(const ExecutionSystem *system)
std::map< const ExecutionGroup *, GroupState > GroupStateMap
static void node_to_operations(const Node *node)
static void execution_group_finished(const ExecutionGroup *group)
Class ExecutionGroup is a group of Operations that are executed as one. This grouping is used to comb...
the ExecutionSystem contains the whole compositor tree.
NodeOperation contains calculation logic.
static char * basename(char *string)
@ Vector
Vector data type.
void * BKE_tempdir_session