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