Blender V5.0
depsgraph_tag.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2013 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10
12
13#include <atomic>
14#include <cstdint>
15#include <cstdio>
16#include <cstring> /* required for memset */
17
18#include "BLI_index_range.hh"
19#include "BLI_math_bits.h"
20#include "BLI_utildefines.h"
21
22#include "DNA_curve_types.h"
23#include "DNA_key_types.h"
24#include "DNA_lattice_types.h"
25#include "DNA_mesh_types.h"
26#include "DNA_object_types.h"
27
28#include "BKE_anim_data.hh"
29#include "BKE_global.hh"
30#include "BKE_idtype.hh"
31#include "BKE_image.hh"
32#include "BKE_lib_override.hh"
33#include "BKE_node.hh"
34#include "BKE_scene.hh"
35#include "BKE_workspace.hh"
36
37#include "DEG_depsgraph.hh"
40
42#include "intern/depsgraph.hh"
52
53namespace deg = blender::deg;
54
55/* *********************** */
56/* Update Tagging/Flushing */
57
58namespace blender::deg {
59
60namespace {
61
62void depsgraph_geometry_tag_to_component(const ID *id, NodeType *component_type)
63{
66 *component_type = result;
67 }
68}
69
70bool is_selectable_data_id_type(const ID_Type id_type)
71{
73}
74
75void depsgraph_select_tag_to_component_opcode(const ID *id,
76 NodeType *component_type,
77 OperationCode *operation_code)
78{
79 const ID_Type id_type = GS(id->name);
80 if (id_type == ID_SCE) {
81 /* We need to flush base flags to all objects in a scene since we
82 * don't know which ones changed. However, we don't want to update
83 * the whole scene, so pick up some operation which will do as less
84 * as possible.
85 *
86 * TODO(sergey): We can introduce explicit exit operation which
87 * does nothing and which is only used to cascade flush down the
88 * road. */
89 *component_type = NodeType::LAYER_COLLECTIONS;
90 *operation_code = OperationCode::VIEW_LAYER_EVAL;
91 }
92 else if (id_type == ID_OB) {
93 *component_type = NodeType::OBJECT_FROM_LAYER;
95 }
96 else if (is_selectable_data_id_type(id_type)) {
97 *component_type = NodeType::BATCH_CACHE;
99 }
100 else {
101 *component_type = NodeType::COPY_ON_EVAL;
102 *operation_code = OperationCode::COPY_ON_EVAL;
103 }
104}
105
106void depsgraph_base_flags_tag_to_component_opcode(const ID *id,
107 NodeType *component_type,
108 OperationCode *operation_code)
109{
110 const ID_Type id_type = GS(id->name);
111 if (id_type == ID_SCE) {
112 *component_type = NodeType::LAYER_COLLECTIONS;
113 *operation_code = OperationCode::VIEW_LAYER_EVAL;
114 }
115 else if (id_type == ID_OB) {
116 *component_type = NodeType::OBJECT_FROM_LAYER;
117 *operation_code = OperationCode::OBJECT_BASE_FLAGS;
118 }
119}
120
121OperationCode psysTagToOperationCode(IDRecalcFlag tag)
122{
123 if (tag == ID_RECALC_PSYS_RESET) {
125 }
127}
128
129void depsgraph_tag_to_component_opcode(const ID *id,
130 IDRecalcFlag tag,
131 NodeType *component_type,
132 OperationCode *operation_code)
133{
134 const ID_Type id_type = GS(id->name);
135 *component_type = NodeType::UNDEFINED;
136 *operation_code = OperationCode::OPERATION;
137 /* Special case for now, in the future we should get rid of this. */
138 if (tag == 0) {
139 *component_type = NodeType::ID_REF;
140 *operation_code = OperationCode::OPERATION;
141 return;
142 }
143 switch (tag) {
145 *component_type = NodeType::TRANSFORM;
146 break;
148 depsgraph_geometry_tag_to_component(id, component_type);
149 break;
151 *component_type = NodeType::ANIMATION;
152 break;
157 if (id_type == ID_PA) {
158 /* NOTES:
159 * - For particle settings node we need to use different
160 * component. Will be nice to get this unified with object,
161 * but we can survive for now with single exception here.
162 * Particles needs reconsideration anyway, */
163 *component_type = NodeType::PARTICLE_SETTINGS;
164 *operation_code = psysTagToOperationCode(tag);
165 }
166 else {
167 *component_type = NodeType::PARTICLE_SYSTEM;
168 }
169 break;
171 *component_type = NodeType::COPY_ON_EVAL;
172 break;
174 *component_type = NodeType::SHADING;
175 break;
176 case ID_RECALC_SELECT:
177 depsgraph_select_tag_to_component_opcode(id, component_type, operation_code);
178 break;
180 depsgraph_base_flags_tag_to_component_opcode(id, component_type, operation_code);
181 break;
183 *component_type = NodeType::POINT_CACHE;
184 break;
186 /* There is no such node in depsgraph, this tag is to be handled
187 * separately. */
188 break;
190 *component_type = NodeType::SEQUENCER;
191 break;
197 case ID_RECALC_AUDIO:
198 *component_type = NodeType::AUDIO;
199 break;
201 *component_type = NodeType::PARAMETERS;
202 break;
203 case ID_RECALC_SOURCE:
204 *component_type = NodeType::PARAMETERS;
205 break;
207 case ID_RECALC_ALL:
209 BLI_assert_msg(0, "Should not happen");
210 break;
212 break; /* Must be ignored by depsgraph. */
214 *component_type = NodeType::NTREE_OUTPUT;
215 *operation_code = OperationCode::NTREE_OUTPUT;
216 break;
217
219 *component_type = NodeType::HIERARCHY;
220 *operation_code = OperationCode::HIERARCHY;
221 break;
222
228 /* Silently ignore.
229 * The bits might be passed here from ID_RECALC_ALL. This is not a code-mistake, but just the
230 * way how the recalc flags are handled. */
231 break;
232 }
233}
234
235void id_tag_update_ntree_special(
236 Main *bmain, Depsgraph *graph, ID *id, uint flags, eUpdateSource update_source)
237{
239 if (ntree == nullptr) {
240 return;
241 }
242 graph_id_tag_update(bmain, graph, &ntree->id, flags, update_source);
243}
244
245void depsgraph_update_editors_tag(Main *bmain, Depsgraph *graph, ID *id)
246{
247 /* NOTE: We handle this immediately, without delaying anything, to be
248 * sure we don't cause threading issues with OpenGL. */
249 /* TODO(sergey): Make sure this works for evaluated data-blocks as well. */
250 DEGEditorUpdateContext update_ctx = {nullptr};
251 update_ctx.bmain = bmain;
252 update_ctx.depsgraph = (::Depsgraph *)graph;
253 update_ctx.scene = graph->scene;
254 update_ctx.view_layer = graph->view_layer;
255 deg_editors_id_update(&update_ctx, id);
256}
257
258void depsgraph_id_tag_copy_on_write(Depsgraph *graph, IDNode *id_node, eUpdateSource update_source)
259{
260 ComponentNode *cow_comp = id_node->find_component(NodeType::COPY_ON_EVAL);
261 if (cow_comp == nullptr) {
262 BLI_assert(!deg_eval_copy_is_needed(GS(id_node->id_orig->name)));
263 return;
264 }
265 cow_comp->tag_update(graph, update_source);
266}
267
268void depsgraph_tag_component(Depsgraph *graph,
269 IDNode *id_node,
270 NodeType component_type,
271 OperationCode operation_code,
272 eUpdateSource update_source)
273{
274 ComponentNode *component_node = id_node->find_component(component_type);
275 /* NOTE: Animation component might not be existing yet (which happens when adding new driver or
276 * adding a new keyframe), so the required copy-on-evaluation tag needs to be taken care
277 * explicitly here. */
278 if (component_node == nullptr) {
279 if (component_type == NodeType::ANIMATION) {
280 id_node->is_cow_explicitly_tagged = true;
281 depsgraph_id_tag_copy_on_write(graph, id_node, update_source);
282 }
283 return;
284 }
285 if (operation_code == OperationCode::OPERATION) {
286 component_node->tag_update(graph, update_source);
287 }
288 else {
289 OperationNode *operation_node = component_node->find_operation(operation_code);
290 if (operation_node != nullptr) {
291 operation_node->tag_update(graph, update_source);
292 }
293 }
294 /* If component depends on copy-on-evaluation, tag it as well. */
295 if (component_node->need_tag_cow_before_update(IDRecalcFlag(id_node->id_cow->recalc))) {
296 depsgraph_id_tag_copy_on_write(graph, id_node, update_source);
297 }
298 if (component_type == NodeType::COPY_ON_EVAL) {
299 id_node->is_cow_explicitly_tagged = true;
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 data-block changed. Now API expects that ID is given
307 * explicitly, but not all areas are aware of this yet. */
308void deg_graph_id_tag_legacy_compat(
309 Main *bmain, Depsgraph *depsgraph, ID *id, IDRecalcFlag tag, eUpdateSource update_source)
310{
311 if (ELEM(tag, ID_RECALC_GEOMETRY, 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_LEGACY: {
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
360void 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
405std::string stringify_update_bitfield(uint flags)
406{
407 if (flags == 0) {
408 return "LEGACY_0";
409 }
410 return DEG_stringify_recalc_flags(flags);
411}
412
413const char *update_source_as_string(eUpdateSource source)
414{
415 switch (source) {
417 return "TIME";
419 return "USER_EDIT";
421 return "RELATIONS";
423 return "VISIBILITY";
425 return "SIDE_EFFECT_REQUEST";
426 }
427 BLI_assert_msg(0, "Should never happen.");
428 return "UNKNOWN";
429}
430
431int deg_recalc_flags_for_legacy_zero()
432{
435}
436
437int deg_recalc_flags_effective(Depsgraph *graph, uint flags)
438{
439 if (graph != nullptr) {
440 if (!graph->is_active) {
441 return 0;
442 }
443 }
444 if (flags == 0) {
445 return deg_recalc_flags_for_legacy_zero();
446 }
447 return flags;
448}
449
450/* Special tag function which tags all components which needs to be tagged
451 * for update flag=0.
452 *
453 * TODO(sergey): This is something to be avoid in the future, make it more
454 * explicit and granular for users to tag what they really need. */
455void deg_graph_node_tag_zero(Main *bmain,
456 Depsgraph *graph,
457 IDNode *id_node,
458 eUpdateSource update_source)
459{
460 if (id_node == nullptr) {
461 return;
462 }
463 ID *id = id_node->id_orig;
464 /* TODO(sergey): Which recalc flags to set here? */
465 id_node->id_cow->recalc |= deg_recalc_flags_for_legacy_zero();
466
467 for (ComponentNode *comp_node : id_node->components.values()) {
468 if (comp_node->type == NodeType::ANIMATION) {
469 continue;
470 }
471 if (comp_node->type == NodeType::COPY_ON_EVAL) {
472 id_node->is_cow_explicitly_tagged = true;
473 }
474
475 comp_node->tag_update(graph, update_source);
476 }
477 deg_graph_id_tag_legacy_compat(bmain, graph, id, (IDRecalcFlag)0, update_source);
478}
479
480/* Implicit tagging of the parameters component on other changes.
481 *
482 * This takes care of ensuring that if a change made in C side on parameters which affect,
483 * say, geometry and explicit tag only done for geometry, parameters are also tagged to give
484 * drivers a chance to re-evaluate for the new values. */
485void deg_graph_tag_parameters_if_needed(Main *bmain,
486 Depsgraph *graph,
487 ID *id,
488 IDNode *id_node,
489 const uint flags,
490 const eUpdateSource update_source)
491{
492 if (flags == 0) {
493 /* Tagging for 0 flags is handled in deg_graph_node_tag_zero(), and parameters are handled
494 * there as well. */
495 return;
496 }
497
498 if (flags & ID_RECALC_PARAMETERS) {
499 /* Parameters are already tagged for update explicitly, no need to run extra logic here. */
500 return;
501 }
502
503 /* Clear flags which are known to not affect parameters usable by drivers. */
504 const uint clean_flags = flags &
507 /* While drivers may use the current-frame, this value is assigned
508 * explicitly and doesn't require the scene to be copied again. */
510
511 if (clean_flags == 0) {
512 /* Changes are limited to only things which are not usable by drivers. */
513 return;
514 }
515
516 graph_id_tag_update_single_flag(bmain, graph, id, id_node, ID_RECALC_PARAMETERS, update_source);
517}
518
519void graph_tag_on_visible_update(Depsgraph *graph, const bool do_time)
520{
521 graph->need_tag_id_on_graph_visibility_update = true;
522 graph->need_tag_id_on_graph_visibility_time_update |= do_time;
523}
524
525} /* namespace */
526
528{
530 return;
531 }
532
533 const bool do_time = graph->need_tag_id_on_graph_visibility_time_update;
534 Main *bmain = graph->bmain;
535
536 /* NOTE: It is possible to have this function called with `do_time=false` first and later (prior
537 * to evaluation though) with `do_time=true`. This means early output checks should be aware of
538 * this. */
539 for (deg::IDNode *id_node : graph->id_nodes) {
540 const ID_Type id_type = GS(id_node->id_orig->name);
541
542 if (!id_node->visible_components_mask) {
543 /* ID has no components which affects anything visible.
544 * No need bother with it to tag or anything. */
545 continue;
546 }
547 uint flags = 0;
548 if (!deg::deg_eval_copy_is_expanded(id_node->id_cow)) {
549 flags |= ID_RECALC_SYNC_TO_EVAL;
550 if (do_time) {
551 if (BKE_animdata_from_id(id_node->id_orig) != nullptr) {
552 flags |= ID_RECALC_ANIMATION;
553 }
554 }
555 }
556 else {
558 /* The ID was already visible and evaluated, all the subsequent
559 * updates and tags are to be done explicitly. */
560 continue;
561 }
562 }
563 /* We only tag components which needs an update. Tagging everything is
564 * not a good idea because that might reset particles cache (or any
565 * other type of cache).
566 *
567 * TODO(sergey): Need to generalize this somehow. */
568 if (id_type == ID_OB) {
570 }
571 /* For non-copy-on-eval datablocks like images, there is no need to update when
572 * they just got added to the depsgraph and there is no flag indicating
573 * a specific change that was made to them. Unlike evaluated datablocks which
574 * have just been copied.
575 * This helps preserve cached image draw data for the compositor. */
576 if (ID_TYPE_USE_COPY_ON_EVAL(id_type) || flags != 0) {
577 graph_id_tag_update(bmain, graph, id_node->id_orig, flags, DEG_UPDATE_SOURCE_VISIBILITY);
578 }
579 if (id_type == ID_SCE) {
580 /* Make sure collection properties are up to date. */
582 }
583 /* Now when ID is updated to the new visibility state, prevent it from
584 * being re-tagged again. Simplest way to do so is to pretend that it
585 * was already updated by the "previous" dependency graph.
586 *
587 * NOTE: Even if the on_visible_update() is called from the state when
588 * dependency graph is tagged for relations update, it will be fine:
589 * since dependency graph builder re-schedules entry tags, all the
590 * tags we request from here will be applied in the updated state of
591 * dependency graph. */
593 }
594
597}
598
600{
601 const ID_Type id_type = GS(id->name);
602 switch (id_type) {
603 case ID_OB: {
604 const Object *object = (Object *)id;
605 switch (object->type) {
606 case OB_MESH:
607 case OB_CURVES_LEGACY:
608 case OB_SURF:
609 case OB_FONT:
610 case OB_LATTICE:
611 case OB_MBALL:
612 case OB_CURVES:
613 case OB_POINTCLOUD:
614 case OB_VOLUME:
615 case OB_GREASE_PENCIL:
616 return NodeType::GEOMETRY;
617 case OB_ARMATURE:
618 return NodeType::EVAL_POSE;
619 /* TODO(sergey): More cases here? */
620 }
621 break;
622 }
623 case ID_ME:
624 case ID_CU_LEGACY:
625 case ID_LT:
626 case ID_MB:
627 case ID_CV:
628 case ID_PT:
629 case ID_VO:
630 case ID_GR:
631 return NodeType::GEOMETRY;
632 case ID_PA: /* Particles */
633 return NodeType::UNDEFINED;
634 case ID_LP:
636 case ID_GD_LEGACY:
637 return NodeType::GEOMETRY;
638 case ID_PAL: /* Palettes */
640 case ID_MSK:
642 case ID_GP:
643 return NodeType::GEOMETRY;
644 default:
645 break;
646 }
647 return NodeType::UNDEFINED;
648}
649
650void id_tag_update(Main *bmain, ID *id, uint flags, eUpdateSource update_source)
651{
652 graph_id_tag_update(bmain, nullptr, id, flags, update_source);
654 graph_id_tag_update(bmain, depsgraph, id, flags, update_source);
655 }
656
657 if (update_source & DEG_UPDATE_SOURCE_USER_EDIT) {
659 }
660
661 /* Accumulate all tags for an ID between two undo steps, so they can be
662 * replayed for undo. */
663 id->recalc_after_undo_push |= deg_recalc_flags_effective(nullptr, flags);
664}
665
666/* IDs that are not covered by the copy-on-evaluation system track updates by storing a runtime
667 * update count that gets updated every time the ID is tagged for update. The updated value is the
668 * value of a global atomic that is initially zero and gets incremented every time *any* ID of the
669 * same type gets updated.
670 *
671 * The update counts can be used to check if the ID was changed since the last time it was cached
672 * by comparing its current update count with the one stored at the moment the ID was cached.
673 *
674 * A global atomic is used as opposed to incrementing the update count per ID to protect against
675 * the case where the ID is destroyed and a new one is created taking its same pointer location,
676 * which could be perceived as no update even though the ID was recreated entirely.
677 *
678 * Only Image IDs are considered for now, but other IDs could be supported if needed. */
679static void set_id_update_count(ID *id)
680{
681 if (GS(id->name) == ID_IM) {
682 Image *image = reinterpret_cast<Image *>(id);
683 static std::atomic<uint64_t> global_image_update_count = 0;
684 image->runtime->update_count = global_image_update_count.fetch_add(1) + 1;
685 }
686}
687
689 Main *bmain, Depsgraph *graph, ID *id, uint flags, eUpdateSource update_source)
690{
691 const int debug_flags = (graph != nullptr) ? DEG_debug_flags_get((::Depsgraph *)graph) : G.debug;
692 if (graph != nullptr && graph->is_evaluating) {
693 if (debug_flags & G_DEBUG_DEPSGRAPH_TAG) {
694 printf("ID tagged for update during dependency graph evaluation.\n");
695 }
696 return;
697 }
698 if (debug_flags & G_DEBUG_DEPSGRAPH_TAG) {
699 printf("%s: id=%s flags=%s source=%s\n",
700 __func__,
701 id->name,
702 stringify_update_bitfield(flags).c_str(),
703 update_source_as_string(update_source));
704 }
705
707
708 IDNode *id_node = (graph != nullptr) ? graph->find_id_node(id) : nullptr;
709 if (graph != nullptr) {
710 DEG_graph_id_type_tag(reinterpret_cast<::Depsgraph *>(graph), GS(id->name));
711 }
712 if (flags == 0) {
713 deg_graph_node_tag_zero(bmain, graph, id_node, update_source);
714 }
715 /* Store original flag in the ID.
716 * Allows to have more granularity than a node-factory based flags. */
717 if (id_node != nullptr) {
718 id_node->id_cow->recalc |= flags;
719 }
720 /* When ID is tagged for update based on an user edits store the recalc flags in the original ID.
721 * This way IDs in the undo steps will have this flag preserved, making it possible to restore
722 * all needed tags when new dependency graph is created on redo.
723 * This is the only way to ensure modifications to animation data (such as keyframes i.e.)
724 * properly triggers animation update for the newly constructed dependency graph on redo (while
725 * usually newly created dependency graph skips animation update to avoid loss of unkeyed
726 * changes). */
727 if (update_source == DEG_UPDATE_SOURCE_USER_EDIT) {
728 id->recalc |= deg_recalc_flags_effective(graph, flags);
729 }
730 uint current_flag = flags;
731 while (current_flag != 0) {
732 IDRecalcFlag tag = (IDRecalcFlag)(1 << bitscan_forward_clear_uint(&current_flag));
733 graph_id_tag_update_single_flag(bmain, graph, id, id_node, tag, update_source);
734 }
735 /* Special case for nested node tree data-blocks. */
736 id_tag_update_ntree_special(bmain, graph, id, flags, update_source);
737 /* Direct update tags means that something outside of simulated/cached
738 * physics did change and that cache is to be invalidated.
739 * This is only needed if data changes. If it's just a drawing, we keep the
740 * point cache. */
741 if (update_source == DEG_UPDATE_SOURCE_USER_EDIT && flags != ID_RECALC_SHADING) {
742 graph_id_tag_update_single_flag(
743 bmain, graph, id, id_node, ID_RECALC_POINT_CACHE, update_source);
744 }
745 deg_graph_tag_parameters_if_needed(bmain, graph, id, id_node, flags, update_source);
746}
747
748} // namespace blender::deg
749
751{
752 switch (flag) {
754 return "TRANSFORM";
756 return "GEOMETRY";
758 return "GEOMETRY_ALL_MODES";
760 return "ANIMATION";
762 return "PSYS_REDO";
764 return "PSYS_RESET";
766 return "PSYS_CHILD";
768 return "PSYS_PHYS";
770 return "PSYS_ALL";
772 return "COPY_ON_EVAL";
774 return "SHADING";
775 case ID_RECALC_SELECT:
776 return "SELECT";
778 return "BASE_FLAGS";
780 return "POINT_CACHE";
782 return "EDITORS";
784 return "SEQUENCER_STRIPS";
786 return "FRAME_CHANGE";
788 return "AUDIO_FPS";
790 return "AUDIO_VOLUME";
792 return "AUDIO_MUTE";
794 return "AUDIO_LISTENER";
795 case ID_RECALC_AUDIO:
796 return "AUDIO";
798 return "PARAMETERS";
799 case ID_RECALC_SOURCE:
800 return "SOURCE";
801 case ID_RECALC_ALL:
802 return "ALL";
804 return "TAG_FOR_UNDO";
806 return "ID_RECALC_NTREE_OUTPUT";
807
809 return "ID_RECALC_HIERARCHY";
810
816 /* Silently return nullptr, indicating that there is no string representation.
817 *
818 * This is needed due to the way how logging for ID_RECALC_ALL works: it iterates over all
819 * bits and converts then to string. */
820 return nullptr;
821 }
822 return nullptr;
823}
824
825/* Data-Based Tagging. */
826
827void DEG_id_tag_update(ID *id, uint flags)
828{
829 DEG_id_tag_update_ex(G.main, id, flags);
830}
831
832void DEG_id_tag_update_ex(Main *bmain, ID *id, uint flags)
833{
834 if (id == nullptr) {
835 /* Ideally should not happen, but old depsgraph allowed this. */
836 return;
837 }
839}
840
842{
843 BLI_assert(depsgraph != nullptr);
844 BLI_assert(id != nullptr);
846 Main *bmain = DEG_get_bmain(depsgraph);
848}
849
850void DEG_graph_id_tag_update(Main *bmain, Depsgraph *depsgraph, ID *id, uint flags)
851{
854}
855
857{
859 DEG_graph_time_tag_update(reinterpret_cast<::Depsgraph *>(depsgraph));
860 }
861}
862
864{
865 deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
866 deg_graph->tag_time_source();
867}
868
869void DEG_graph_id_type_tag(Depsgraph *depsgraph, short id_type)
870{
871 if (id_type == ID_NT) {
872 /* Stupid workaround so parent data-blocks of nested node-tree get looped
873 * over when we loop over tagged data-block types. */
879 }
880 const int id_type_index = BKE_idtype_idcode_to_index(id_type);
881 deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
882 deg_graph->id_type_updated[id_type_index] = 1;
883}
884
885void DEG_id_type_tag(Main *bmain, short id_type)
886{
888 DEG_graph_id_type_tag(reinterpret_cast<::Depsgraph *>(depsgraph), id_type);
889 }
890}
891
892void DEG_graph_tag_on_visible_update(Depsgraph *depsgraph, const bool do_time)
893{
895 deg::graph_tag_on_visible_update(graph, do_time);
896}
897
898void DEG_tag_on_visible_update(Main *bmain, const bool do_time)
899{
901 deg::graph_tag_on_visible_update(depsgraph, do_time);
902 }
903}
904
906{
908 graph->use_editors_update = true;
909}
910
911void DEG_editors_update(Depsgraph *depsgraph, bool time)
912{
914 if (!graph->use_editors_update) {
915 return;
916 }
917
920 Main *bmain = DEG_get_bmain(depsgraph);
921 bool updated = time || DEG_id_type_any_updated(depsgraph);
922
923 DEGEditorUpdateContext update_ctx = {nullptr};
924 update_ctx.bmain = bmain;
925 update_ctx.depsgraph = depsgraph;
926 update_ctx.scene = scene;
927 update_ctx.view_layer = view_layer;
928 deg::deg_editors_scene_update(&update_ctx, updated);
929}
930
932{
933 id->recalc &= ~ID_RECALC_ALL;
935 /* Clear embedded node trees too. */
936 if (ntree) {
937 ntree->id.recalc &= ~ID_RECALC_ALL;
938 }
939 /* XXX And what about scene's master collection here? */
940}
941
942void DEG_ids_clear_recalc(Depsgraph *depsgraph, const bool backup)
943{
944 deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
945 /* TODO(sergey): Re-implement POST_UPDATE_HANDLER_WORKAROUND using entry_tags
946 * and id_tags storage from the new dependency graph. */
948 return;
949 }
950 /* Go over all ID nodes, clearing tags. */
951 for (deg::IDNode *id_node : deg_graph->id_nodes) {
952 if (backup) {
953 id_node->id_cow_recalc_backup |= id_node->id_cow->recalc;
954 }
955 /* TODO: we clear original ID recalc flags here, but this may not work
956 * correctly when there are multiple depsgraph with others still using
957 * the recalc flag. */
958 id_node->is_user_modified = false;
959 id_node->is_cow_explicitly_tagged = false;
961 if (deg_graph->is_active) {
963 }
964 }
965
966 if (backup) {
968 if (deg_graph->id_type_updated[i] != 0) {
969 deg_graph->id_type_updated_backup[i] = 1;
970 }
971 }
972 }
973 memset(deg_graph->id_type_updated, 0, sizeof(deg_graph->id_type_updated));
974}
975
977{
978 deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
979
980 for (deg::IDNode *id_node : deg_graph->id_nodes) {
981 id_node->id_cow->recalc |= id_node->id_cow_recalc_backup;
982 id_node->id_cow_recalc_backup = 0;
983 }
984
986 if (deg_graph->id_type_updated_backup[i] != 0) {
987 deg_graph->id_type_updated[i] = 1;
988 }
989 }
990 memset(deg_graph->id_type_updated_backup, 0, sizeof(deg_graph->id_type_updated_backup));
991}
AnimData * BKE_animdata_from_id(const ID *id)
Definition anim_data.cc:83
@ G_DEBUG_DEPSGRAPH_TAG
int BKE_idtype_idcode_to_index(short idcode)
Definition idtype.cc:228
void BKE_lib_override_id_tag_on_deg_tag_from_user(ID *id)
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
MINLINE unsigned int bitscan_forward_clear_uint(unsigned int *a)
unsigned int uint
#define ELEM(...)
void DEG_graph_id_type_tag(Depsgraph *depsgraph, short id_type)
std::string DEG_stringify_recalc_flags(unsigned int flags)
int DEG_debug_flags_get(const Depsgraph *depsgraph)
ViewLayer * DEG_get_input_view_layer(const Depsgraph *graph)
Main * DEG_get_bmain(const Depsgraph *graph)
bool DEG_id_type_any_updated(const Depsgraph *depsgraph)
Scene * DEG_get_input_scene(const Depsgraph *graph)
#define ID_TYPE_USE_COPY_ON_EVAL(_id_type)
Definition DNA_ID.h:740
IDRecalcFlag
Definition DNA_ID.h:1049
@ ID_RECALC_PARAMETERS
Definition DNA_ID.h:1138
@ ID_RECALC_AUDIO_FPS
Definition DNA_ID.h:1127
@ ID_RECALC_PSYS_PHYS
Definition DNA_ID.h:1087
@ ID_RECALC_AUDIO_LISTENER
Definition DNA_ID.h:1130
@ ID_RECALC_TRANSFORM
Definition DNA_ID.h:1054
@ ID_RECALC_PROVISION_29
Definition DNA_ID.h:1166
@ ID_RECALC_SHADING
Definition DNA_ID.h:1094
@ ID_RECALC_PROVISION_30
Definition DNA_ID.h:1167
@ ID_RECALC_FRAME_CHANGE
Definition DNA_ID.h:1125
@ ID_RECALC_AUDIO
Definition DNA_ID.h:1132
@ ID_RECALC_POINT_CACHE
Definition DNA_ID.h:1105
@ ID_RECALC_SELECT
Definition DNA_ID.h:1101
@ ID_RECALC_PSYS_REDO
Definition DNA_ID.h:1081
@ ID_RECALC_PROVISION_31
Definition DNA_ID.h:1168
@ ID_RECALC_PSYS_CHILD
Definition DNA_ID.h:1085
@ ID_RECALC_HIERARCHY
Definition DNA_ID.h:1158
@ ID_RECALC_PROVISION_27
Definition DNA_ID.h:1164
@ ID_RECALC_SOURCE
Definition DNA_ID.h:1143
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1118
@ ID_RECALC_EDITORS
Definition DNA_ID.h:1111
@ ID_RECALC_GEOMETRY_ALL_MODES
Definition DNA_ID.h:1181
@ ID_RECALC_PSYS_ALL
Definition DNA_ID.h:1191
@ ID_RECALC_AUDIO_MUTE
Definition DNA_ID.h:1129
@ ID_RECALC_SEQUENCER_STRIPS
Definition DNA_ID.h:1122
@ ID_RECALC_TAG_FOR_UNDO
Definition DNA_ID.h:1152
@ ID_RECALC_NTREE_OUTPUT
Definition DNA_ID.h:1155
@ ID_RECALC_PSYS_RESET
Definition DNA_ID.h:1083
@ ID_RECALC_ANIMATION
Definition DNA_ID.h:1077
@ ID_RECALC_PROVISION_28
Definition DNA_ID.h:1165
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1074
@ ID_RECALC_ALL
Definition DNA_ID.h:1188
@ ID_RECALC_AUDIO_VOLUME
Definition DNA_ID.h:1128
@ ID_RECALC_BASE_FLAGS
Definition DNA_ID.h:1104
struct ID ID
#define INDEX_ID_MAX
Definition DNA_ID.h:1360
ID_Type
@ ID_TE
@ ID_IM
@ ID_VO
@ ID_NT
@ ID_LA
@ ID_SCE
@ ID_MSK
@ ID_CV
@ ID_PAL
@ ID_LP
@ ID_WO
@ ID_MA
@ ID_CU_LEGACY
@ ID_GD_LEGACY
@ ID_ME
@ ID_GR
@ ID_MB
@ ID_LT
@ ID_OB
@ ID_GP
@ ID_PA
@ ID_PT
struct Curve Curve
struct Lattice Lattice
struct Mesh Mesh
struct bNodeTree bNodeTree
Object is a sort of wrapper for general info.
@ OB_LATTICE
@ OB_MBALL
@ OB_SURF
@ OB_FONT
@ OB_GREASE_PENCIL
@ OB_ARMATURE
@ OB_MESH
@ OB_POINTCLOUD
@ OB_VOLUME
@ OB_CURVES_LEGACY
@ OB_CURVES
struct Object Object
BPy_StructRNA * depsgraph
long long int int64_t
void DEG_graph_time_tag_update(Depsgraph *depsgraph)
void DEG_id_type_tag(Main *bmain, short id_type)
void DEG_editors_update(Depsgraph *depsgraph, bool time)
void DEG_id_tag_update_ex(Main *bmain, ID *id, uint flags)
void DEG_enable_editors_update(Depsgraph *depsgraph)
void DEG_ids_clear_recalc(Depsgraph *depsgraph, const bool backup)
void DEG_time_tag_update(Main *bmain)
void DEG_tag_on_visible_update(Main *bmain, const bool do_time)
void DEG_id_tag_update(ID *id, uint flags)
void DEG_graph_id_tag_update(Main *bmain, Depsgraph *depsgraph, ID *id, uint flags)
void DEG_graph_tag_on_visible_update(Depsgraph *depsgraph, const bool do_time)
void DEG_id_tag_update_for_side_effect_request(Depsgraph *depsgraph, ID *id, uint flags)
void DEG_graph_id_type_tag(Depsgraph *depsgraph, short id_type)
const char * DEG_update_tag_as_string(IDRecalcFlag flag)
void DEG_ids_restore_recalc(Depsgraph *depsgraph)
static void deg_graph_clear_id_recalc_flags(ID *id)
#define GS(x)
#define printf(...)
#define G(x, y, z)
bNodeTree * node_tree_from_id(ID *id)
Definition node.cc:4568
Span< Depsgraph * > get_all_registered_graphs(Main *bmain)
NodeType geometry_tag_to_component(const ID *id)
static void set_id_update_count(ID *id)
void deg_editors_id_update(const DEGEditorUpdateContext *update_ctx, ID *id)
void deg_editors_scene_update(const DEGEditorUpdateContext *update_ctx, bool updated)
void graph_tag_ids_for_visible_update(Depsgraph *graph)
bool deg_eval_copy_is_expanded(const ID *id_cow)
bool deg_eval_copy_is_needed(const ID *id_orig)
DepsNodeFactory * type_get_factory(const NodeType type)
void id_tag_update(Main *bmain, ID *id, uint flags, eUpdateSource update_source)
void graph_id_tag_update(Main *bmain, Depsgraph *graph, ID *id, uint flags, eUpdateSource update_source)
@ DEG_UPDATE_SOURCE_SIDE_EFFECT_REQUEST
struct Key * key
Definition DNA_ID.h:414
unsigned int recalc
Definition DNA_ID.h:445
char name[258]
Definition DNA_ID.h:432
ImageRuntimeHandle * runtime
struct Key * key
struct Key * key
void tag_update(Depsgraph *graph, eUpdateSource source) override
IDNode * find_id_node(const ID *id) const
Definition depsgraph.cc:101
char id_type_updated[INDEX_ID_MAX]
Definition depsgraph.hh:117
bool need_tag_id_on_graph_visibility_time_update
Definition depsgraph.hh:114
bool need_tag_id_on_graph_visibility_update
Definition depsgraph.hh:113
char id_type_updated_backup[INDEX_ID_MAX]
Definition depsgraph.hh:119
IDComponentsMask previously_visible_components_mask
IDComponentsMask visible_components_mask
void tag_update(Depsgraph *graph, eUpdateSource source) override
i
Definition text_draw.cc:230
uint8_t flag
Definition wm_window.cc:145