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