Blender  V2.93
depsgraph_debug.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2014 Blender Foundation.
17  * All rights reserved.
18  */
19 
26 #include "BLI_utildefines.h"
27 
28 #include "DNA_scene_types.h"
29 
30 #include "DNA_object_types.h"
31 
32 #include "DEG_depsgraph.h"
33 #include "DEG_depsgraph_build.h"
34 #include "DEG_depsgraph_debug.h"
35 #include "DEG_depsgraph_query.h"
36 
37 #include "intern/debug/deg_debug.h"
38 #include "intern/depsgraph.h"
40 #include "intern/depsgraph_type.h"
44 
45 namespace deg = blender::deg;
46 
48 {
49  deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
50  deg_graph->debug.flags = flags;
51 }
52 
54 {
55  const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(depsgraph);
56  return deg_graph->debug.flags;
57 }
58 
59 void DEG_debug_name_set(struct Depsgraph *depsgraph, const char *name)
60 {
61  deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
62  deg_graph->debug.name = name;
63 }
64 
66 {
67  const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(depsgraph);
68  return deg_graph->debug.name.c_str();
69 }
70 
71 bool DEG_debug_compare(const struct Depsgraph *graph1, const struct Depsgraph *graph2)
72 {
73  BLI_assert(graph1 != nullptr);
74  BLI_assert(graph2 != nullptr);
75  const deg::Depsgraph *deg_graph1 = reinterpret_cast<const deg::Depsgraph *>(graph1);
76  const deg::Depsgraph *deg_graph2 = reinterpret_cast<const deg::Depsgraph *>(graph2);
77  if (deg_graph1->operations.size() != deg_graph2->operations.size()) {
78  return false;
79  }
80  /* TODO(sergey): Currently we only do real stupid check,
81  * which is fast but which isn't 100% reliable.
82  *
83  * Would be cool to make it more robust, but it's good enough
84  * for now. Also, proper graph check is actually NP-complex
85  * problem. */
86  return true;
87 }
88 
90  Main *bmain,
91  Scene *scene,
92  ViewLayer *view_layer)
93 {
94  Depsgraph *temp_depsgraph = DEG_graph_new(bmain, scene, view_layer, DEG_get_mode(graph));
95  bool valid = true;
96  DEG_graph_build_from_view_layer(temp_depsgraph);
97  if (!DEG_debug_compare(temp_depsgraph, graph)) {
98  fprintf(stderr, "ERROR! Depsgraph wasn't tagged for update when it should have!\n");
99  BLI_assert(!"This should not happen!");
100  valid = false;
101  }
102  DEG_graph_free(temp_depsgraph);
103  return valid;
104 }
105 
107 {
108  const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
109  /* Validate links exists in both directions. */
110  for (deg::OperationNode *node : deg_graph->operations) {
111  for (deg::Relation *rel : node->outlinks) {
112  int counter1 = 0;
113  for (deg::Relation *tmp_rel : node->outlinks) {
114  if (tmp_rel == rel) {
115  counter1++;
116  }
117  }
118  int counter2 = 0;
119  for (deg::Relation *tmp_rel : rel->to->inlinks) {
120  if (tmp_rel == rel) {
121  counter2++;
122  }
123  }
124  if (counter1 != counter2) {
125  printf(
126  "Relation exists in outgoing direction but not in "
127  "incoming (%d vs. %d).\n",
128  counter1,
129  counter2);
130  return false;
131  }
132  }
133  }
134 
135  for (deg::OperationNode *node : deg_graph->operations) {
136  for (deg::Relation *rel : node->inlinks) {
137  int counter1 = 0;
138  for (deg::Relation *tmp_rel : node->inlinks) {
139  if (tmp_rel == rel) {
140  counter1++;
141  }
142  }
143  int counter2 = 0;
144  for (deg::Relation *tmp_rel : rel->from->outlinks) {
145  if (tmp_rel == rel) {
146  counter2++;
147  }
148  }
149  if (counter1 != counter2) {
150  printf("Relation exists in incoming direction but not in outcoming (%d vs. %d).\n",
151  counter1,
152  counter2);
153  }
154  }
155  }
156 
157  /* Validate node valency calculated in both directions. */
158  for (deg::OperationNode *node : deg_graph->operations) {
159  node->num_links_pending = 0;
160  node->custom_flags = 0;
161  }
162 
163  for (deg::OperationNode *node : deg_graph->operations) {
164  if (node->custom_flags) {
165  printf("Node %s is twice in the operations!\n", node->identifier().c_str());
166  return false;
167  }
168  for (deg::Relation *rel : node->outlinks) {
169  if (rel->to->type == deg::NodeType::OPERATION) {
172  ++to->num_links_pending;
173  }
174  }
175  node->custom_flags = 1;
176  }
177 
178  for (deg::OperationNode *node : deg_graph->operations) {
179  int num_links_pending = 0;
180  for (deg::Relation *rel : node->inlinks) {
181  if (rel->from->type == deg::NodeType::OPERATION) {
182  num_links_pending++;
183  }
184  }
185  if (node->num_links_pending != num_links_pending) {
186  printf("Valency mismatch: %s, %u != %d\n",
187  node->identifier().c_str(),
188  node->num_links_pending,
189  num_links_pending);
190  printf("Number of inlinks: %d\n", (int)node->inlinks.size());
191  return false;
192  }
193  }
194  return true;
195 }
196 
197 /* ------------------------------------------------ */
198 
206  size_t *r_outer,
207  size_t *r_operations,
208  size_t *r_relations)
209 {
210  const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
211 
212  /* number of operations */
213  if (r_operations) {
214  /* All operations should be in this list, allowing us to count the total
215  * number of nodes. */
216  *r_operations = deg_graph->operations.size();
217  }
218 
219  /* Count number of outer nodes and/or relations between these. */
220  if (r_outer || r_relations) {
221  size_t tot_outer = 0;
222  size_t tot_rels = 0;
223 
224  for (deg::IDNode *id_node : deg_graph->id_nodes) {
225  tot_outer++;
226  for (deg::ComponentNode *comp_node : id_node->components.values()) {
227  tot_outer++;
228  for (deg::OperationNode *op_node : comp_node->operations) {
229  tot_rels += op_node->inlinks.size();
230  }
231  }
232  }
233 
234  deg::TimeSourceNode *time_source = deg_graph->find_time_source();
235  if (time_source != nullptr) {
236  tot_rels += time_source->inlinks.size();
237  }
238 
239  if (r_relations) {
240  *r_relations = tot_rels;
241  }
242  if (r_outer) {
243  *r_outer = tot_outer;
244  }
245  }
246 }
247 
248 static deg::string depsgraph_name_for_logging(struct Depsgraph *depsgraph)
249 {
250  const char *name = DEG_debug_name_get(depsgraph);
251  if (name[0] == '\0') {
252  return "";
253  }
254  return "[" + deg::string(name) + "]: ";
255 }
256 
258 {
259  fprintf(stdout, "%s", depsgraph_name_for_logging(depsgraph).c_str());
260 }
261 
263  const char *function_name,
264  const char *object_name,
265  const void *object_address)
266 {
268  return;
269  }
270  fprintf(stdout,
271  "%s%s on %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  fflush(stdout);
279 }
280 
282  const char *function_name,
283  const char *object_name,
284  const void *object_address,
285  const char *subdata_comment,
286  const char *subdata_name,
287  const void *subdata_address)
288 {
290  return;
291  }
292  fprintf(stdout,
293  "%s%s on %s %s(%p)%s %s %s %s(%p)%s\n",
295  function_name,
296  object_name,
297  deg::color_for_pointer(object_address).c_str(),
298  object_address,
299  deg::color_end().c_str(),
300  subdata_comment,
301  subdata_name,
302  deg::color_for_pointer(subdata_address).c_str(),
303  subdata_address,
304  deg::color_end().c_str());
305  fflush(stdout);
306 }
307 
309  const char *function_name,
310  const char *object_name,
311  const void *object_address,
312  const char *subdata_comment,
313  const char *subdata_name,
314  const void *subdata_address,
315  const int subdata_index)
316 {
318  return;
319  }
320  fprintf(stdout,
321  "%s%s on %s %s(%p)%s %s %s[%d] %s(%p)%s\n",
323  function_name,
324  object_name,
325  deg::color_for_pointer(object_address).c_str(),
326  object_address,
327  deg::color_end().c_str(),
328  subdata_comment,
329  subdata_name,
330  subdata_index,
331  deg::color_for_pointer(subdata_address).c_str(),
332  subdata_address,
333  deg::color_end().c_str());
334  fflush(stdout);
335 }
336 
338  const char *function_name,
339  const char *object_name,
340  const void *object_address,
341  const char *parent_comment,
342  const char *parent_name,
343  const void *parent_address)
344 {
346  return;
347  }
348  fprintf(stdout,
349  "%s%s on %s %s(%p) [%s] %s %s %s(%p)%s\n",
351  function_name,
352  object_name,
353  deg::color_for_pointer(object_address).c_str(),
354  object_address,
355  deg::color_end().c_str(),
356  parent_comment,
357  parent_name,
358  deg::color_for_pointer(parent_address).c_str(),
359  parent_address,
360  deg::color_end().c_str());
361  fflush(stdout);
362 }
363 
365  const char *function_name,
366  const char *object_name,
367  const void *object_address,
368  float time)
369 {
371  return;
372  }
373  fprintf(stdout,
374  "%s%s on %s %s(%p)%s at time %f\n",
376  function_name,
377  object_name,
378  deg::color_for_pointer(object_address).c_str(),
379  object_address,
380  deg::color_end().c_str(),
381  time);
382  fflush(stdout);
383 }
@ G_DEBUG_DEPSGRAPH_EVAL
Definition: BKE_global.h:142
#define BLI_assert(a)
Definition: BLI_assert.h:58
Depsgraph * DEG_graph_new(struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer, eEvaluationMode mode)
Definition: depsgraph.cc:281
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
void DEG_graph_free(Depsgraph *graph)
Definition: depsgraph.cc:314
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:662
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:80
string color_end()
Definition: deg_debug.cc:92
Definition: BKE_main.h:116
TimeSourceNode * find_time_source() const
Definition: depsgraph.cc:102
OperationNodes operations
Definition: depsgraph.h:126
DepsgraphDebug debug
Definition: depsgraph.h:154
IDDepsNodes id_nodes
Definition: depsgraph.h:103
Relations inlinks
Definition: deg_node.h:175
Relations outlinks
Definition: deg_node.h:176