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(&current_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(&current_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