Merge branch 'master' into blender2.8
[blender.git] / source / blender / depsgraph / intern / eval / deg_eval_flush.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/eval/deg_eval_flush.cc
28  *  \ingroup depsgraph
29  *
30  * Core routines for how the Depsgraph works.
31  */
32
33 #include "intern/eval/deg_eval_flush.h"
34
35 // TODO(sergey): Use some sort of wrapper.
36 #include <deque>
37
38 #include "BLI_utildefines.h"
39 #include "BLI_listbase.h"
40 #include "BLI_task.h"
41 #include "BLI_ghash.h"
42
43 extern "C" {
44 #include "DNA_object_types.h"
45 } /* extern "C" */
46
47 #include "DEG_depsgraph.h"
48
49 #include "intern/nodes/deg_node.h"
50 #include "intern/nodes/deg_node_component.h"
51 #include "intern/nodes/deg_node_id.h"
52 #include "intern/nodes/deg_node_operation.h"
53
54 #include "intern/depsgraph_intern.h"
55 #include "intern/eval/deg_eval_copy_on_write.h"
56 #include "util/deg_util_foreach.h"
57
58 namespace DEG {
59
60 enum {
61         ID_STATE_NONE     = 0,
62         ID_STATE_MODIFIED = 1,
63 };
64
65 enum {
66         COMPONENT_STATE_NONE      = 0,
67         COMPONENT_STATE_SCHEDULED = 1,
68         COMPONENT_STATE_DONE      = 2,
69 };
70
71 typedef std::deque<OperationDepsNode *> FlushQueue;
72
73 namespace {
74
75 void flush_init_operation_node_func(
76         void *__restrict data_v,
77         const int i,
78         const ParallelRangeTLS *__restrict /*tls*/)
79 {
80         Depsgraph *graph = (Depsgraph *)data_v;
81         OperationDepsNode *node = graph->operations[i];
82         node->scheduled = false;
83 }
84
85 void flush_init_id_node_func(
86         void *__restrict data_v,
87         const int i,
88         const ParallelRangeTLS *__restrict /*tls*/)
89 {
90         Depsgraph *graph = (Depsgraph *)data_v;
91         IDDepsNode *id_node = graph->id_nodes[i];
92         id_node->done = ID_STATE_NONE;
93         GHASH_FOREACH_BEGIN(ComponentDepsNode *, comp_node, id_node->components)
94                 comp_node->done = COMPONENT_STATE_NONE;
95         GHASH_FOREACH_END();
96 }
97
98 BLI_INLINE void flush_prepare(Depsgraph *graph)
99 {
100         {
101                 const int num_operations = graph->operations.size();
102                 ParallelRangeSettings settings;
103                 BLI_parallel_range_settings_defaults(&settings);
104                 settings.min_iter_per_thread = 1024;
105                 BLI_task_parallel_range(0, num_operations,
106                                         graph,
107                                         flush_init_operation_node_func,
108                                         &settings);
109         }
110         {
111                 const int num_id_nodes = graph->id_nodes.size();
112                 ParallelRangeSettings settings;
113                 BLI_parallel_range_settings_defaults(&settings);
114                 settings.min_iter_per_thread = 1024;
115                 BLI_task_parallel_range(0, num_id_nodes,
116                                         graph,
117                                         flush_init_id_node_func,
118                                         &settings);
119         }
120 }
121
122 BLI_INLINE void flush_schedule_entrypoints(Depsgraph *graph, FlushQueue *queue)
123 {
124         GSET_FOREACH_BEGIN(OperationDepsNode *, op_node, graph->entry_tags)
125         {
126                 queue->push_back(op_node);
127                 op_node->scheduled = true;
128         }
129         GSET_FOREACH_END();
130 }
131
132 BLI_INLINE void flush_handle_id_node(IDDepsNode *id_node)
133 {
134         id_node->done = ID_STATE_MODIFIED;
135 }
136
137 /* TODO(sergey): We can reduce number of arguments here. */
138 BLI_INLINE void flush_handle_component_node(IDDepsNode *id_node,
139                                             ComponentDepsNode *comp_node,
140                                             FlushQueue *queue)
141 {
142         /* We only handle component once. */
143         if (comp_node->done == COMPONENT_STATE_DONE) {
144                 return;
145         }
146         comp_node->done = COMPONENT_STATE_DONE;
147         /* Tag all required operations in component for update.  */
148         foreach (OperationDepsNode *op, comp_node->operations) {
149                 /* We don't want to flush tags in "upstream" direction for
150                  * certain types of operations.
151                  *
152                  * TODO(sergey): Need a more generic solution for this.
153                  */
154                 if (op->opcode == DEG_OPCODE_PARTICLE_SETTINGS_EVAL) {
155                         continue;
156                 }
157                 op->flag |= DEPSOP_FLAG_NEEDS_UPDATE;
158         }
159         /* when some target changes bone, we might need to re-run the
160          * whole IK solver, otherwise result might be unpredictable.
161          */
162         if (comp_node->type == DEG_NODE_TYPE_BONE) {
163                 ComponentDepsNode *pose_comp =
164                         id_node->find_component(DEG_NODE_TYPE_EVAL_POSE);
165                 BLI_assert(pose_comp != NULL);
166                 if (pose_comp->done == COMPONENT_STATE_NONE) {
167                         queue->push_front(pose_comp->get_entry_operation());
168                         pose_comp->done = COMPONENT_STATE_SCHEDULED;
169                 }
170         }
171 }
172
173 /* Schedule children of the given operation node for traversal.
174  *
175  * One of the children will by-pass the queue and will be returned as a function
176  * return value, so it can start being handled right away, without building too
177  * much of a queue.
178  */
179 BLI_INLINE OperationDepsNode *flush_schedule_children(
180         OperationDepsNode *op_node,
181         FlushQueue *queue)
182 {
183         OperationDepsNode *result = NULL;
184         foreach (DepsRelation *rel, op_node->outlinks) {
185                 if (rel->flag & DEPSREL_FLAG_NO_FLUSH) {
186                         continue;
187                 }
188                 OperationDepsNode *to_node = (OperationDepsNode *)rel->to;
189                 if (to_node->scheduled == false) {
190                         if (result != NULL) {
191                                 queue->push_front(to_node);
192                         }
193                         else {
194                                 result = to_node;
195                         }
196                         to_node->scheduled = true;
197                 }
198         }
199         return result;
200 }
201
202 void flush_engine_data_update(ID *id)
203 {
204         if (GS(id->name) != ID_OB) {
205                 return;
206         }
207         Object *object = (Object *)id;
208         LISTBASE_FOREACH(ObjectEngineData *, engine_data, &object->drawdata) {
209                 engine_data->recalc |= id->recalc;
210         }
211 }
212
213 /* NOTE: It will also accumulate flags from changed components. */
214 void flush_editors_id_update(Main *bmain,
215                              Depsgraph *graph,
216                              const DEGEditorUpdateContext *update_ctx)
217 {
218         foreach (IDDepsNode *id_node, graph->id_nodes) {
219                 if (id_node->done != ID_STATE_MODIFIED) {
220                         continue;
221                 }
222                 DEG_id_type_tag(bmain, GS(id_node->id_orig->name));
223                 /* TODO(sergey): Do we need to pass original or evaluated ID here? */
224                 ID *id_orig = id_node->id_orig;
225                 ID *id_cow = id_node->id_cow;
226                 /* Copy tag from original data to CoW storage.
227                  * This is because DEG_id_tag_update() sets tags on original
228                  * data.
229                  */
230                 id_cow->recalc |= (id_orig->recalc & ID_RECALC_ALL);
231                 /* Gather recalc flags from all changed components. */
232                 GHASH_FOREACH_BEGIN(ComponentDepsNode *, comp_node, id_node->components)
233                 {
234                         if (comp_node->done != COMPONENT_STATE_DONE) {
235                                 continue;
236                         }
237                         DepsNodeFactory *factory = deg_type_get_factory(comp_node->type);
238                         BLI_assert(factory != NULL);
239                         id_cow->recalc |= factory->id_recalc_tag();
240                 }
241                 GHASH_FOREACH_END();
242                 DEG_DEBUG_PRINTF(EVAL, "Accumulated recalc bits for %s: %u\n",
243                                  id_orig->name, (unsigned int)id_cow->recalc);
244                 /* Inform editors. */
245                 if (deg_copy_on_write_is_expanded(id_cow)) {
246                         deg_editors_id_update(update_ctx, id_cow);
247                         /* ID may need to get its auto-override operations refreshed. */
248                         if (ID_IS_STATIC_OVERRIDE_AUTO(id_orig)) {
249                                 id_orig->tag |= LIB_TAG_OVERRIDESTATIC_AUTOREFRESH;
250                         }
251                         /* Inform draw engines that something was changed. */
252                         flush_engine_data_update(id_cow);
253                 }
254         }
255 }
256
257 }  // namespace
258
259 /* Flush updates from tagged nodes outwards until all affected nodes
260  * are tagged.
261  */
262 void deg_graph_flush_updates(Main *bmain, Depsgraph *graph)
263 {
264         /* Sanity checks. */
265         BLI_assert(bmain != NULL);
266         BLI_assert(graph != NULL);
267         /* Nothing to update, early out. */
268         if (BLI_gset_len(graph->entry_tags) == 0) {
269                 return;
270         }
271         /* Reset all flags, get ready for the flush. */
272         flush_prepare(graph);
273         /* Starting from the tagged "entry" nodes, flush outwards. */
274         FlushQueue queue;
275         flush_schedule_entrypoints(graph, &queue);
276         /* Prepare update context for editors. */
277         DEGEditorUpdateContext update_ctx;
278         update_ctx.bmain = bmain;
279         update_ctx.depsgraph = (::Depsgraph *)graph;
280         update_ctx.scene = graph->scene;
281         update_ctx.view_layer = graph->view_layer;
282         /* Do actual flush. */
283         while (!queue.empty()) {
284                 OperationDepsNode *op_node = queue.front();
285                 queue.pop_front();
286                 while (op_node != NULL) {
287                         /* Tag operation as required for update. */
288                         op_node->flag |= DEPSOP_FLAG_NEEDS_UPDATE;
289                         /* Inform corresponding ID and component nodes about the change. */
290                         ComponentDepsNode *comp_node = op_node->owner;
291                         IDDepsNode *id_node = comp_node->owner;
292                         flush_handle_id_node(id_node);
293                         flush_handle_component_node(id_node,
294                                                     comp_node,
295                                                     &queue);
296                         /* Flush to nodes along links. */
297                         op_node = flush_schedule_children(op_node, &queue);
298                 }
299         }
300         /* Inform editors about all changes. */
301         flush_editors_id_update(bmain, graph, &update_ctx);
302 }
303
304 static void graph_clear_func(
305         void *__restrict data_v,
306         const int i,
307         const ParallelRangeTLS *__restrict /*tls*/)
308 {
309         Depsgraph *graph = (Depsgraph *)data_v;
310         OperationDepsNode *node = graph->operations[i];
311         /* Clear node's "pending update" settings. */
312         node->flag &= ~(DEPSOP_FLAG_DIRECTLY_MODIFIED | DEPSOP_FLAG_NEEDS_UPDATE);
313 }
314
315 /* Clear tags from all operation nodes. */
316 void deg_graph_clear_tags(Depsgraph *graph)
317 {
318         /* Go over all operation nodes, clearing tags. */
319         const int num_operations = graph->operations.size();
320         ParallelRangeSettings settings;
321         BLI_parallel_range_settings_defaults(&settings);
322         settings.min_iter_per_thread = 1024;
323         BLI_task_parallel_range(0, num_operations,
324                                 graph,
325                                 graph_clear_func,
326                                 &settings);
327         /* Clear any entry tags which haven't been flushed. */
328         BLI_gset_clear(graph->entry_tags, NULL);
329 }
330
331 }  // namespace DEG