Depsgraph: Comb code to a better state all over
[blender.git] / source / blender / depsgraph / intern / depsgraph_tag.cc
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2013 Blender Foundation.
19  * All rights reserved.
20  *
21  * Original Author: Joshua Leung
22  * Contributor(s): None Yet
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file blender/depsgraph/intern/depsgraph_tag.cc
28  *  \ingroup depsgraph
29  *
30  * Core routines for how the Depsgraph works.
31  */
32
33 #include "intern/depsgraph_tag.h"
34
35 #include <stdio.h>
36 #include <cstring>  /* required for memset */
37 #include <queue>
38
39 #include "BLI_utildefines.h"
40 #include "BLI_listbase.h"
41 #include "BLI_math_bits.h"
42 #include "BLI_task.h"
43
44 extern "C" {
45 #include "DNA_anim_types.h"
46 #include "DNA_curve_types.h"
47 #include "DNA_key_types.h"
48 #include "DNA_lattice_types.h"
49 #include "DNA_mesh_types.h"
50 #include "DNA_object_types.h"
51 #include "DNA_particle_types.h"
52 #include "DNA_screen_types.h"
53 #include "DNA_windowmanager_types.h"
54
55 #include "BKE_animsys.h"
56 #include "BKE_global.h"
57 #include "BKE_idcode.h"
58 #include "BKE_node.h"
59 #include "BKE_scene.h"
60 #include "BKE_workspace.h"
61
62 #define new new_
63 #include "BKE_screen.h"
64 #undef new
65 } /* extern "C" */
66
67 #include "DEG_depsgraph.h"
68 #include "DEG_depsgraph_debug.h"
69 #include "DEG_depsgraph_query.h"
70
71 #include "intern/builder/deg_builder.h"
72 #include "intern/depsgraph.h"
73 #include "intern/depsgraph_update.h"
74 #include "intern/eval/deg_eval_copy_on_write.h"
75 #include "intern/eval/deg_eval_flush.h"
76 #include "intern/node/deg_node.h"
77 #include "intern/node/deg_node_component.h"
78 #include "intern/node/deg_node_factory.h"
79 #include "intern/node/deg_node_id.h"
80 #include "intern/node/deg_node_operation.h"
81
82 /* *********************** */
83 /* Update Tagging/Flushing */
84
85 namespace DEG {
86
87 namespace {
88
89 void depsgraph_geometry_tag_to_component(const ID *id,
90                                          NodeType *component_type)
91 {
92         const NodeType result = geometry_tag_to_component(id);
93         if (result != NodeType::UNDEFINED) {
94                 *component_type = result;
95         }
96 }
97
98 bool is_selectable_data_id_type(const ID_Type id_type)
99 {
100         return ELEM(id_type, ID_ME, ID_CU, ID_MB, ID_LT, ID_GD);
101 }
102
103 void depsgraph_select_tag_to_component_opcode(
104         const ID *id,
105         NodeType *component_type,
106         OperationCode *operation_code)
107 {
108         const ID_Type id_type = GS(id->name);
109         if (id_type == ID_SCE) {
110                 /* We need to flush base flags to all objects in a scene since we
111                  * don't know which ones changed. However, we don't want to update
112                  * the whole scene, so pick up some operation which will do as less
113                  * as possible.
114                  *
115                  * TODO(sergey): We can introduce explicit exit operation which
116                  * does nothing and which is only used to cascade flush down the
117                  * road. */
118                 *component_type = NodeType::LAYER_COLLECTIONS;
119                 *operation_code = OperationCode::VIEW_LAYER_EVAL;
120         }
121         else if (id_type == ID_OB) {
122                 *component_type = NodeType::OBJECT_FROM_LAYER;
123                 *operation_code = OperationCode::OBJECT_BASE_FLAGS;
124         }
125         else if (id_type == ID_MC) {
126                 *component_type = NodeType::BATCH_CACHE;
127                 *operation_code = OperationCode::MOVIECLIP_SELECT_UPDATE;
128         }
129         else if (is_selectable_data_id_type(id_type)) {
130                 *component_type = NodeType::BATCH_CACHE;
131                 *operation_code = OperationCode::GEOMETRY_SELECT_UPDATE;
132         }
133         else {
134                 *component_type = NodeType::COPY_ON_WRITE;
135                 *operation_code = OperationCode::COPY_ON_WRITE;
136         }
137 }
138
139 void depsgraph_base_flags_tag_to_component_opcode(
140         const ID *id,
141         NodeType *component_type,
142         OperationCode *operation_code)
143 {
144         const ID_Type id_type = GS(id->name);
145         if (id_type == ID_SCE) {
146                 *component_type = NodeType::LAYER_COLLECTIONS;
147                 *operation_code = OperationCode::VIEW_LAYER_EVAL;
148         }
149         else if (id_type == ID_OB) {
150                 *component_type = NodeType::OBJECT_FROM_LAYER;
151                 *operation_code = OperationCode::OBJECT_BASE_FLAGS;
152         }
153 }
154
155 OperationCode psysTagToOperationCode(IDRecalcFlag tag)
156 {
157         if (tag == ID_RECALC_PSYS_RESET) {
158                 return OperationCode::PARTICLE_SETTINGS_RESET;
159         }
160         return OperationCode::OPERATION;
161 }
162
163 void depsgraph_tag_to_component_opcode(const ID *id,
164                                        IDRecalcFlag tag,
165                                        NodeType *component_type,
166                                        OperationCode *operation_code)
167 {
168         const ID_Type id_type = GS(id->name);
169         *component_type = NodeType::UNDEFINED;
170         *operation_code = OperationCode::OPERATION;
171         /* Special case for now, in the future we should get rid of this. */
172         if (tag == 0) {
173                 *component_type = NodeType::ID_REF;
174                 *operation_code = OperationCode::OPERATION;
175                 return;
176         }
177         switch (tag) {
178                 case ID_RECALC_TRANSFORM:
179                         *component_type = NodeType::TRANSFORM;
180                         break;
181                 case ID_RECALC_GEOMETRY:
182                         depsgraph_geometry_tag_to_component(id, component_type);
183                         break;
184                 case ID_RECALC_ANIMATION:
185                         *component_type = NodeType::ANIMATION;
186                         break;
187                 case ID_RECALC_PSYS_REDO:
188                 case ID_RECALC_PSYS_RESET:
189                 case ID_RECALC_PSYS_CHILD:
190                 case ID_RECALC_PSYS_PHYS:
191                         if (id_type == ID_PA) {
192                                 /* NOTES:
193                                  * - For particle settings node we need to use different
194                                  *   component. Will be nice to get this unified with object,
195                                  *   but we can survive for now with single exception here.
196                                  *   Particles needs reconsideration anyway, */
197                                 *component_type = NodeType::PARTICLE_SETTINGS;
198                                 *operation_code = psysTagToOperationCode(tag);
199                         }
200                         else {
201                                 *component_type = NodeType::PARTICLE_SYSTEM;
202                         }
203                         break;
204                 case ID_RECALC_COPY_ON_WRITE:
205                         *component_type = NodeType::COPY_ON_WRITE;
206                         break;
207                 case ID_RECALC_SHADING:
208                         if (id_type == ID_NT) {
209                                 *component_type = NodeType::SHADING_PARAMETERS;
210                         }
211                         else {
212                                 *component_type = NodeType::SHADING;
213                         }
214                         break;
215                 case ID_RECALC_SELECT:
216                         depsgraph_select_tag_to_component_opcode(id,
217                                                                  component_type,
218                                                                  operation_code);
219                         break;
220                 case ID_RECALC_BASE_FLAGS:
221                         depsgraph_base_flags_tag_to_component_opcode(id,
222                                                                      component_type,
223                                                                      operation_code);
224                         break;
225                 case ID_RECALC_POINT_CACHE:
226                         *component_type = NodeType::POINT_CACHE;
227                         break;
228                 case ID_RECALC_EDITORS:
229                         /* There is no such node in depsgraph, this tag is to be handled
230                          * separately. */
231                         break;
232                 case ID_RECALC_ALL:
233                 case ID_RECALC_PSYS_ALL:
234                         BLI_assert(!"Should not happen");
235                         break;
236         }
237 }
238
239 void id_tag_update_ntree_special(Main *bmain,
240                                  Depsgraph *graph,
241                                  ID *id,
242                                  int flag,
243                                  eUpdateSource update_source)
244 {
245         bNodeTree *ntree = ntreeFromID(id);
246         if (ntree == NULL) {
247                 return;
248         }
249         graph_id_tag_update(bmain, graph, &ntree->id, flag, update_source);
250 }
251
252 void depsgraph_update_editors_tag(Main *bmain, Depsgraph *graph, ID *id)
253 {
254         /* NOTE: We handle this immediately, without delaying anything, to be
255          * sure we don't cause threading issues with OpenGL. */
256         /* TODO(sergey): Make sure this works for CoW-ed datablocks as well. */
257         DEGEditorUpdateContext update_ctx = {NULL};
258         update_ctx.bmain = bmain;
259         update_ctx.depsgraph = (::Depsgraph *)graph;
260         update_ctx.scene = graph->scene;
261         update_ctx.view_layer = graph->view_layer;
262         deg_editors_id_update(&update_ctx, id);
263 }
264
265 void depsgraph_tag_component(Depsgraph *graph,
266                              IDNode *id_node,
267                              NodeType component_type,
268                              OperationCode operation_code,
269                              eUpdateSource update_source)
270 {
271         ComponentNode *component_node =
272                 id_node->find_component(component_type);
273         if (component_node == NULL) {
274                 return;
275         }
276         if (operation_code == OperationCode::OPERATION) {
277                 component_node->tag_update(graph, update_source);
278         }
279         else {
280                 OperationNode *operation_node =
281                         component_node->find_operation(operation_code);
282                 if (operation_node != NULL) {
283                         operation_node->tag_update(graph, update_source);
284                 }
285         }
286         /* If component depends on copy-on-write, tag it as well. */
287         if (component_node->need_tag_cow_before_update()) {
288                 ComponentNode *cow_comp =
289                         id_node->find_component(NodeType::COPY_ON_WRITE);
290                 cow_comp->tag_update(graph, update_source);
291                 id_node->id_orig->recalc |= ID_RECALC_COPY_ON_WRITE;
292         }
293 }
294
295 /* This is a tag compatibility with legacy code.
296  *
297  * Mainly, old code was tagging object with ID_RECALC_GEOMETRY tag to inform
298  * that object's data datablock changed. Now API expects that ID is given
299  * explicitly, but not all areas are aware of this yet. */
300 void deg_graph_id_tag_legacy_compat(Main *bmain,
301                                     Depsgraph *depsgraph,
302                                     ID *id,
303                                     IDRecalcFlag tag,
304                                     eUpdateSource update_source)
305 {
306         if (tag == ID_RECALC_GEOMETRY || tag == 0) {
307                 switch (GS(id->name)) {
308                         case ID_OB:
309                         {
310                                 Object *object = (Object *)id;
311                                 ID *data_id = (ID *)object->data;
312                                 if (data_id != NULL) {
313                                         graph_id_tag_update(
314                                                 bmain, depsgraph, data_id, 0, update_source);
315                                 }
316                                 break;
317                         }
318                         /* TODO(sergey): Shape keys are annoying, maybe we should find a
319                          * way to chain geometry evaluation to them, so we don't need extra
320                          * tagging here. */
321                         case ID_ME:
322                         {
323                                 Mesh *mesh = (Mesh *)id;
324                                 ID *key_id = &mesh->key->id;
325                                 if (key_id != NULL) {
326                                         graph_id_tag_update(
327                                                 bmain, depsgraph, key_id, 0, update_source);
328                                 }
329                                 break;
330                         }
331                         case ID_LT:
332                         {
333                                 Lattice *lattice = (Lattice *)id;
334                                 ID *key_id = &lattice->key->id;
335                                 if (key_id != NULL) {
336                                         graph_id_tag_update(
337                                                 bmain, depsgraph, key_id, 0, update_source);
338                                 }
339                                 break;
340                         }
341                         case ID_CU:
342                         {
343                                 Curve *curve = (Curve *)id;
344                                 ID *key_id = &curve->key->id;
345                                 if (key_id != NULL) {
346                                         graph_id_tag_update(
347                                                 bmain, depsgraph, key_id, 0, update_source);
348                                 }
349                                 break;
350                         }
351                         default:
352                                 break;
353                 }
354         }
355 }
356
357 static void graph_id_tag_update_single_flag(Main *bmain,
358                                             Depsgraph *graph,
359                                             ID *id,
360                                             IDNode *id_node,
361                                             IDRecalcFlag tag,
362                                             eUpdateSource update_source)
363 {
364         if (tag == ID_RECALC_EDITORS) {
365                 if (graph != NULL) {
366                         depsgraph_update_editors_tag(bmain, graph, id);
367                 }
368                 return;
369         }
370         /* Get description of what is to be tagged. */
371         NodeType component_type;
372         OperationCode operation_code;
373         depsgraph_tag_to_component_opcode(id,
374                                           tag,
375                                           &component_type,
376                                           &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         /* Tag ID recalc flag. */
384         DepsNodeFactory *factory = type_get_factory(component_type);
385         BLI_assert(factory != NULL);
386         id->recalc |= factory->id_recalc_tag();
387         /* Some sanity checks before moving forward. */
388         if (id_node == NULL) {
389                 /* Happens when object is tagged for update and not yet in the
390                  * dependency graph (but will be after relations update). */
391                 return;
392         }
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(
399                         graph, id_node, component_type, operation_code, update_source);
400         }
401         /* TODO(sergey): Get rid of this once all areas are using proper data ID
402          * for tagging. */
403         deg_graph_id_tag_legacy_compat(bmain, graph, id, tag, update_source);
404
405 }
406
407 string stringify_append_bit(const string& str, IDRecalcFlag tag)
408 {
409         string result = str;
410         if (!result.empty()) {
411                 result += ", ";
412         }
413         result += DEG_update_tag_as_string(tag);
414         return result;
415 }
416
417 string stringify_update_bitfield(int flag)
418 {
419         if (flag == 0) {
420                 return "LEGACY_0";
421         }
422         string result = "";
423         int current_flag = flag;
424         /* Special cases to avoid ALL flags form being split into
425          * individual bits. */
426         if ((current_flag & ID_RECALC_PSYS_ALL) == ID_RECALC_PSYS_ALL) {
427                 result = stringify_append_bit(result, ID_RECALC_PSYS_ALL);
428         }
429         /* Handle all the rest of the flags. */
430         while (current_flag != 0) {
431                 IDRecalcFlag tag =
432                         (IDRecalcFlag)(1 << bitscan_forward_clear_i(&current_flag));
433                 result = stringify_append_bit(result, tag);
434         }
435         return result;
436 }
437
438 const char *update_source_as_string(eUpdateSource source)
439 {
440         switch (source) {
441                 case DEG_UPDATE_SOURCE_TIME: return "TIME";
442                 case DEG_UPDATE_SOURCE_USER_EDIT: return "USER_EDIT";
443                 case DEG_UPDATE_SOURCE_RELATIONS: return "RELATIONS";
444                 case DEG_UPDATE_SOURCE_VISIBILITY: return "VISIBILITY";
445         }
446         BLI_assert(!"Should never happen.");
447         return "UNKNOWN";
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. */
455 void deg_graph_node_tag_zero(Main *bmain,
456                              Depsgraph *graph,
457                              IDNode *id_node,
458                              eUpdateSource update_source)
459 {
460         if (id_node == NULL) {
461                 return;
462         }
463         ID *id = id_node->id_orig;
464         /* TODO(sergey): Which recalc flags to set here? */
465         id->recalc |= ID_RECALC_ALL & ~(ID_RECALC_PSYS_ALL | ID_RECALC_ANIMATION);
466         GHASH_FOREACH_BEGIN(ComponentNode *, comp_node, id_node->components)
467         {
468                 if (comp_node->type == NodeType::ANIMATION) {
469                         continue;
470                 }
471                 comp_node->tag_update(graph, DEG_UPDATE_SOURCE_USER_EDIT);
472         }
473         GHASH_FOREACH_END();
474         deg_graph_id_tag_legacy_compat(
475                 bmain, graph, id, (IDRecalcFlag)0, update_source);
476 }
477
478 void deg_graph_on_visible_update(Main *bmain, Depsgraph *graph)
479 {
480         for (DEG::IDNode *id_node : graph->id_nodes) {
481                 if (!id_node->visible_components_mask) {
482                         /* ID has no components which affects anything visible. no meed
483                          * bother with it to tag or anything. */
484                         continue;
485                 }
486                 if (id_node->visible_components_mask ==
487                     id_node->previously_visible_components_mask)
488                 {
489                         /* The ID was already visible and evaluated, all the subsequent
490                          * updates and tags are to be done explicitly. */
491                         continue;
492                 }
493                 int flag = 0;
494                 if (!DEG::deg_copy_on_write_is_expanded(id_node->id_cow)) {
495                         flag |= ID_RECALC_COPY_ON_WRITE;
496                 }
497                 /* We only tag components which needs an update. Tagging everything is
498                  * not a good idea because that might reset particles cache (or any
499                  * other type of cache).
500                  *
501                  * TODO(sergey): Need to generalize this somehow. */
502                 const ID_Type id_type = GS(id_node->id_orig->name);
503                 if (id_type == ID_OB) {
504                         flag |= ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY;
505                 }
506                 graph_id_tag_update(bmain,
507                                     graph,
508                                     id_node->id_orig,
509                                     flag, DEG_UPDATE_SOURCE_VISIBILITY);
510                 if (id_type == ID_SCE) {
511                         /* Make sure collection properties are up to date. */
512                         id_node->tag_update(graph, DEG_UPDATE_SOURCE_VISIBILITY);
513                 }
514                 /* Now when ID is updated to the new visibility state, prevent it from
515                  * being re-tagged again. Simplest way to do so is to pretend that it
516                  * was already updated by the "previous" dependency graph.
517                  *
518                  * NOTE: Even if the on_visible_update() is called from the state when
519                  * dependency graph is tagged for relations update, it will be fine:
520                  * since dependency graph builder re-schedules entry tags, all the
521                  * tags we request from here will be applied in the updated state of
522                  * dependency graph. */
523                 id_node->previously_visible_components_mask =
524                         id_node->visible_components_mask;
525         }
526 }
527
528 }  /* namespace */
529
530 NodeType geometry_tag_to_component(const ID *id)
531 {
532         const ID_Type id_type = GS(id->name);
533         switch (id_type) {
534                 case ID_OB:
535                 {
536                         const Object *object = (Object *)id;
537                         switch (object->type) {
538                                 case OB_MESH:
539                                 case OB_CURVE:
540                                 case OB_SURF:
541                                 case OB_FONT:
542                                 case OB_LATTICE:
543                                 case OB_MBALL:
544                                 case OB_GPENCIL:
545                                         return NodeType::GEOMETRY;
546                                 case OB_ARMATURE:
547                                         return NodeType::EVAL_POSE;
548                                         /* TODO(sergey): More cases here? */
549                         }
550                         break;
551                 }
552                 case ID_ME:
553                 case ID_CU:
554                 case ID_LT:
555                 case ID_MB:
556                         return NodeType::GEOMETRY;
557                 case ID_PA: /* Particles */
558                         return NodeType::UNDEFINED;
559                 case ID_LP:
560                         return NodeType::PARAMETERS;
561                 case ID_GD:
562                         return NodeType::GEOMETRY;
563                 case ID_PAL: /* Palettes */
564                         return NodeType::PARAMETERS;
565                 default:
566                         break;
567         }
568         return NodeType::UNDEFINED;
569 }
570
571 void id_tag_update(Main *bmain, ID *id, int flag, eUpdateSource update_source)
572 {
573         graph_id_tag_update(bmain, NULL, id, flag, update_source);
574         LISTBASE_FOREACH (Scene *, scene, &bmain->scene) {
575                 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
576                         Depsgraph *depsgraph =
577                                 (Depsgraph *)BKE_scene_get_depsgraph(scene,
578                                                                      view_layer,
579                                                                      false);
580                         if (depsgraph != NULL) {
581                                 graph_id_tag_update(
582                                         bmain, depsgraph, id, flag, update_source);
583                         }
584                 }
585         }
586 }
587
588 void graph_id_tag_update(Main *bmain,
589                          Depsgraph *graph,
590                          ID *id,
591                          int flag,
592                          eUpdateSource update_source)
593 {
594         const int debug_flags = (graph != NULL)
595                 ? DEG_debug_flags_get((::Depsgraph *)graph)
596                 : G.debug;
597         if (debug_flags & G_DEBUG_DEPSGRAPH_TAG) {
598                 printf("%s: id=%s flags=%s source=%s\n",
599                        __func__,
600                        id->name,
601                        stringify_update_bitfield(flag).c_str(),
602                        update_source_as_string(update_source));
603         }
604         IDNode *id_node = (graph != NULL) ? graph->find_id_node(id)
605                                               : NULL;
606         DEG_id_type_tag(bmain, GS(id->name));
607         if (flag == 0) {
608                 deg_graph_node_tag_zero(bmain, graph, id_node, update_source);
609         }
610         id->recalc |= flag;
611         int current_flag = flag;
612         while (current_flag != 0) {
613                 IDRecalcFlag tag =
614                         (IDRecalcFlag)(1 << bitscan_forward_clear_i(&current_flag));
615                 graph_id_tag_update_single_flag(
616                         bmain, graph, id, id_node, tag, update_source);
617         }
618         /* Special case for nested node tree datablocks. */
619         id_tag_update_ntree_special(bmain, graph, id, flag, update_source);
620         /* Direct update tags means that something outside of simulated/cached
621          * physics did change and that cache is to be invalidated. */
622         if (update_source == DEG_UPDATE_SOURCE_USER_EDIT) {
623                 graph_id_tag_update_single_flag(
624                         bmain, graph, id, id_node, ID_RECALC_POINT_CACHE, update_source);
625         }
626 }
627
628 }  // namespace DEG
629
630 const char *DEG_update_tag_as_string(IDRecalcFlag flag)
631 {
632         switch (flag) {
633                 case ID_RECALC_TRANSFORM: return "TRANSFORM";
634                 case ID_RECALC_GEOMETRY: return "GEOMETRY";
635                 case ID_RECALC_ANIMATION: return "ANIMATION";
636                 case ID_RECALC_PSYS_REDO: return "PSYS_REDO";
637                 case ID_RECALC_PSYS_RESET: return "PSYS_RESET";
638                 case ID_RECALC_PSYS_CHILD: return "PSYS_CHILD";
639                 case ID_RECALC_PSYS_PHYS: return "PSYS_PHYS";
640                 case ID_RECALC_PSYS_ALL: return "PSYS_ALL";
641                 case ID_RECALC_COPY_ON_WRITE: return "COPY_ON_WRITE";
642                 case ID_RECALC_SHADING: return "SHADING";
643                 case ID_RECALC_SELECT: return "SELECT";
644                 case ID_RECALC_BASE_FLAGS: return "BASE_FLAGS";
645                 case ID_RECALC_POINT_CACHE: return "POINT_CACHE";
646                 case ID_RECALC_EDITORS: return "EDITORS";
647                 case ID_RECALC_ALL: return "ALL";
648         }
649         BLI_assert(!"Unhandled update flag, should never happen!");
650         return "UNKNOWN";
651 }
652
653 /* Data-Based Tagging  */
654
655 /* Tag given ID for an update in all the dependency graphs. */
656 void DEG_id_tag_update(ID *id, int flag)
657 {
658         DEG_id_tag_update_ex(G.main, id, flag);
659 }
660
661 void DEG_id_tag_update_ex(Main *bmain, ID *id, int flag)
662 {
663         if (id == NULL) {
664                 /* Ideally should not happen, but old depsgraph allowed this. */
665                 return;
666         }
667         DEG::id_tag_update(
668                 bmain, id, flag, DEG::DEG_UPDATE_SOURCE_USER_EDIT);
669 }
670
671 void DEG_graph_id_tag_update(struct Main *bmain,
672                              struct Depsgraph *depsgraph,
673                              struct ID *id,
674                              int flag)
675 {
676         DEG::Depsgraph *graph = (DEG::Depsgraph *)depsgraph;
677         DEG::graph_id_tag_update(
678                 bmain, graph, id, flag, DEG::DEG_UPDATE_SOURCE_USER_EDIT);
679 }
680
681 /* Mark a particular datablock type as having changing. */
682 void DEG_id_type_tag(Main *bmain, short id_type)
683 {
684         if (id_type == ID_NT) {
685                 /* Stupid workaround so parent datablocks of nested nodetree get looped
686                  * over when we loop over tagged datablock types. */
687                 DEG_id_type_tag(bmain, ID_MA);
688                 DEG_id_type_tag(bmain, ID_TE);
689                 DEG_id_type_tag(bmain, ID_LA);
690                 DEG_id_type_tag(bmain, ID_WO);
691                 DEG_id_type_tag(bmain, ID_SCE);
692         }
693
694         int id_type_index = BKE_idcode_to_index(id_type);
695
696         LISTBASE_FOREACH (Scene *, scene, &bmain->scene) {
697                 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
698                         Depsgraph *depsgraph =
699                                 (Depsgraph *)BKE_scene_get_depsgraph(scene,
700                                                                      view_layer,
701                                                                      false);
702                         if (depsgraph != NULL) {
703                                 DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(depsgraph);
704                                 deg_graph->id_type_updated[id_type_index] = 1;
705                         }
706                 }
707         }
708 }
709
710 void DEG_graph_flush_update(Main *bmain, Depsgraph *depsgraph)
711 {
712         if (depsgraph == NULL) {
713                 return;
714         }
715         DEG::deg_graph_flush_updates(bmain, (DEG::Depsgraph *)depsgraph);
716 }
717
718 /* Update dependency graph when visible scenes/layers changes. */
719 void DEG_graph_on_visible_update(Main *bmain, Depsgraph *depsgraph)
720 {
721         DEG::Depsgraph *graph = (DEG::Depsgraph *)depsgraph;
722         DEG::deg_graph_on_visible_update(bmain, graph);
723 }
724
725 void DEG_on_visible_update(Main *bmain, const bool UNUSED(do_time))
726 {
727         LISTBASE_FOREACH (Scene *, scene, &bmain->scene) {
728                 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
729                         Depsgraph *depsgraph =
730                                 (Depsgraph *)BKE_scene_get_depsgraph(scene,
731                                                                      view_layer,
732                                                                      false);
733                         if (depsgraph != NULL) {
734                                 DEG_graph_on_visible_update(bmain, depsgraph);
735                         }
736                 }
737         }
738 }
739
740 /* Check if something was changed in the database and inform
741  * editors about this. */
742 void DEG_ids_check_recalc(Main *bmain,
743                           Depsgraph *depsgraph,
744                           Scene *scene,
745                           ViewLayer *view_layer,
746                           bool time)
747 {
748         bool updated = time || DEG_id_type_any_updated(depsgraph);
749
750         DEGEditorUpdateContext update_ctx = {NULL};
751         update_ctx.bmain = bmain;
752         update_ctx.depsgraph = depsgraph;
753         update_ctx.scene = scene;
754         update_ctx.view_layer = view_layer;
755         DEG::deg_editors_scene_update(&update_ctx, updated);
756 }
757
758 static void deg_graph_clear_id_node_func(
759         void *__restrict data_v,
760         const int i,
761         const ParallelRangeTLS *__restrict /*tls*/)
762 {
763         /* TODO: we clear original ID recalc flags here, but this may not work
764          * correctly when there are multiple depsgraph with others still using
765          * the recalc flag. */
766         DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(data_v);
767         DEG::IDNode *id_node = deg_graph->id_nodes[i];
768         id_node->id_cow->recalc &= ~ID_RECALC_ALL;
769         id_node->id_orig->recalc &= ~ID_RECALC_ALL;
770
771         /* Clear embedded node trees too. */
772         bNodeTree *ntree_cow = ntreeFromID(id_node->id_cow);
773         if (ntree_cow) {
774                 ntree_cow->id.recalc &= ~ID_RECALC_ALL;
775         }
776         bNodeTree *ntree_orig = ntreeFromID(id_node->id_orig);
777         if (ntree_orig) {
778                 ntree_orig->id.recalc &= ~ID_RECALC_ALL;
779         }
780 }
781
782 void DEG_ids_clear_recalc(Main *UNUSED(bmain),
783                           Depsgraph *depsgraph)
784 {
785         DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(depsgraph);
786         /* TODO(sergey): Re-implement POST_UPDATE_HANDLER_WORKAROUND using entry_tags
787          * and id_tags storage from the new dependency graph. */
788         if (!DEG_id_type_any_updated(depsgraph)) {
789                 return;
790         }
791         /* Go over all ID nodes nodes, clearing tags. */
792         const int num_id_nodes = deg_graph->id_nodes.size();
793         ParallelRangeSettings settings;
794         BLI_parallel_range_settings_defaults(&settings);
795         settings.min_iter_per_thread = 1024;
796         BLI_task_parallel_range(0, num_id_nodes,
797                                 deg_graph,
798                                 deg_graph_clear_id_node_func,
799                                 &settings);
800         memset(deg_graph->id_type_updated, 0, sizeof(deg_graph->id_type_updated));
801 }