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
20 /** \file
21 * \ingroup depsgraph
22 *
23 * Core routines for how the Depsgraph works.
24 */
25
26 #include "intern/depsgraph_tag.h"
27
28 #include <cstring> /* required for memset */
29 #include <queue>
30 #include <stdio.h>
31
32 #include "BLI_math_bits.h"
33 #include "BLI_task.h"
34 #include "BLI_utildefines.h"
35
36 #include "DNA_anim_types.h"
37 #include "DNA_curve_types.h"
38 #include "DNA_key_types.h"
39 #include "DNA_lattice_types.h"
40 #include "DNA_mesh_types.h"
41 #include "DNA_object_types.h"
42 #include "DNA_particle_types.h"
43 #include "DNA_screen_types.h"
44 #include "DNA_windowmanager_types.h"
45
46 #include "BKE_anim_data.h"
47 #include "BKE_global.h"
48 #include "BKE_idtype.h"
49 #include "BKE_node.h"
50 #include "BKE_scene.h"
51 #include "BKE_screen.h"
52 #include "BKE_workspace.h"
53
54 #include "DEG_depsgraph.h"
55 #include "DEG_depsgraph_debug.h"
56 #include "DEG_depsgraph_query.h"
57
58 #include "intern/builder/deg_builder.h"
59 #include "intern/depsgraph.h"
60 #include "intern/depsgraph_registry.h"
61 #include "intern/depsgraph_update.h"
62 #include "intern/eval/deg_eval_copy_on_write.h"
63 #include "intern/eval/deg_eval_flush.h"
64 #include "intern/node/deg_node.h"
65 #include "intern/node/deg_node_component.h"
66 #include "intern/node/deg_node_factory.h"
67 #include "intern/node/deg_node_id.h"
68 #include "intern/node/deg_node_operation.h"
69 #include "intern/node/deg_node_time.h"
70
71 namespace deg = blender::deg;
72
73 /* *********************** */
74 /* Update Tagging/Flushing */
75
76 namespace blender {
77 namespace deg {
78
79 namespace {
80
depsgraph_geometry_tag_to_component(const ID * id,NodeType * component_type)81 void depsgraph_geometry_tag_to_component(const ID *id, NodeType *component_type)
82 {
83 const NodeType result = geometry_tag_to_component(id);
84 if (result != NodeType::UNDEFINED) {
85 *component_type = result;
86 }
87 }
88
is_selectable_data_id_type(const ID_Type id_type)89 bool is_selectable_data_id_type(const ID_Type id_type)
90 {
91 return ELEM(id_type, ID_ME, ID_CU, ID_MB, ID_LT, ID_GD, ID_HA, ID_PT, ID_VO);
92 }
93
depsgraph_select_tag_to_component_opcode(const ID * id,NodeType * component_type,OperationCode * operation_code)94 void depsgraph_select_tag_to_component_opcode(const ID *id,
95 NodeType *component_type,
96 OperationCode *operation_code)
97 {
98 const ID_Type id_type = GS(id->name);
99 if (id_type == ID_SCE) {
100 /* We need to flush base flags to all objects in a scene since we
101 * don't know which ones changed. However, we don't want to update
102 * the whole scene, so pick up some operation which will do as less
103 * as possible.
104 *
105 * TODO(sergey): We can introduce explicit exit operation which
106 * does nothing and which is only used to cascade flush down the
107 * road. */
108 *component_type = NodeType::LAYER_COLLECTIONS;
109 *operation_code = OperationCode::VIEW_LAYER_EVAL;
110 }
111 else if (id_type == ID_OB) {
112 *component_type = NodeType::OBJECT_FROM_LAYER;
113 *operation_code = OperationCode::OBJECT_FROM_LAYER_ENTRY;
114 }
115 else if (id_type == ID_MC) {
116 *component_type = NodeType::BATCH_CACHE;
117 *operation_code = OperationCode::MOVIECLIP_SELECT_UPDATE;
118 }
119 else if (is_selectable_data_id_type(id_type)) {
120 *component_type = NodeType::BATCH_CACHE;
121 *operation_code = OperationCode::GEOMETRY_SELECT_UPDATE;
122 }
123 else {
124 *component_type = NodeType::COPY_ON_WRITE;
125 *operation_code = OperationCode::COPY_ON_WRITE;
126 }
127 }
128
depsgraph_base_flags_tag_to_component_opcode(const ID * id,NodeType * component_type,OperationCode * operation_code)129 void depsgraph_base_flags_tag_to_component_opcode(const ID *id,
130 NodeType *component_type,
131 OperationCode *operation_code)
132 {
133 const ID_Type id_type = GS(id->name);
134 if (id_type == ID_SCE) {
135 *component_type = NodeType::LAYER_COLLECTIONS;
136 *operation_code = OperationCode::VIEW_LAYER_EVAL;
137 }
138 else if (id_type == ID_OB) {
139 *component_type = NodeType::OBJECT_FROM_LAYER;
140 *operation_code = OperationCode::OBJECT_BASE_FLAGS;
141 }
142 }
143
psysTagToOperationCode(IDRecalcFlag tag)144 OperationCode psysTagToOperationCode(IDRecalcFlag tag)
145 {
146 if (tag == ID_RECALC_PSYS_RESET) {
147 return OperationCode::PARTICLE_SETTINGS_RESET;
148 }
149 return OperationCode::OPERATION;
150 }
151
depsgraph_tag_to_component_opcode(const ID * id,IDRecalcFlag tag,NodeType * component_type,OperationCode * operation_code)152 void depsgraph_tag_to_component_opcode(const ID *id,
153 IDRecalcFlag tag,
154 NodeType *component_type,
155 OperationCode *operation_code)
156 {
157 const ID_Type id_type = GS(id->name);
158 *component_type = NodeType::UNDEFINED;
159 *operation_code = OperationCode::OPERATION;
160 /* Special case for now, in the future we should get rid of this. */
161 if (tag == 0) {
162 *component_type = NodeType::ID_REF;
163 *operation_code = OperationCode::OPERATION;
164 return;
165 }
166 switch (tag) {
167 case ID_RECALC_TRANSFORM:
168 *component_type = NodeType::TRANSFORM;
169 break;
170 case ID_RECALC_GEOMETRY:
171 depsgraph_geometry_tag_to_component(id, component_type);
172 break;
173 case ID_RECALC_ANIMATION:
174 *component_type = NodeType::ANIMATION;
175 break;
176 case ID_RECALC_PSYS_REDO:
177 case ID_RECALC_PSYS_RESET:
178 case ID_RECALC_PSYS_CHILD:
179 case ID_RECALC_PSYS_PHYS:
180 if (id_type == ID_PA) {
181 /* NOTES:
182 * - For particle settings node we need to use different
183 * component. Will be nice to get this unified with object,
184 * but we can survive for now with single exception here.
185 * Particles needs reconsideration anyway, */
186 *component_type = NodeType::PARTICLE_SETTINGS;
187 *operation_code = psysTagToOperationCode(tag);
188 }
189 else {
190 *component_type = NodeType::PARTICLE_SYSTEM;
191 }
192 break;
193 case ID_RECALC_COPY_ON_WRITE:
194 *component_type = NodeType::COPY_ON_WRITE;
195 break;
196 case ID_RECALC_SHADING:
197 if (id_type == ID_NT) {
198 *component_type = NodeType::SHADING_PARAMETERS;
199 }
200 else {
201 *component_type = NodeType::SHADING;
202 }
203 break;
204 case ID_RECALC_SELECT:
205 depsgraph_select_tag_to_component_opcode(id, component_type, operation_code);
206 break;
207 case ID_RECALC_BASE_FLAGS:
208 depsgraph_base_flags_tag_to_component_opcode(id, component_type, operation_code);
209 break;
210 case ID_RECALC_POINT_CACHE:
211 *component_type = NodeType::POINT_CACHE;
212 break;
213 case ID_RECALC_EDITORS:
214 /* There is no such node in depsgraph, this tag is to be handled
215 * separately. */
216 break;
217 case ID_RECALC_SEQUENCER_STRIPS:
218 *component_type = NodeType::SEQUENCER;
219 break;
220 case ID_RECALC_AUDIO_SEEK:
221 case ID_RECALC_AUDIO_FPS:
222 case ID_RECALC_AUDIO_VOLUME:
223 case ID_RECALC_AUDIO_MUTE:
224 case ID_RECALC_AUDIO_LISTENER:
225 case ID_RECALC_AUDIO:
226 *component_type = NodeType::AUDIO;
227 break;
228 case ID_RECALC_PARAMETERS:
229 *component_type = NodeType::PARAMETERS;
230 break;
231 case ID_RECALC_SOURCE:
232 *component_type = NodeType::PARAMETERS;
233 break;
234 case ID_RECALC_ALL:
235 case ID_RECALC_PSYS_ALL:
236 BLI_assert(!"Should not happen");
237 break;
238 case ID_RECALC_TAG_FOR_UNDO:
239 break; /* Must be ignored by depsgraph. */
240 }
241 }
242
id_tag_update_ntree_special(Main * bmain,Depsgraph * graph,ID * id,int flag,eUpdateSource update_source)243 void id_tag_update_ntree_special(
244 Main *bmain, Depsgraph *graph, ID *id, int flag, eUpdateSource update_source)
245 {
246 bNodeTree *ntree = ntreeFromID(id);
247 if (ntree == nullptr) {
248 return;
249 }
250 graph_id_tag_update(bmain, graph, &ntree->id, flag, update_source);
251 }
252
depsgraph_update_editors_tag(Main * bmain,Depsgraph * graph,ID * id)253 void depsgraph_update_editors_tag(Main *bmain, Depsgraph *graph, ID *id)
254 {
255 /* NOTE: We handle this immediately, without delaying anything, to be
256 * sure we don't cause threading issues with OpenGL. */
257 /* TODO(sergey): Make sure this works for CoW-ed datablocks as well. */
258 DEGEditorUpdateContext update_ctx = {nullptr};
259 update_ctx.bmain = bmain;
260 update_ctx.depsgraph = (::Depsgraph *)graph;
261 update_ctx.scene = graph->scene;
262 update_ctx.view_layer = graph->view_layer;
263 deg_editors_id_update(&update_ctx, id);
264 }
265
depsgraph_id_tag_copy_on_write(Depsgraph * graph,IDNode * id_node,eUpdateSource update_source)266 void depsgraph_id_tag_copy_on_write(Depsgraph *graph, IDNode *id_node, eUpdateSource update_source)
267 {
268 ComponentNode *cow_comp = id_node->find_component(NodeType::COPY_ON_WRITE);
269 cow_comp->tag_update(graph, update_source);
270 }
271
depsgraph_tag_component(Depsgraph * graph,IDNode * id_node,NodeType component_type,OperationCode operation_code,eUpdateSource update_source)272 void depsgraph_tag_component(Depsgraph *graph,
273 IDNode *id_node,
274 NodeType component_type,
275 OperationCode operation_code,
276 eUpdateSource update_source)
277 {
278 ComponentNode *component_node = id_node->find_component(component_type);
279 /* NOTE: Animation component might not be existing yet (which happens when adding new driver or
280 * adding a new keyframe), so the required copy-on-write tag needs to be taken care explicitly
281 * here. */
282 if (component_node == nullptr) {
283 if (component_type == NodeType::ANIMATION) {
284 depsgraph_id_tag_copy_on_write(graph, id_node, update_source);
285 }
286 return;
287 }
288 if (operation_code == OperationCode::OPERATION) {
289 component_node->tag_update(graph, update_source);
290 }
291 else {
292 OperationNode *operation_node = component_node->find_operation(operation_code);
293 if (operation_node != nullptr) {
294 operation_node->tag_update(graph, update_source);
295 }
296 }
297 /* If component depends on copy-on-write, tag it as well. */
298 if (component_node->need_tag_cow_before_update()) {
299 depsgraph_id_tag_copy_on_write(graph, id_node, update_source);
300 }
301 }
302
303 /* This is a tag compatibility with legacy code.
304 *
305 * Mainly, old code was tagging object with ID_RECALC_GEOMETRY tag to inform
306 * that object's data datablock changed. Now API expects that ID is given
307 * explicitly, but not all areas are aware of this yet. */
deg_graph_id_tag_legacy_compat(Main * bmain,Depsgraph * depsgraph,ID * id,IDRecalcFlag tag,eUpdateSource update_source)308 void deg_graph_id_tag_legacy_compat(
309 Main *bmain, Depsgraph *depsgraph, ID *id, IDRecalcFlag tag, eUpdateSource update_source)
310 {
311 if (tag == ID_RECALC_GEOMETRY || tag == 0) {
312 switch (GS(id->name)) {
313 case ID_OB: {
314 Object *object = (Object *)id;
315 ID *data_id = (ID *)object->data;
316 if (data_id != nullptr) {
317 graph_id_tag_update(bmain, depsgraph, data_id, 0, update_source);
318 }
319 break;
320 }
321 /* TODO(sergey): Shape keys are annoying, maybe we should find a
322 * way to chain geometry evaluation to them, so we don't need extra
323 * tagging here. */
324 case ID_ME: {
325 Mesh *mesh = (Mesh *)id;
326 if (mesh->key != nullptr) {
327 ID *key_id = &mesh->key->id;
328 if (key_id != nullptr) {
329 graph_id_tag_update(bmain, depsgraph, key_id, 0, update_source);
330 }
331 }
332 break;
333 }
334 case ID_LT: {
335 Lattice *lattice = (Lattice *)id;
336 if (lattice->key != nullptr) {
337 ID *key_id = &lattice->key->id;
338 if (key_id != nullptr) {
339 graph_id_tag_update(bmain, depsgraph, key_id, 0, update_source);
340 }
341 }
342 break;
343 }
344 case ID_CU: {
345 Curve *curve = (Curve *)id;
346 if (curve->key != nullptr) {
347 ID *key_id = &curve->key->id;
348 if (key_id != nullptr) {
349 graph_id_tag_update(bmain, depsgraph, key_id, 0, update_source);
350 }
351 }
352 break;
353 }
354 default:
355 break;
356 }
357 }
358 }
359
graph_id_tag_update_single_flag(Main * bmain,Depsgraph * graph,ID * id,IDNode * id_node,IDRecalcFlag tag,eUpdateSource update_source)360 void graph_id_tag_update_single_flag(Main *bmain,
361 Depsgraph *graph,
362 ID *id,
363 IDNode *id_node,
364 IDRecalcFlag tag,
365 eUpdateSource update_source)
366 {
367 if (tag == ID_RECALC_EDITORS) {
368 if (graph != nullptr && graph->is_active) {
369 depsgraph_update_editors_tag(bmain, graph, id);
370 }
371 return;
372 }
373 /* Get description of what is to be tagged. */
374 NodeType component_type;
375 OperationCode operation_code;
376 depsgraph_tag_to_component_opcode(id, tag, &component_type, &operation_code);
377 /* Check whether we've got something to tag. */
378 if (component_type == NodeType::UNDEFINED) {
379 /* Given ID does not support tag. */
380 /* TODO(sergey): Shall we raise some panic here? */
381 return;
382 }
383 /* Some sanity checks before moving forward. */
384 if (id_node == nullptr) {
385 /* Happens when object is tagged for update and not yet in the
386 * dependency graph (but will be after relations update). */
387 return;
388 }
389 /* Tag ID recalc flag. */
390 DepsNodeFactory *factory = type_get_factory(component_type);
391 BLI_assert(factory != nullptr);
392 id_node->id_cow->recalc |= factory->id_recalc_tag();
393 /* Tag corresponding dependency graph operation for update. */
394 if (component_type == NodeType::ID_REF) {
395 id_node->tag_update(graph, update_source);
396 }
397 else {
398 depsgraph_tag_component(graph, id_node, component_type, operation_code, update_source);
399 }
400 /* TODO(sergey): Get rid of this once all areas are using proper data ID
401 * for tagging. */
402 deg_graph_id_tag_legacy_compat(bmain, graph, id, tag, update_source);
403 }
404
stringify_append_bit(const string & str,IDRecalcFlag tag)405 string stringify_append_bit(const string &str, IDRecalcFlag tag)
406 {
407 const char *tag_name = DEG_update_tag_as_string(tag);
408 if (tag_name == nullptr) {
409 return str;
410 }
411 string result = str;
412 if (!result.empty()) {
413 result += ", ";
414 }
415 result += tag_name;
416 return result;
417 }
418
stringify_update_bitfield(int flag)419 string stringify_update_bitfield(int flag)
420 {
421 if (flag == 0) {
422 return "LEGACY_0";
423 }
424 string result;
425 int current_flag = flag;
426 /* Special cases to avoid ALL flags form being split into
427 * individual bits. */
428 if ((current_flag & ID_RECALC_PSYS_ALL) == ID_RECALC_PSYS_ALL) {
429 result = stringify_append_bit(result, ID_RECALC_PSYS_ALL);
430 }
431 /* Handle all the rest of the flags. */
432 while (current_flag != 0) {
433 IDRecalcFlag tag = (IDRecalcFlag)(1 << bitscan_forward_clear_i(¤t_flag));
434 result = stringify_append_bit(result, tag);
435 }
436 return result;
437 }
438
update_source_as_string(eUpdateSource source)439 const char *update_source_as_string(eUpdateSource source)
440 {
441 switch (source) {
442 case DEG_UPDATE_SOURCE_TIME:
443 return "TIME";
444 case DEG_UPDATE_SOURCE_USER_EDIT:
445 return "USER_EDIT";
446 case DEG_UPDATE_SOURCE_RELATIONS:
447 return "RELATIONS";
448 case DEG_UPDATE_SOURCE_VISIBILITY:
449 return "VISIBILITY";
450 }
451 BLI_assert(!"Should never happen.");
452 return "UNKNOWN";
453 }
454
deg_recalc_flags_for_legacy_zero()455 int deg_recalc_flags_for_legacy_zero()
456 {
457 return ID_RECALC_ALL &
458 ~(ID_RECALC_PSYS_ALL | ID_RECALC_ANIMATION | ID_RECALC_SOURCE | ID_RECALC_EDITORS);
459 }
460
deg_recalc_flags_effective(Depsgraph * graph,int flags)461 int deg_recalc_flags_effective(Depsgraph *graph, int flags)
462 {
463 if (graph != nullptr) {
464 if (!graph->is_active) {
465 return 0;
466 }
467 }
468 if (flags == 0) {
469 return deg_recalc_flags_for_legacy_zero();
470 }
471 return flags;
472 }
473
474 /* Special tag function which tags all components which needs to be tagged
475 * for update flag=0.
476 *
477 * TODO(sergey): This is something to be avoid in the future, make it more
478 * explicit and granular for users to tag what they really need. */
deg_graph_node_tag_zero(Main * bmain,Depsgraph * graph,IDNode * id_node,eUpdateSource update_source)479 void deg_graph_node_tag_zero(Main *bmain,
480 Depsgraph *graph,
481 IDNode *id_node,
482 eUpdateSource update_source)
483 {
484 if (id_node == nullptr) {
485 return;
486 }
487 ID *id = id_node->id_orig;
488 /* TODO(sergey): Which recalc flags to set here? */
489 id_node->id_cow->recalc |= deg_recalc_flags_for_legacy_zero();
490
491 for (ComponentNode *comp_node : id_node->components.values()) {
492 if (comp_node->type == NodeType::ANIMATION) {
493 continue;
494 }
495 comp_node->tag_update(graph, update_source);
496 }
497 deg_graph_id_tag_legacy_compat(bmain, graph, id, (IDRecalcFlag)0, update_source);
498 }
499
deg_graph_on_visible_update(Main * bmain,Depsgraph * graph,const bool do_time)500 void deg_graph_on_visible_update(Main *bmain, Depsgraph *graph, const bool do_time)
501 {
502 /* NOTE: It is possible to have this function called with `do_time=false` first and later (prior
503 * to evaluation though) with `do_time=true`. This means early output checks should be aware of
504 * this. */
505 for (deg::IDNode *id_node : graph->id_nodes) {
506 const ID_Type id_type = GS(id_node->id_orig->name);
507 if (id_type == ID_OB) {
508 Object *object_orig = reinterpret_cast<Object *>(id_node->id_orig);
509 if (object_orig->proxy != nullptr) {
510 object_orig->proxy->proxy_from = object_orig;
511 }
512 }
513
514 if (!id_node->visible_components_mask) {
515 /* ID has no components which affects anything visible.
516 * No need bother with it to tag or anything. */
517 continue;
518 }
519 int flag = 0;
520 if (!deg::deg_copy_on_write_is_expanded(id_node->id_cow)) {
521 flag |= ID_RECALC_COPY_ON_WRITE;
522 if (do_time) {
523 if (BKE_animdata_from_id(id_node->id_orig) != nullptr) {
524 flag |= ID_RECALC_ANIMATION;
525 }
526 }
527 }
528 else {
529 if (id_node->visible_components_mask == id_node->previously_visible_components_mask) {
530 /* The ID was already visible and evaluated, all the subsequent
531 * updates and tags are to be done explicitly. */
532 continue;
533 }
534 }
535 /* We only tag components which needs an update. Tagging everything is
536 * not a good idea because that might reset particles cache (or any
537 * other type of cache).
538 *
539 * TODO(sergey): Need to generalize this somehow. */
540 if (id_type == ID_OB) {
541 flag |= ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY;
542 }
543 graph_id_tag_update(bmain, graph, id_node->id_orig, flag, DEG_UPDATE_SOURCE_VISIBILITY);
544 if (id_type == ID_SCE) {
545 /* Make sure collection properties are up to date. */
546 id_node->tag_update(graph, DEG_UPDATE_SOURCE_VISIBILITY);
547 }
548 /* Now when ID is updated to the new visibility state, prevent it from
549 * being re-tagged again. Simplest way to do so is to pretend that it
550 * was already updated by the "previous" dependency graph.
551 *
552 * NOTE: Even if the on_visible_update() is called from the state when
553 * dependency graph is tagged for relations update, it will be fine:
554 * since dependency graph builder re-schedules entry tags, all the
555 * tags we request from here will be applied in the updated state of
556 * dependency graph. */
557 id_node->previously_visible_components_mask = id_node->visible_components_mask;
558 }
559 }
560
561 } /* namespace */
562
geometry_tag_to_component(const ID * id)563 NodeType geometry_tag_to_component(const ID *id)
564 {
565 const ID_Type id_type = GS(id->name);
566 switch (id_type) {
567 case ID_OB: {
568 const Object *object = (Object *)id;
569 switch (object->type) {
570 case OB_MESH:
571 case OB_CURVE:
572 case OB_SURF:
573 case OB_FONT:
574 case OB_LATTICE:
575 case OB_MBALL:
576 case OB_GPENCIL:
577 case OB_HAIR:
578 case OB_POINTCLOUD:
579 case OB_VOLUME:
580 return NodeType::GEOMETRY;
581 case OB_ARMATURE:
582 return NodeType::EVAL_POSE;
583 /* TODO(sergey): More cases here? */
584 }
585 break;
586 }
587 case ID_ME:
588 case ID_CU:
589 case ID_LT:
590 case ID_MB:
591 case ID_HA:
592 case ID_PT:
593 case ID_VO:
594 return NodeType::GEOMETRY;
595 case ID_PA: /* Particles */
596 return NodeType::UNDEFINED;
597 case ID_LP:
598 return NodeType::PARAMETERS;
599 case ID_GD:
600 return NodeType::GEOMETRY;
601 case ID_PAL: /* Palettes */
602 return NodeType::PARAMETERS;
603 case ID_MSK:
604 return NodeType::PARAMETERS;
605 default:
606 break;
607 }
608 return NodeType::UNDEFINED;
609 }
610
id_tag_update(Main * bmain,ID * id,int flag,eUpdateSource update_source)611 void id_tag_update(Main *bmain, ID *id, int flag, eUpdateSource update_source)
612 {
613 graph_id_tag_update(bmain, nullptr, id, flag, update_source);
614 for (deg::Depsgraph *depsgraph : deg::get_all_registered_graphs(bmain)) {
615 graph_id_tag_update(bmain, depsgraph, id, flag, update_source);
616 }
617
618 /* Accumulate all tags for an ID between two undo steps, so they can be
619 * replayed for undo. */
620 id->recalc_after_undo_push |= deg_recalc_flags_effective(NULL, flag);
621 }
622
graph_id_tag_update(Main * bmain,Depsgraph * graph,ID * id,int flag,eUpdateSource update_source)623 void graph_id_tag_update(
624 Main *bmain, Depsgraph *graph, ID *id, int flag, eUpdateSource update_source)
625 {
626 const int debug_flags = (graph != nullptr) ? DEG_debug_flags_get((::Depsgraph *)graph) : G.debug;
627 if (graph != nullptr && graph->is_evaluating) {
628 if (debug_flags & G_DEBUG_DEPSGRAPH) {
629 printf("ID tagged for update during dependency graph evaluation.");
630 }
631 return;
632 }
633 if (debug_flags & G_DEBUG_DEPSGRAPH_TAG) {
634 printf("%s: id=%s flags=%s source=%s\n",
635 __func__,
636 id->name,
637 stringify_update_bitfield(flag).c_str(),
638 update_source_as_string(update_source));
639 }
640 IDNode *id_node = (graph != nullptr) ? graph->find_id_node(id) : nullptr;
641 if (graph != nullptr) {
642 DEG_graph_id_type_tag(reinterpret_cast<::Depsgraph *>(graph), GS(id->name));
643 }
644 if (flag == 0) {
645 deg_graph_node_tag_zero(bmain, graph, id_node, update_source);
646 }
647 /* Store original flag in the ID.
648 * Allows to have more granularity than a node-factory based flags. */
649 if (id_node != nullptr) {
650 id_node->id_cow->recalc |= flag;
651 }
652 /* When ID is tagged for update based on an user edits store the recalc flags in the original ID.
653 * This way IDs in the undo steps will have this flag preserved, making it possible to restore
654 * all needed tags when new dependency graph is created on redo.
655 * This is the only way to ensure modifications to animation data (such as keyframes i.e.)
656 * properly triggers animation update for the newly constructed dependency graph on redo (while
657 * usually newly created dependency graph skips animation update to avoid loss of unkeyed
658 * changes). */
659 if (update_source == DEG_UPDATE_SOURCE_USER_EDIT) {
660 id->recalc |= deg_recalc_flags_effective(graph, flag);
661 }
662 int current_flag = flag;
663 while (current_flag != 0) {
664 IDRecalcFlag tag = (IDRecalcFlag)(1 << bitscan_forward_clear_i(¤t_flag));
665 graph_id_tag_update_single_flag(bmain, graph, id, id_node, tag, update_source);
666 }
667 /* Special case for nested node tree datablocks. */
668 id_tag_update_ntree_special(bmain, graph, id, flag, update_source);
669 /* Direct update tags means that something outside of simulated/cached
670 * physics did change and that cache is to be invalidated.
671 * This is only needed if data changes. If it's just a drawing, we keep the
672 * point cache. */
673 if (update_source == DEG_UPDATE_SOURCE_USER_EDIT && flag != ID_RECALC_SHADING) {
674 graph_id_tag_update_single_flag(
675 bmain, graph, id, id_node, ID_RECALC_POINT_CACHE, update_source);
676 }
677 }
678
679 } // namespace deg
680 } // namespace blender
681
DEG_update_tag_as_string(IDRecalcFlag flag)682 const char *DEG_update_tag_as_string(IDRecalcFlag flag)
683 {
684 switch (flag) {
685 case ID_RECALC_TRANSFORM:
686 return "TRANSFORM";
687 case ID_RECALC_GEOMETRY:
688 return "GEOMETRY";
689 case ID_RECALC_ANIMATION:
690 return "ANIMATION";
691 case ID_RECALC_PSYS_REDO:
692 return "PSYS_REDO";
693 case ID_RECALC_PSYS_RESET:
694 return "PSYS_RESET";
695 case ID_RECALC_PSYS_CHILD:
696 return "PSYS_CHILD";
697 case ID_RECALC_PSYS_PHYS:
698 return "PSYS_PHYS";
699 case ID_RECALC_PSYS_ALL:
700 return "PSYS_ALL";
701 case ID_RECALC_COPY_ON_WRITE:
702 return "COPY_ON_WRITE";
703 case ID_RECALC_SHADING:
704 return "SHADING";
705 case ID_RECALC_SELECT:
706 return "SELECT";
707 case ID_RECALC_BASE_FLAGS:
708 return "BASE_FLAGS";
709 case ID_RECALC_POINT_CACHE:
710 return "POINT_CACHE";
711 case ID_RECALC_EDITORS:
712 return "EDITORS";
713 case ID_RECALC_SEQUENCER_STRIPS:
714 return "SEQUENCER_STRIPS";
715 case ID_RECALC_AUDIO_SEEK:
716 return "AUDIO_SEEK";
717 case ID_RECALC_AUDIO_FPS:
718 return "AUDIO_FPS";
719 case ID_RECALC_AUDIO_VOLUME:
720 return "AUDIO_VOLUME";
721 case ID_RECALC_AUDIO_MUTE:
722 return "AUDIO_MUTE";
723 case ID_RECALC_AUDIO_LISTENER:
724 return "AUDIO_LISTENER";
725 case ID_RECALC_AUDIO:
726 return "AUDIO";
727 case ID_RECALC_PARAMETERS:
728 return "PARAMETERS";
729 case ID_RECALC_SOURCE:
730 return "SOURCE";
731 case ID_RECALC_ALL:
732 return "ALL";
733 case ID_RECALC_TAG_FOR_UNDO:
734 return "TAG_FOR_UNDO";
735 }
736 return nullptr;
737 }
738
739 /* Data-Based Tagging */
740
741 /* Tag given ID for an update in all the dependency graphs. */
DEG_id_tag_update(ID * id,int flag)742 void DEG_id_tag_update(ID *id, int flag)
743 {
744 DEG_id_tag_update_ex(G.main, id, flag);
745 }
746
DEG_id_tag_update_ex(Main * bmain,ID * id,int flag)747 void DEG_id_tag_update_ex(Main *bmain, ID *id, int flag)
748 {
749 if (id == nullptr) {
750 /* Ideally should not happen, but old depsgraph allowed this. */
751 return;
752 }
753 deg::id_tag_update(bmain, id, flag, deg::DEG_UPDATE_SOURCE_USER_EDIT);
754 }
755
DEG_graph_id_tag_update(struct Main * bmain,struct Depsgraph * depsgraph,struct ID * id,int flag)756 void DEG_graph_id_tag_update(struct Main *bmain,
757 struct Depsgraph *depsgraph,
758 struct ID *id,
759 int flag)
760 {
761 deg::Depsgraph *graph = (deg::Depsgraph *)depsgraph;
762 deg::graph_id_tag_update(bmain, graph, id, flag, deg::DEG_UPDATE_SOURCE_USER_EDIT);
763 }
764
DEG_time_tag_update(struct Main * bmain)765 void DEG_time_tag_update(struct Main *bmain)
766 {
767 for (deg::Depsgraph *depsgraph : deg::get_all_registered_graphs(bmain)) {
768 DEG_graph_time_tag_update(reinterpret_cast<::Depsgraph *>(depsgraph));
769 }
770 }
771
DEG_graph_time_tag_update(struct Depsgraph * depsgraph)772 void DEG_graph_time_tag_update(struct Depsgraph *depsgraph)
773 {
774 deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
775 deg_graph->tag_time_source();
776 }
777
778 /* Mark a particular datablock type as having changing. */
DEG_graph_id_type_tag(Depsgraph * depsgraph,short id_type)779 void DEG_graph_id_type_tag(Depsgraph *depsgraph, short id_type)
780 {
781 if (id_type == ID_NT) {
782 /* Stupid workaround so parent datablocks of nested nodetree get looped
783 * over when we loop over tagged datablock types. */
784 DEG_graph_id_type_tag(depsgraph, ID_MA);
785 DEG_graph_id_type_tag(depsgraph, ID_TE);
786 DEG_graph_id_type_tag(depsgraph, ID_LA);
787 DEG_graph_id_type_tag(depsgraph, ID_WO);
788 DEG_graph_id_type_tag(depsgraph, ID_SCE);
789 DEG_graph_id_type_tag(depsgraph, ID_SIM);
790 }
791 const int id_type_index = BKE_idtype_idcode_to_index(id_type);
792 deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
793 deg_graph->id_type_updated[id_type_index] = 1;
794 }
795
DEG_id_type_tag(Main * bmain,short id_type)796 void DEG_id_type_tag(Main *bmain, short id_type)
797 {
798 for (deg::Depsgraph *depsgraph : deg::get_all_registered_graphs(bmain)) {
799 DEG_graph_id_type_tag(reinterpret_cast<::Depsgraph *>(depsgraph), id_type);
800 }
801 }
802
803 /* Update dependency graph when visible scenes/layers changes. */
DEG_graph_on_visible_update(Main * bmain,Depsgraph * depsgraph,const bool do_time)804 void DEG_graph_on_visible_update(Main *bmain, Depsgraph *depsgraph, const bool do_time)
805 {
806 deg::Depsgraph *graph = (deg::Depsgraph *)depsgraph;
807 deg::deg_graph_on_visible_update(bmain, graph, do_time);
808 }
809
DEG_on_visible_update(Main * bmain,const bool do_time)810 void DEG_on_visible_update(Main *bmain, const bool do_time)
811 {
812 for (deg::Depsgraph *depsgraph : deg::get_all_registered_graphs(bmain)) {
813 DEG_graph_on_visible_update(bmain, reinterpret_cast<::Depsgraph *>(depsgraph), do_time);
814 }
815 }
816
817 /* Check if something was changed in the database and inform
818 * editors about this. */
DEG_ids_check_recalc(Main * bmain,Depsgraph * depsgraph,Scene * scene,ViewLayer * view_layer,bool time)819 void DEG_ids_check_recalc(
820 Main *bmain, Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, bool time)
821 {
822 bool updated = time || DEG_id_type_any_updated(depsgraph);
823
824 DEGEditorUpdateContext update_ctx = {nullptr};
825 update_ctx.bmain = bmain;
826 update_ctx.depsgraph = depsgraph;
827 update_ctx.scene = scene;
828 update_ctx.view_layer = view_layer;
829 deg::deg_editors_scene_update(&update_ctx, updated);
830 }
831
deg_graph_clear_id_recalc_flags(ID * id)832 static void deg_graph_clear_id_recalc_flags(ID *id)
833 {
834 id->recalc &= ~ID_RECALC_ALL;
835 bNodeTree *ntree = ntreeFromID(id);
836 /* Clear embedded node trees too. */
837 if (ntree) {
838 ntree->id.recalc &= ~ID_RECALC_ALL;
839 }
840 /* XXX And what about scene's master collection here? */
841 }
842
DEG_ids_clear_recalc(Main * UNUSED (bmain),Depsgraph * depsgraph)843 void DEG_ids_clear_recalc(Main *UNUSED(bmain), Depsgraph *depsgraph)
844 {
845 deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
846 /* TODO(sergey): Re-implement POST_UPDATE_HANDLER_WORKAROUND using entry_tags
847 * and id_tags storage from the new dependency graph. */
848 if (!DEG_id_type_any_updated(depsgraph)) {
849 return;
850 }
851 /* Go over all ID nodes nodes, clearing tags. */
852 for (deg::IDNode *id_node : deg_graph->id_nodes) {
853 /* TODO: we clear original ID recalc flags here, but this may not work
854 * correctly when there are multiple depsgraph with others still using
855 * the recalc flag. */
856 id_node->is_user_modified = false;
857 deg_graph_clear_id_recalc_flags(id_node->id_cow);
858 if (deg_graph->is_active) {
859 deg_graph_clear_id_recalc_flags(id_node->id_orig);
860 }
861 }
862 memset(deg_graph->id_type_updated, 0, sizeof(deg_graph->id_type_updated));
863 }
864