Rename any instance of scene layer or render layer in code with view layer
[blender.git] / source / blender / depsgraph / intern / depsgraph_debug.cc
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2014 Blender Foundation.
19  * All rights reserved.
20  *
21  * Original Author: Lukas Toenne
22  * Contributor(s): None Yet
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file blender/depsgraph/intern/depsgraph_debug.cc
28  *  \ingroup depsgraph
29  *
30  * Implementation of tools for debugging the depsgraph
31  */
32
33 #include "BLI_utildefines.h"
34 #include "BLI_ghash.h"
35
36 extern "C" {
37 #include "DNA_scene_types.h"
38 }  /* extern "C" */
39
40 #include "DEG_depsgraph.h"
41 #include "DEG_depsgraph_debug.h"
42 #include "DEG_depsgraph_build.h"
43
44 #include "intern/depsgraph_intern.h"
45 #include "util/deg_util_foreach.h"
46
47 bool DEG_debug_compare(const struct Depsgraph *graph1,
48                        const struct Depsgraph *graph2)
49 {
50         BLI_assert(graph1 != NULL);
51         BLI_assert(graph2 != NULL);
52         const DEG::Depsgraph *deg_graph1 = reinterpret_cast<const DEG::Depsgraph *>(graph1);
53         const DEG::Depsgraph *deg_graph2 = reinterpret_cast<const DEG::Depsgraph *>(graph2);
54         if (deg_graph1->operations.size() != deg_graph2->operations.size()) {
55                 return false;
56         }
57         /* TODO(sergey): Currently we only do real stupid check,
58          * which is fast but which isn't 100% reliable.
59          *
60          * Would be cool to make it more robust, but it's good enough
61          * for now. Also, proper graph check is actually NP-complex
62          * problem..
63          */
64         return true;
65 }
66
67 bool DEG_debug_graph_relations_validate(Depsgraph *graph,
68                                         Main *bmain,
69                                         Scene *scene,
70                                         ViewLayer *view_layer)
71 {
72         Depsgraph *temp_depsgraph = DEG_graph_new();
73         bool valid = true;
74         DEG_graph_build_from_view_layer(temp_depsgraph, bmain, scene, view_layer);
75         if (!DEG_debug_compare(temp_depsgraph, graph)) {
76                 fprintf(stderr, "ERROR! Depsgraph wasn't tagged for update when it should have!\n");
77                 BLI_assert(!"This should not happen!");
78                 valid = false;
79         }
80         DEG_graph_free(temp_depsgraph);
81         return valid;
82 }
83
84 bool DEG_debug_consistency_check(Depsgraph *graph)
85 {
86         const DEG::Depsgraph *deg_graph = reinterpret_cast<const DEG::Depsgraph *>(graph);
87
88         /* Validate links exists in both directions. */
89         foreach (DEG::OperationDepsNode *node, deg_graph->operations) {
90                 foreach (DEG::DepsRelation *rel, node->outlinks) {
91                         int counter1 = 0;
92                         foreach (DEG::DepsRelation *tmp_rel, node->outlinks) {
93                                 if (tmp_rel == rel) {
94                                         ++counter1;
95                                 }
96                         }
97
98                         int counter2 = 0;
99                         foreach (DEG::DepsRelation *tmp_rel, rel->to->inlinks) {
100                                 if (tmp_rel == rel) {
101                                         ++counter2;
102                                 }
103                         }
104
105                         if (counter1 != counter2) {
106                                 printf("Relation exists in outgoing direction but not in incoming (%d vs. %d).\n",
107                                        counter1, counter2);
108                                 return false;
109                         }
110                 }
111         }
112
113         foreach (DEG::OperationDepsNode *node, deg_graph->operations) {
114                 foreach (DEG::DepsRelation *rel, node->inlinks) {
115                         int counter1 = 0;
116                         foreach (DEG::DepsRelation *tmp_rel, node->inlinks) {
117                                 if (tmp_rel == rel) {
118                                         ++counter1;
119                                 }
120                         }
121
122                         int counter2 = 0;
123                         foreach (DEG::DepsRelation *tmp_rel, rel->from->outlinks) {
124                                 if (tmp_rel == rel) {
125                                         ++counter2;
126                                 }
127                         }
128
129                         if (counter1 != counter2) {
130                                 printf("Relation exists in incoming direction but not in outcoming (%d vs. %d).\n",
131                                        counter1, counter2);
132                         }
133                 }
134         }
135
136         /* Validate node valency calculated in both directions. */
137         foreach (DEG::OperationDepsNode *node, deg_graph->operations) {
138                 node->num_links_pending = 0;
139                 node->done = 0;
140         }
141
142         foreach (DEG::OperationDepsNode *node, deg_graph->operations) {
143                 if (node->done) {
144                         printf("Node %s is twice in the operations!\n",
145                                node->identifier().c_str());
146                         return false;
147                 }
148                 foreach (DEG::DepsRelation *rel, node->outlinks) {
149                         if (rel->to->type == DEG::DEG_NODE_TYPE_OPERATION) {
150                                 DEG::OperationDepsNode *to = (DEG::OperationDepsNode *)rel->to;
151                                 BLI_assert(to->num_links_pending < to->inlinks.size());
152                                 ++to->num_links_pending;
153                         }
154                 }
155                 node->done = 1;
156         }
157
158         foreach (DEG::OperationDepsNode *node, deg_graph->operations) {
159                 int num_links_pending = 0;
160                 foreach (DEG::DepsRelation *rel, node->inlinks) {
161                         if (rel->from->type == DEG::DEG_NODE_TYPE_OPERATION) {
162                                 ++num_links_pending;
163                         }
164                 }
165                 if (node->num_links_pending != num_links_pending) {
166                         printf("Valency mismatch: %s, %u != %d\n",
167                                node->identifier().c_str(),
168                                node->num_links_pending, num_links_pending);
169                         printf("Number of inlinks: %d\n", (int)node->inlinks.size());
170                         return false;
171                 }
172         }
173         return true;
174 }
175
176 /* ------------------------------------------------ */
177
178 /**
179  * Obtain simple statistics about the complexity of the depsgraph
180  * \param[out] r_outer       The number of outer nodes in the graph
181  * \param[out] r_operations  The number of operation nodes in the graph
182  * \param[out] r_relations   The number of relations between (executable) nodes in the graph
183  */
184 void DEG_stats_simple(const Depsgraph *graph, size_t *r_outer,
185                       size_t *r_operations, size_t *r_relations)
186 {
187         const DEG::Depsgraph *deg_graph = reinterpret_cast<const DEG::Depsgraph *>(graph);
188
189         /* number of operations */
190         if (r_operations) {
191                 /* All operations should be in this list, allowing us to count the total
192                  * number of nodes.
193                  */
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                 foreach (DEG::IDDepsNode *id_node, deg_graph->id_nodes) {
203                         tot_outer++;
204                         GHASH_FOREACH_BEGIN(DEG::ComponentDepsNode *, comp_node, id_node->components)
205                         {
206                                 tot_outer++;
207                                 foreach (DEG::OperationDepsNode *op_node, comp_node->operations) {
208                                         tot_rels += op_node->inlinks.size();
209                                 }
210                         }
211                         GHASH_FOREACH_END();
212                 }
213
214                 DEG::TimeSourceDepsNode *time_source = deg_graph->find_time_source();
215                 if (time_source != NULL) {
216                         tot_rels += time_source->inlinks.size();
217                 }
218
219                 if (r_relations) *r_relations = tot_rels;
220                 if (r_outer)     *r_outer     = tot_outer;
221         }
222 }