Blender  V2.93
depsgraph.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) 2013 Blender Foundation.
17  * All rights reserved.
18  */
19 
26 #include "intern/depsgraph.h" /* own include */
27 
28 #include <algorithm>
29 #include <cstring>
30 
31 #include "MEM_guardedalloc.h"
32 
33 #include "BLI_console.h"
34 #include "BLI_hash.h"
35 #include "BLI_utildefines.h"
36 
37 #include "BKE_global.h"
38 #include "BKE_idtype.h"
39 #include "BKE_scene.h"
40 
41 #include "DEG_depsgraph.h"
42 #include "DEG_depsgraph_debug.h"
43 
48 
50 
51 #include "intern/node/deg_node.h"
57 
58 namespace deg = blender::deg;
59 
60 namespace blender::deg {
61 
63  : time_source(nullptr),
64  need_update(true),
65  bmain(bmain),
66  scene(scene),
67  view_layer(view_layer),
68  mode(mode),
69  ctime(BKE_scene_frame_get(scene)),
70  scene_cow(nullptr),
71  is_active(false),
72  is_evaluating(false),
73  is_render_pipeline_depsgraph(false),
74  use_editors_update(false)
75 {
77  memset(id_type_updated, 0, sizeof(id_type_updated));
78  memset(id_type_exist, 0, sizeof(id_type_exist));
79  memset(physics_relations, 0, sizeof(physics_relations));
80 
82 }
83 
85 {
87  delete time_source;
89 }
90 
91 /* Node Management ---------------------------- */
92 
94 {
95  if (time_source == nullptr) {
97  time_source = (TimeSourceNode *)factory->create_node(nullptr, "", "Time Source");
98  }
99  return time_source;
100 }
101 
103 {
104  return time_source;
105 }
106 
108 {
110 }
111 
113 {
114  return id_hash.lookup_default(id, nullptr);
115 }
116 
117 IDNode *Depsgraph::add_id_node(ID *id, ID *id_cow_hint)
118 {
120  IDNode *id_node = find_id_node(id);
121  if (!id_node) {
123  id_node = (IDNode *)factory->create_node(id, "", id->name);
124  id_node->init_copy_on_write(id_cow_hint);
125  /* Register node in ID hash.
126  *
127  * NOTE: We address ID nodes by the original ID pointer they are
128  * referencing to. */
129  id_hash.add_new(id, id_node);
131 
133  }
134  return id_node;
135 }
136 
137 template<typename FilterFunc>
138 static void clear_id_nodes_conditional(Depsgraph::IDDepsNodes *id_nodes, const FilterFunc &filter)
139 {
140  for (IDNode *id_node : *id_nodes) {
141  if (id_node->id_cow == nullptr) {
142  /* This means builder "stole" ownership of the copy-on-written
143  * datablock for her own dirty needs. */
144  continue;
145  }
146  if (id_node->id_cow == id_node->id_orig) {
147  /* Copy-on-write version is not needed for this ID type.
148  *
149  * NOTE: Is important to not de-reference the original datablock here because it might be
150  * freed already (happens during main database free when some IDs are freed prior to a
151  * scene). */
152  continue;
153  }
155  continue;
156  }
157  const ID_Type id_type = GS(id_node->id_cow->name);
158  if (filter(id_type)) {
159  id_node->destroy();
160  }
161  }
162 }
163 
165 {
166  /* Free memory used by ID nodes. */
167 
168  /* Stupid workaround to ensure we free IDs in a proper order. */
169  clear_id_nodes_conditional(&id_nodes, [](ID_Type id_type) { return id_type == ID_SCE; });
170  clear_id_nodes_conditional(&id_nodes, [](ID_Type id_type) { return id_type != ID_PA; });
171 
172  for (IDNode *id_node : id_nodes) {
173  delete id_node;
174  }
175  /* Clear containers. */
176  id_hash.clear();
177  id_nodes.clear();
178  /* Clear physics relation caches. */
180 }
181 
182 /* Add new relation between two nodes */
183 Relation *Depsgraph::add_new_relation(Node *from, Node *to, const char *description, int flags)
184 {
185  Relation *rel = nullptr;
186  if (flags & RELATION_CHECK_BEFORE_ADD) {
187  rel = check_nodes_connected(from, to, description);
188  }
189  if (rel != nullptr) {
190  rel->flag |= flags;
191  return rel;
192  }
193 
194 #ifndef NDEBUG
195  if (from->type == NodeType::OPERATION && to->type == NodeType::OPERATION) {
196  OperationNode *operation_from = static_cast<OperationNode *>(from);
197  OperationNode *operation_to = static_cast<OperationNode *>(to);
198  BLI_assert(operation_to->owner->type != NodeType::COPY_ON_WRITE ||
199  operation_from->owner->type == NodeType::COPY_ON_WRITE);
200  }
201 #endif
202 
203  /* Create new relation, and add it to the graph. */
204  rel = new Relation(from, to, description);
205  rel->flag |= flags;
206  return rel;
207 }
208 
210  const Node *to,
211  const char *description)
212 {
213  for (Relation *rel : from->outlinks) {
214  BLI_assert(rel->from == from);
215  if (rel->to != to) {
216  continue;
217  }
218  if (description != nullptr && !STREQ(rel->name, description)) {
219  continue;
220  }
221  return rel;
222  }
223  return nullptr;
224 }
225 
226 /* Low level tagging -------------------------------------- */
227 
228 /* Tag a specific node as needing updates. */
230 {
231  /* Sanity check. */
232  if (node == nullptr) {
233  return;
234  }
235  /* Add to graph-level set of directly modified nodes to start searching
236  * from.
237  * NOTE: this is necessary since we have several thousand nodes to play
238  * with. */
239  entry_tags.add(node);
240 }
241 
243 {
244  clear_id_nodes();
245  delete time_source;
246  time_source = nullptr;
247 }
248 
249 ID *Depsgraph::get_cow_id(const ID *id_orig) const
250 {
251  IDNode *id_node = find_id_node(id_orig);
252  if (id_node == nullptr) {
253  /* This function is used from places where we expect ID to be either
254  * already a copy-on-write version or have a corresponding copy-on-write
255  * version.
256  *
257  * We try to enforce that in debug builds, for release we play a bit
258  * safer game here. */
259  if ((id_orig->tag & LIB_TAG_COPIED_ON_WRITE) == 0) {
260  /* TODO(sergey): This is nice sanity check to have, but it fails
261  * in following situations:
262  *
263  * - Material has link to texture, which is not needed by new
264  * shading system and hence can be ignored at construction.
265  * - Object or mesh has material at a slot which is not used (for
266  * example, object has material slot by materials are set to
267  * object data). */
268  // BLI_assert(!"Request for non-existing copy-on-write ID");
269  }
270  return (ID *)id_orig;
271  }
272  return id_node->id_cow;
273 }
274 
275 } // namespace blender::deg
276 
277 /* **************** */
278 /* Public Graph API */
279 
280 /* Initialize a new Depsgraph */
282 {
283  deg::Depsgraph *deg_depsgraph = new deg::Depsgraph(bmain, scene, view_layer, mode);
284  deg::register_graph(deg_depsgraph);
285  return reinterpret_cast<Depsgraph *>(deg_depsgraph);
286 }
287 
288 /* Replace the "owner" pointers (currently Main/Scene/ViewLayer) of this depsgraph.
289  * Used for:
290  * - Undo steps when we do want to re-use the old depsgraph data as much as possible.
291  * - Rendering where we want to re-use objects between different view layers. */
293  Main *bmain,
294  Scene *scene,
295  ViewLayer *view_layer)
296 {
297  deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
298 
299  const bool do_update_register = deg_graph->bmain != bmain;
300  if (do_update_register && deg_graph->bmain != nullptr) {
301  deg::unregister_graph(deg_graph);
302  }
303 
304  deg_graph->bmain = bmain;
305  deg_graph->scene = scene;
306  deg_graph->view_layer = view_layer;
307 
308  if (do_update_register) {
309  deg::register_graph(deg_graph);
310  }
311 }
312 
313 /* Free graph's contents and graph itself */
315 {
316  if (graph == nullptr) {
317  return;
318  }
319  using deg::Depsgraph;
320  deg::Depsgraph *deg_depsgraph = reinterpret_cast<deg::Depsgraph *>(graph);
321  deg::unregister_graph(deg_depsgraph);
322  delete deg_depsgraph;
323 }
324 
326 {
327  const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(depsgraph);
328  return deg_graph->is_evaluating;
329 }
330 
331 bool DEG_is_active(const struct Depsgraph *depsgraph)
332 {
333  if (depsgraph == nullptr) {
334  /* Happens for such cases as work object in what_does_obaction(),
335  * and sine render pipeline parts. Shouldn't really be accepting
336  * nullptr depsgraph, but is quite hard to get proper one in those
337  * cases. */
338  return false;
339  }
340  const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(depsgraph);
341  return deg_graph->is_active;
342 }
343 
345 {
346  deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
347  deg_graph->is_active = true;
348  /* TODO(sergey): Copy data from evaluated state to original. */
349 }
350 
352 {
353  deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
354  deg_graph->is_active = false;
355 }
int BKE_idtype_idcode_to_index(const short idcode)
Definition: idtype.c:345
float BKE_scene_frame_get(const struct Scene *scene)
#define BLI_assert(a)
Definition: BLI_assert.h:58
Set of utility functions and constants to work with consoles.
void BLI_spin_init(SpinLock *spin)
Definition: threads.cc:447
void BLI_spin_end(SpinLock *spin)
Definition: threads.cc:495
#define STREQ(a, b)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
eEvaluationMode
Definition: DEG_depsgraph.h:60
@ LIB_TAG_COPIED_ON_WRITE
Definition: DNA_ID.h:565
ID_Type
Definition: DNA_ID_enums.h:56
@ ID_SCE
Definition: DNA_ID_enums.h:57
@ ID_PA
Definition: DNA_ID_enums.h:82
Read Guarded memory(de)allocation.
void append(const T &value)
Definition: BLI_vector.hh:438
OperationNode * node
Depsgraph * graph
StackEntry * from
const IDNode * id_node
Scene scene
const Depsgraph * depsgraph
void DEG_graph_replace_owners(struct Depsgraph *depsgraph, Main *bmain, Scene *scene, ViewLayer *view_layer)
Definition: depsgraph.cc:292
bool DEG_is_active(const struct Depsgraph *depsgraph)
Definition: depsgraph.cc:331
void DEG_make_active(struct Depsgraph *depsgraph)
Definition: depsgraph.cc:344
Depsgraph * DEG_graph_new(Main *bmain, Scene *scene, ViewLayer *view_layer, eEvaluationMode mode)
Definition: depsgraph.cc:281
void DEG_graph_free(Depsgraph *graph)
Definition: depsgraph.cc:314
void DEG_make_inactive(struct Depsgraph *depsgraph)
Definition: depsgraph.cc:351
bool DEG_is_evaluating(const struct Depsgraph *depsgraph)
Definition: depsgraph.cc:325
DO_INLINE void filter(lfVector *V, fmatrix3x3 *S)
#define GS(x)
Definition: iris.c:241
static void clear_id_nodes_conditional(Depsgraph::IDDepsNodes *id_nodes, const FilterFunc &filter)
Definition: depsgraph.cc:138
void clear_physics_relations(Depsgraph *graph)
DepsNodeFactory * type_get_factory(const NodeType type)
bool deg_copy_on_write_is_expanded(const ID *id_cow)
void unregister_graph(Depsgraph *depsgraph)
void register_graph(Depsgraph *depsgraph)
Definition: DNA_ID.h:273
int tag
Definition: DNA_ID.h:292
char name[66]
Definition: DNA_ID.h:283
Definition: BKE_main.h:116
virtual Node * create_node(const ID *id, const char *subdata, const char *name) const =0
ID * get_cow_id(const ID *id_orig) const
Definition: depsgraph.cc:249
Map< const ID *, ListBase * > * physics_relations[DEG_PHYSICS_RELATIONS_NUM]
Definition: depsgraph.h:169
IDNode * find_id_node(const ID *id) const
Definition: depsgraph.cc:112
char id_type_updated[INDEX_ID_MAX]
Definition: depsgraph.h:112
TimeSourceNode * find_time_source() const
Definition: depsgraph.cc:102
IDNode * add_id_node(ID *id, ID *id_cow_hint=nullptr)
Definition: depsgraph.cc:117
Depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer, eEvaluationMode mode)
Definition: depsgraph.cc:62
ViewLayer * view_layer
Definition: depsgraph.h:135
Relation * add_new_relation(Node *from, Node *to, const char *description, int flags=0)
Definition: depsgraph.cc:183
char id_type_exist[INDEX_ID_MAX]
Definition: depsgraph.h:115
Map< const ID *, IDNode * > id_hash
Definition: depsgraph.h:98
Vector< IDNode * > IDDepsNodes
Definition: depsgraph.h:62
Relation * check_nodes_connected(const Node *from, const Node *to, const char *description)
Definition: depsgraph.cc:209
TimeSourceNode * add_time_source()
Definition: depsgraph.cc:93
Set< OperationNode * > entry_tags
Definition: depsgraph.h:120
TimeSourceNode * time_source
Definition: depsgraph.h:106
IDDepsNodes id_nodes
Definition: depsgraph.h:103
void add_entry_tag(OperationNode *node)
Definition: depsgraph.cc:229
virtual void tag_update(Depsgraph *graph, eUpdateSource source) override