Blender  V3.3
depsgraph_debug.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2014 Blender Foundation. All rights reserved. */
3 
10 #include "BLI_utildefines.h"
11 
12 #include "DNA_scene_types.h"
13 
14 #include "DNA_object_types.h"
15 
16 #include "DEG_depsgraph.h"
17 #include "DEG_depsgraph_build.h"
18 #include "DEG_depsgraph_debug.h"
19 #include "DEG_depsgraph_query.h"
20 
21 #include "intern/debug/deg_debug.h"
22 #include "intern/depsgraph.h"
24 #include "intern/depsgraph_type.h"
28 
29 namespace deg = blender::deg;
30 
32 {
33  deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
34  deg_graph->debug.flags = flags;
35 }
36 
38 {
39  const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(depsgraph);
40  return deg_graph->debug.flags;
41 }
42 
43 void DEG_debug_name_set(struct Depsgraph *depsgraph, const char *name)
44 {
45  deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
46  deg_graph->debug.name = name;
47 }
48 
50 {
51  const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(depsgraph);
52  return deg_graph->debug.name.c_str();
53 }
54 
55 bool DEG_debug_compare(const struct Depsgraph *graph1, const struct Depsgraph *graph2)
56 {
57  BLI_assert(graph1 != nullptr);
58  BLI_assert(graph2 != nullptr);
59  const deg::Depsgraph *deg_graph1 = reinterpret_cast<const deg::Depsgraph *>(graph1);
60  const deg::Depsgraph *deg_graph2 = reinterpret_cast<const deg::Depsgraph *>(graph2);
61  if (deg_graph1->operations.size() != deg_graph2->operations.size()) {
62  return false;
63  }
64  /* TODO(sergey): Currently we only do real stupid check,
65  * which is fast but which isn't 100% reliable.
66  *
67  * Would be cool to make it more robust, but it's good enough
68  * for now. Also, proper graph check is actually NP-complex
69  * problem. */
70  return true;
71 }
72 
74  Main *bmain,
75  Scene *scene,
76  ViewLayer *view_layer)
77 {
78  Depsgraph *temp_depsgraph = DEG_graph_new(bmain, scene, view_layer, DEG_get_mode(graph));
79  bool valid = true;
80  DEG_graph_build_from_view_layer(temp_depsgraph);
81  if (!DEG_debug_compare(temp_depsgraph, graph)) {
82  fprintf(stderr, "ERROR! Depsgraph wasn't tagged for update when it should have!\n");
83  BLI_assert_msg(0, "This should not happen!");
84  valid = false;
85  }
86  DEG_graph_free(temp_depsgraph);
87  return valid;
88 }
89 
91 {
92  const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
93  /* Validate links exists in both directions. */
94  for (deg::OperationNode *node : deg_graph->operations) {
95  for (deg::Relation *rel : node->outlinks) {
96  int counter1 = 0;
97  for (deg::Relation *tmp_rel : node->outlinks) {
98  if (tmp_rel == rel) {
99  counter1++;
100  }
101  }
102  int counter2 = 0;
103  for (deg::Relation *tmp_rel : rel->to->inlinks) {
104  if (tmp_rel == rel) {
105  counter2++;
106  }
107  }
108  if (counter1 != counter2) {
109  printf(
110  "Relation exists in outgoing direction but not in "
111  "incoming (%d vs. %d).\n",
112  counter1,
113  counter2);
114  return false;
115  }
116  }
117  }
118 
119  for (deg::OperationNode *node : deg_graph->operations) {
120  for (deg::Relation *rel : node->inlinks) {
121  int counter1 = 0;
122  for (deg::Relation *tmp_rel : node->inlinks) {
123  if (tmp_rel == rel) {
124  counter1++;
125  }
126  }
127  int counter2 = 0;
128  for (deg::Relation *tmp_rel : rel->from->outlinks) {
129  if (tmp_rel == rel) {
130  counter2++;
131  }
132  }
133  if (counter1 != counter2) {
134  printf("Relation exists in incoming direction but not in outcoming (%d vs. %d).\n",
135  counter1,
136  counter2);
137  }
138  }
139  }
140 
141  /* Validate node valency calculated in both directions. */
142  for (deg::OperationNode *node : deg_graph->operations) {
143  node->num_links_pending = 0;
144  node->custom_flags = 0;
145  }
146 
147  for (deg::OperationNode *node : deg_graph->operations) {
148  if (node->custom_flags) {
149  printf("Node %s is twice in the operations!\n", node->identifier().c_str());
150  return false;
151  }
152  for (deg::Relation *rel : node->outlinks) {
153  if (rel->to->type == deg::NodeType::OPERATION) {
156  ++to->num_links_pending;
157  }
158  }
159  node->custom_flags = 1;
160  }
161 
162  for (deg::OperationNode *node : deg_graph->operations) {
163  int num_links_pending = 0;
164  for (deg::Relation *rel : node->inlinks) {
165  if (rel->from->type == deg::NodeType::OPERATION) {
166  num_links_pending++;
167  }
168  }
169  if (node->num_links_pending != num_links_pending) {
170  printf("Valency mismatch: %s, %u != %d\n",
171  node->identifier().c_str(),
172  node->num_links_pending,
173  num_links_pending);
174  printf("Number of inlinks: %d\n", (int)node->inlinks.size());
175  return false;
176  }
177  }
178  return true;
179 }
180 
181 /* ------------------------------------------------ */
182 
184  size_t *r_outer,
185  size_t *r_operations,
186  size_t *r_relations)
187 {
188  const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
189 
190  /* number of operations */
191  if (r_operations) {
192  /* All operations should be in this list, allowing us to count the total
193  * number of nodes. */
194  *r_operations = deg_graph->operations.size();
195  }
196 
197  /* Count number of outer nodes and/or relations between these. */
198  if (r_outer || r_relations) {
199  size_t tot_outer = 0;
200  size_t tot_rels = 0;
201 
202  for (deg::IDNode *id_node : deg_graph->id_nodes) {
203  tot_outer++;
204  for (deg::ComponentNode *comp_node : id_node->components.values()) {
205  tot_outer++;
206  for (deg::OperationNode *op_node : comp_node->operations) {
207  tot_rels += op_node->inlinks.size();
208  }
209  }
210  }
211 
212  deg::TimeSourceNode *time_source = deg_graph->find_time_source();
213  if (time_source != nullptr) {
214  tot_rels += time_source->inlinks.size();
215  }
216 
217  if (r_relations) {
218  *r_relations = tot_rels;
219  }
220  if (r_outer) {
221  *r_outer = tot_outer;
222  }
223  }
224 }
225 
226 static deg::string depsgraph_name_for_logging(struct Depsgraph *depsgraph)
227 {
228  const char *name = DEG_debug_name_get(depsgraph);
229  if (name[0] == '\0') {
230  return "";
231  }
232  return "[" + deg::string(name) + "]: ";
233 }
234 
236 {
237  fprintf(stdout, "%s", depsgraph_name_for_logging(depsgraph).c_str());
238 }
239 
241  const char *function_name,
242  const char *object_name,
243  const void *object_address)
244 {
246  return;
247  }
248  fprintf(stdout,
249  "%s%s on %s %s(%p)%s\n",
251  function_name,
252  object_name,
253  deg::color_for_pointer(object_address).c_str(),
254  object_address,
255  deg::color_end().c_str());
256  fflush(stdout);
257 }
258 
260  const char *function_name,
261  const char *object_name,
262  const void *object_address,
263  const char *subdata_comment,
264  const char *subdata_name,
265  const void *subdata_address)
266 {
268  return;
269  }
270  fprintf(stdout,
271  "%s%s on %s %s(%p)%s %s %s %s(%p)%s\n",
273  function_name,
274  object_name,
275  deg::color_for_pointer(object_address).c_str(),
276  object_address,
277  deg::color_end().c_str(),
278  subdata_comment,
279  subdata_name,
280  deg::color_for_pointer(subdata_address).c_str(),
281  subdata_address,
282  deg::color_end().c_str());
283  fflush(stdout);
284 }
285 
287  const char *function_name,
288  const char *object_name,
289  const void *object_address,
290  const char *subdata_comment,
291  const char *subdata_name,
292  const void *subdata_address,
293  const int subdata_index)
294 {
296  return;
297  }
298  fprintf(stdout,
299  "%s%s on %s %s(%p)%s %s %s[%d] %s(%p)%s\n",
301  function_name,
302  object_name,
303  deg::color_for_pointer(object_address).c_str(),
304  object_address,
305  deg::color_end().c_str(),
306  subdata_comment,
307  subdata_name,
308  subdata_index,
309  deg::color_for_pointer(subdata_address).c_str(),
310  subdata_address,
311  deg::color_end().c_str());
312  fflush(stdout);
313 }
314 
316  const char *function_name,
317  const char *object_name,
318  const void *object_address,
319  const char *parent_comment,
320  const char *parent_name,
321  const void *parent_address)
322 {
324  return;
325  }
326  fprintf(stdout,
327  "%s%s on %s %s(%p) [%s] %s %s %s(%p)%s\n",
329  function_name,
330  object_name,
331  deg::color_for_pointer(object_address).c_str(),
332  object_address,
333  deg::color_end().c_str(),
334  parent_comment,
335  parent_name,
336  deg::color_for_pointer(parent_address).c_str(),
337  parent_address,
338  deg::color_end().c_str());
339  fflush(stdout);
340 }
341 
343  const char *function_name,
344  const char *object_name,
345  const void *object_address,
346  float time)
347 {
349  return;
350  }
351  fprintf(stdout,
352  "%s%s on %s %s(%p)%s at time %f\n",
354  function_name,
355  object_name,
356  deg::color_for_pointer(object_address).c_str(),
357  object_address,
358  deg::color_end().c_str(),
359  time);
360  fflush(stdout);
361 }
@ G_DEBUG_DEPSGRAPH_EVAL
Definition: BKE_global.h:183
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition: BLI_assert.h:53
Depsgraph * DEG_graph_new(struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer, eEvaluationMode mode)
Definition: depsgraph.cc:267
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
void DEG_graph_free(Depsgraph *graph)
Definition: depsgraph.cc:295
void DEG_graph_build_from_view_layer(struct Depsgraph *graph)
eEvaluationMode DEG_get_mode(const Depsgraph *graph)
Object is a sort of wrapper for general info.
int64_t size() const
Definition: BLI_vector.hh:694
OperationNode * node
Depsgraph * graph
const IDNode * id_node
double time
Scene scene
const Depsgraph * depsgraph
void DEG_debug_flags_set(Depsgraph *depsgraph, int flags)
static deg::string depsgraph_name_for_logging(struct Depsgraph *depsgraph)
void DEG_debug_print_eval_time(struct Depsgraph *depsgraph, const char *function_name, const char *object_name, const void *object_address, float time)
int DEG_debug_flags_get(const Depsgraph *depsgraph)
bool DEG_debug_compare(const struct Depsgraph *graph1, const struct Depsgraph *graph2)
bool DEG_debug_consistency_check(Depsgraph *graph)
void DEG_debug_print_eval(struct Depsgraph *depsgraph, const char *function_name, const char *object_name, const void *object_address)
bool DEG_debug_graph_relations_validate(Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer)
void DEG_debug_name_set(struct Depsgraph *depsgraph, const char *name)
void DEG_debug_print_begin(struct Depsgraph *depsgraph)
void DEG_debug_print_eval_subdata(struct Depsgraph *depsgraph, const char *function_name, const char *object_name, const void *object_address, const char *subdata_comment, const char *subdata_name, const void *subdata_address)
void DEG_stats_simple(const Depsgraph *graph, size_t *r_outer, size_t *r_operations, size_t *r_relations)
const char * DEG_debug_name_get(struct Depsgraph *depsgraph)
void DEG_debug_print_eval_subdata_index(struct Depsgraph *depsgraph, const char *function_name, const char *object_name, const void *object_address, const char *subdata_comment, const char *subdata_name, const void *subdata_address, const int subdata_index)
void DEG_debug_print_eval_parent_typed(struct Depsgraph *depsgraph, const char *function_name, const char *object_name, const void *object_address, const char *parent_comment, const char *parent_name, const void *parent_address)
string color_for_pointer(const void *pointer)
Definition: deg_debug.cc:64
string color_end()
Definition: deg_debug.cc:76
Definition: BKE_main.h:121
TimeSourceNode * find_time_source() const
Definition: depsgraph.cc:91
OperationNodes operations
Definition: depsgraph.h:120
DepsgraphDebug debug
Definition: depsgraph.h:150
IDDepsNodes id_nodes
Definition: depsgraph.h:86
Relations inlinks
Definition: deg_node.h:173
Relations outlinks
Definition: deg_node.h:174