Depsgraph: initialize EvaluationContext even if nothing to update
[blender.git] / source / blender / depsgraph / intern / eval / deg_eval.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.cc
28  *  \ingroup depsgraph
29  *
30  * Evaluation engine entrypoints for Depsgraph Engine.
31  */
32
33 #include "intern/eval/deg_eval.h"
34
35 #include "PIL_time.h"
36
37 #include "BLI_utildefines.h"
38 #include "BLI_task.h"
39 #include "BLI_ghash.h"
40
41 extern "C" {
42 #include "BKE_depsgraph.h"
43 #include "BKE_global.h"
44 } /* extern "C" */
45
46 #include "DEG_depsgraph.h"
47
48 #include "atomic_ops.h"
49
50 #include "intern/eval/deg_eval_flush.h"
51 #include "intern/eval/deg_eval_stats.h"
52 #include "intern/nodes/deg_node.h"
53 #include "intern/nodes/deg_node_component.h"
54 #include "intern/nodes/deg_node_id.h"
55 #include "intern/nodes/deg_node_operation.h"
56 #include "intern/nodes/deg_node_time.h"
57 #include "intern/depsgraph.h"
58 #include "intern/depsgraph_intern.h"
59
60 #include "util/deg_util_foreach.h"
61
62 namespace DEG {
63
64 /* ********************** */
65 /* Evaluation Entrypoints */
66
67 /* Forward declarations. */
68 static void schedule_children(TaskPool *pool,
69                               Depsgraph *graph,
70                               OperationDepsNode *node,
71                               const unsigned int layers,
72                               const int thread_id);
73
74 struct DepsgraphEvalState {
75         EvaluationContext *eval_ctx;
76         Depsgraph *graph;
77         unsigned int layers;
78         bool do_stats;
79 };
80
81 static void deg_task_run_func(TaskPool *pool,
82                               void *taskdata,
83                               int thread_id)
84 {
85         void *userdata_v = BLI_task_pool_userdata(pool);
86         DepsgraphEvalState *state = (DepsgraphEvalState *)userdata_v;
87         OperationDepsNode *node = (OperationDepsNode *)taskdata;
88         /* Sanity checks. */
89         BLI_assert(!node->is_noop() && "NOOP nodes should not actually be scheduled");
90         /* Perform operation. */
91         if (state->do_stats) {
92                 const double start_time = PIL_check_seconds_timer();
93                 node->evaluate(state->eval_ctx);
94                 node->stats.current_time += PIL_check_seconds_timer() - start_time;
95         }
96         else {
97                 node->evaluate(state->eval_ctx);
98         }
99         /* Schedule children. */
100         BLI_task_pool_delayed_push_begin(pool, thread_id);
101         schedule_children(pool, state->graph, node, state->layers, thread_id);
102         BLI_task_pool_delayed_push_end(pool, thread_id);
103 }
104
105 typedef struct CalculatePengindData {
106         Depsgraph *graph;
107         unsigned int layers;
108 } CalculatePengindData;
109
110 static void calculate_pending_func(
111         void *__restrict data_v,
112         const int i,
113         const ParallelRangeTLS *__restrict /*tls*/)
114 {
115         CalculatePengindData *data = (CalculatePengindData *)data_v;
116         Depsgraph *graph = data->graph;
117         unsigned int layers = data->layers;
118         OperationDepsNode *node = graph->operations[i];
119         IDDepsNode *id_node = node->owner->owner;
120
121         node->num_links_pending = 0;
122         node->scheduled = false;
123
124         /* count number of inputs that need updates */
125         if ((id_node->layers & layers) != 0 &&
126             (node->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0)
127         {
128                 foreach (DepsRelation *rel, node->inlinks) {
129                         if (rel->from->type == DEG_NODE_TYPE_OPERATION &&
130                             (rel->flag & DEPSREL_FLAG_CYCLIC) == 0)
131                         {
132                                 OperationDepsNode *from = (OperationDepsNode *)rel->from;
133                                 IDDepsNode *id_from_node = from->owner->owner;
134                                 if ((id_from_node->layers & layers) != 0 &&
135                                     (from->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0)
136                                 {
137                                         ++node->num_links_pending;
138                                 }
139                         }
140                 }
141         }
142 }
143
144 static void calculate_pending_parents(Depsgraph *graph, unsigned int layers)
145 {
146         const int num_operations = graph->operations.size();
147         CalculatePengindData data;
148         data.graph = graph;
149         data.layers = layers;
150         ParallelRangeSettings settings;
151         BLI_parallel_range_settings_defaults(&settings);
152         settings.min_iter_per_thread = 1024;
153         BLI_task_parallel_range(0,
154                                 num_operations,
155                                 &data,
156                                 calculate_pending_func,
157                                 &settings);
158 }
159
160 static void initialize_execution(DepsgraphEvalState *state, Depsgraph *graph)
161 {
162         const bool do_stats = state->do_stats;
163         calculate_pending_parents(graph, state->layers);
164         /* Clear tags and other things which needs to be clear. */
165         foreach (OperationDepsNode *node, graph->operations) {
166                 node->done = 0;
167                 if (do_stats) {
168                         node->stats.reset_current();
169                 }
170         }
171 }
172
173 /* Schedule a node if it needs evaluation.
174  *   dec_parents: Decrement pending parents count, true when child nodes are
175  *                scheduled after a task has been completed.
176  */
177 static void schedule_node(TaskPool *pool, Depsgraph *graph, unsigned int layers,
178                           OperationDepsNode *node, bool dec_parents,
179                           const int thread_id)
180 {
181         unsigned int id_layers = node->owner->owner->layers;
182
183         if ((node->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0 &&
184             (id_layers & layers) != 0)
185         {
186                 if (dec_parents) {
187                         BLI_assert(node->num_links_pending > 0);
188                         atomic_sub_and_fetch_uint32(&node->num_links_pending, 1);
189                 }
190
191                 if (node->num_links_pending == 0) {
192                         bool is_scheduled = atomic_fetch_and_or_uint8(
193                                 (uint8_t *)&node->scheduled, (uint8_t)true);
194                         if (!is_scheduled) {
195                                 if (node->is_noop()) {
196                                         /* skip NOOP node, schedule children right away */
197                                         schedule_children(pool, graph, node, layers, thread_id);
198                                 }
199                                 else {
200                                         /* children are scheduled once this task is completed */
201                                         BLI_task_pool_push_from_thread(pool,
202                                                                        deg_task_run_func,
203                                                                        node,
204                                                                        false,
205                                                                        TASK_PRIORITY_HIGH,
206                                                                        thread_id);
207                                 }
208                         }
209                 }
210         }
211 }
212
213 static void schedule_graph(TaskPool *pool,
214                            Depsgraph *graph,
215                            const unsigned int layers)
216 {
217         foreach (OperationDepsNode *node, graph->operations) {
218                 schedule_node(pool, graph, layers, node, false, 0);
219         }
220 }
221
222 static void schedule_children(TaskPool *pool,
223                               Depsgraph *graph,
224                               OperationDepsNode *node,
225                               const unsigned int layers,
226                               const int thread_id)
227 {
228         foreach (DepsRelation *rel, node->outlinks) {
229                 OperationDepsNode *child = (OperationDepsNode *)rel->to;
230                 BLI_assert(child->type == DEG_NODE_TYPE_OPERATION);
231                 if (child->scheduled) {
232                         /* Happens when having cyclic dependencies. */
233                         continue;
234                 }
235                 schedule_node(pool,
236                               graph,
237                               layers,
238                               child,
239                               (rel->flag & DEPSREL_FLAG_CYCLIC) == 0,
240                               thread_id);
241         }
242 }
243
244 /**
245  * Evaluate all nodes tagged for updating,
246  * \warning This is usually done as part of main loop, but may also be
247  * called from frame-change update.
248  *
249  * \note Time sources should be all valid!
250  */
251 void deg_evaluate_on_refresh(EvaluationContext *eval_ctx,
252                              Depsgraph *graph,
253                              const unsigned int layers)
254 {
255         /* Set time for the current graph evaluation context. */
256         TimeSourceDepsNode *time_src = graph->find_time_source();
257         eval_ctx->ctime = time_src->cfra;
258         /* Nothing to update, early out. */
259         if (BLI_gset_len(graph->entry_tags) == 0) {
260                 return;
261         }
262         DEG_DEBUG_PRINTF(EVAL, "%s: layers:%u, graph->layers:%u\n",
263                          __func__,
264                          layers,
265                          graph->layers);
266         const bool do_time_debug = ((G.debug & G_DEBUG_DEPSGRAPH_TIME) != 0);
267         const double start_time = do_time_debug ? PIL_check_seconds_timer() : 0;
268         /* Set up evaluation context for depsgraph itself. */
269         DepsgraphEvalState state;
270         state.eval_ctx = eval_ctx;
271         state.graph = graph;
272         state.layers = layers;
273         state.do_stats = do_time_debug;
274         /* Set up task scheduler and pull for threaded evaluation. */
275         TaskScheduler *task_scheduler;
276         bool need_free_scheduler;
277         if (G.debug & G_DEBUG_DEPSGRAPH_NO_THREADS) {
278                 task_scheduler = BLI_task_scheduler_create(1);
279                 need_free_scheduler = true;
280         }
281         else {
282                 task_scheduler = BLI_task_scheduler_get();
283                 need_free_scheduler = false;
284         }
285         TaskPool *task_pool = BLI_task_pool_create_suspended(task_scheduler, &state);
286         /* Prepare all nodes for evaluation. */
287         initialize_execution(&state, graph);
288         /* Do actual evaluation now. */
289         schedule_graph(task_pool, graph, layers);
290         BLI_task_pool_work_and_wait(task_pool);
291         BLI_task_pool_free(task_pool);
292         /* Finalize statistics gathering. This is because we only gather single
293          * operation timing here, without aggregating anything to avoid any extra
294          * synchronization.
295          */
296         if (state.do_stats) {
297                 deg_eval_stats_aggregate(graph);
298         }
299         /* Clear any uncleared tags - just in case. */
300         deg_graph_clear_tags(graph);
301         if (need_free_scheduler) {
302                 BLI_task_scheduler_free(task_scheduler);
303         }
304         if (do_time_debug) {
305                 printf("Depsgraph updated in %f seconds.\n",
306                        PIL_check_seconds_timer() - start_time);
307         }
308 }
309
310 }  // namespace DEG