Rename any instance of scene layer or render layer in code with view layer
[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 #include "DNA_object_types.h"
42
43 #include "DEG_depsgraph.h"
44 #include "DEG_depsgraph_query.h"
45
46 #include "atomic_ops.h"
47
48 #include "intern/eval/deg_eval_flush.h"
49 #include "intern/nodes/deg_node.h"
50 #include "intern/nodes/deg_node_component.h"
51 #include "intern/nodes/deg_node_operation.h"
52 #include "intern/depsgraph.h"
53 #include "intern/depsgraph_intern.h"
54 #include "util/deg_util_foreach.h"
55
56 /* Unfinished and unused, and takes quite some pre-processing time. */
57 #undef USE_EVAL_PRIORITY
58
59 /* Use integrated debugger to keep track how much each of the nodes was
60  * evaluating.
61  */
62 #undef USE_DEBUGGER
63
64 namespace DEG {
65
66 /* ********************** */
67 /* Evaluation Entrypoints */
68
69 /* Forward declarations. */
70 static void schedule_children(TaskPool *pool,
71                               Depsgraph *graph,
72                               OperationDepsNode *node,
73                               const int thread_id);
74
75 struct DepsgraphEvalState {
76         EvaluationContext *eval_ctx;
77         Depsgraph *graph;
78 };
79
80 static void deg_task_run_func(TaskPool *pool,
81                               void *taskdata,
82                               int thread_id)
83 {
84         DepsgraphEvalState *state =
85                 reinterpret_cast<DepsgraphEvalState *>(BLI_task_pool_userdata(pool));
86         OperationDepsNode *node = reinterpret_cast<OperationDepsNode *>(taskdata);
87
88         BLI_assert(!node->is_noop() && "NOOP nodes should not actually be scheduled");
89
90         /* Should only be the case for NOOPs, which never get to this point. */
91         BLI_assert(node->evaluate);
92
93         /* Get context. */
94         /* TODO: Who initialises this? "Init" operations aren't able to
95          * initialise it!!!
96          */
97         /* TODO(sergey): We don't use component contexts at this moment. */
98         /* ComponentDepsNode *comp = node->owner; */
99         BLI_assert(node->owner != NULL);
100
101         /* Since we're not leaving the thread for until the graph branches it is
102          * possible to have NO-OP on the way. for which evaluate() will be NULL.
103          * but that's all fine, we'll just scheduler it's children.
104          */
105         if (node->evaluate) {
106                         /* Take note of current time. */
107 #ifdef USE_DEBUGGER
108                 double start_time = PIL_check_seconds_timer();
109                 DepsgraphDebug::task_started(state->graph, node);
110 #endif
111
112                 /* Perform operation. */
113                 node->evaluate(state->eval_ctx);
114
115                         /* Note how long this took. */
116 #ifdef USE_DEBUGGER
117                 double end_time = PIL_check_seconds_timer();
118                 DepsgraphDebug::task_completed(state->graph,
119                                                node,
120                                                end_time - start_time);
121 #endif
122         }
123
124         BLI_task_pool_delayed_push_begin(pool, thread_id);
125         schedule_children(pool, state->graph, node, thread_id);
126         BLI_task_pool_delayed_push_end(pool, thread_id);
127 }
128
129 typedef struct CalculatePengindData {
130         Depsgraph *graph;
131 } CalculatePengindData;
132
133 static void calculate_pending_func(void *data_v, int i)
134 {
135         CalculatePengindData *data = (CalculatePengindData *)data_v;
136         Depsgraph *graph = data->graph;
137         OperationDepsNode *node = graph->operations[i];
138
139         node->num_links_pending = 0;
140         node->scheduled = false;
141
142         /* count number of inputs that need updates */
143         if ((node->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0) {
144                 foreach (DepsRelation *rel, node->inlinks) {
145                         if (rel->from->type == DEG_NODE_TYPE_OPERATION &&
146                             (rel->flag & DEPSREL_FLAG_CYCLIC) == 0)
147                         {
148                                 OperationDepsNode *from = (OperationDepsNode *)rel->from;
149                                 if ((from->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0) {
150                                         ++node->num_links_pending;
151                                 }
152                         }
153                 }
154         }
155 }
156
157 static void calculate_pending_parents(Depsgraph *graph)
158 {
159         const int num_operations = graph->operations.size();
160         const bool do_threads = num_operations > 256;
161         CalculatePengindData data;
162         data.graph = graph;
163         BLI_task_parallel_range(0,
164                                 num_operations,
165                                 &data,
166                                 calculate_pending_func,
167                                 do_threads);
168 }
169
170 #ifdef USE_EVAL_PRIORITY
171 static void calculate_eval_priority(OperationDepsNode *node)
172 {
173         if (node->done) {
174                 return;
175         }
176         node->done = 1;
177
178         if (node->flag & DEPSOP_FLAG_NEEDS_UPDATE) {
179                 /* XXX standard cost of a node, could be estimated somewhat later on */
180                 const float cost = 1.0f;
181                 /* NOOP nodes have no cost */
182                 node->eval_priority = node->is_noop() ? cost : 0.0f;
183
184                 foreach (DepsRelation *rel, node->outlinks) {
185                         OperationDepsNode *to = (OperationDepsNode *)rel->to;
186                         BLI_assert(to->type == DEG_NODE_TYPE_OPERATION);
187                         calculate_eval_priority(to);
188                         node->eval_priority += to->eval_priority;
189                 }
190         }
191         else {
192                 node->eval_priority = 0.0f;
193         }
194 }
195 #endif
196
197 /* Schedule a node if it needs evaluation.
198  *   dec_parents: Decrement pending parents count, true when child nodes are
199  *                scheduled after a task has been completed.
200  */
201 static void schedule_node(TaskPool *pool, Depsgraph *graph,
202                           OperationDepsNode *node, bool dec_parents,
203                           const int thread_id)
204 {
205         if ((node->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0) {
206                 if (dec_parents) {
207                         BLI_assert(node->num_links_pending > 0);
208                         atomic_sub_and_fetch_uint32(&node->num_links_pending, 1);
209                 }
210
211                 if (node->num_links_pending == 0) {
212                         bool is_scheduled = atomic_fetch_and_or_uint8(
213                                 (uint8_t *)&node->scheduled, (uint8_t)true);
214                         if (!is_scheduled) {
215                                 if (node->is_noop()) {
216                                         /* skip NOOP node, schedule children right away */
217                                         schedule_children(pool, graph, node, thread_id);
218                                 }
219                                 else {
220                                         /* children are scheduled once this task is completed */
221                                         BLI_task_pool_push_from_thread(pool,
222                                                                        deg_task_run_func,
223                                                                        node,
224                                                                        false,
225                                                                        TASK_PRIORITY_HIGH,
226                                                                        thread_id);
227                                 }
228                         }
229                 }
230         }
231 }
232
233 static void schedule_graph(TaskPool *pool, Depsgraph *graph)
234 {
235         foreach (OperationDepsNode *node, graph->operations) {
236                 schedule_node(pool, graph, node, false, 0);
237         }
238 }
239
240 static void schedule_children(TaskPool *pool,
241                               Depsgraph *graph,
242                               OperationDepsNode *node,
243                               const int thread_id)
244 {
245         foreach (DepsRelation *rel, node->outlinks) {
246                 OperationDepsNode *child = (OperationDepsNode *)rel->to;
247                 BLI_assert(child->type == DEG_NODE_TYPE_OPERATION);
248                 if (child->scheduled) {
249                         /* Happens when having cyclic dependencies. */
250                         continue;
251                 }
252                 schedule_node(pool,
253                               graph,
254                               child,
255                               (rel->flag & DEPSREL_FLAG_CYCLIC) == 0,
256                               thread_id);
257         }
258 }
259
260 /**
261  * Evaluate all nodes tagged for updating,
262  * \warning This is usually done as part of main loop, but may also be
263  * called from frame-change update.
264  *
265  * \note Time sources should be all valid!
266  */
267 void deg_evaluate_on_refresh(EvaluationContext *eval_ctx,
268                              Depsgraph *graph)
269 {
270         /* Generate base evaluation context, upon which all the others are derived. */
271         // TODO: this needs both main and scene access...
272
273         /* Nothing to update, early out. */
274         if (BLI_gset_size(graph->entry_tags) == 0) {
275                 return;
276         }
277
278         /* Set time for the current graph evaluation context. */
279         TimeSourceDepsNode *time_src = graph->find_time_source();
280         eval_ctx->depsgraph = (::Depsgraph *)graph;
281         eval_ctx->view_layer = DEG_get_evaluated_view_layer((::Depsgraph *)graph);
282         eval_ctx->ctime = time_src->cfra;
283
284         /* XXX could use a separate pool for each eval context */
285         DepsgraphEvalState state;
286         state.eval_ctx = eval_ctx;
287         state.graph = graph;
288
289         TaskScheduler *task_scheduler;
290         bool need_free_scheduler;
291
292         if (G.debug & G_DEBUG_DEPSGRAPH_NO_THREADS) {
293                 task_scheduler = BLI_task_scheduler_create(1);
294                 need_free_scheduler = true;
295         }
296         else {
297                 task_scheduler = BLI_task_scheduler_get();
298                 need_free_scheduler = false;
299         }
300
301         TaskPool *task_pool = BLI_task_pool_create_suspended(task_scheduler, &state);
302
303         calculate_pending_parents(graph);
304
305         /* Clear tags. */
306         foreach (OperationDepsNode *node, graph->operations) {
307                 node->done = 0;
308         }
309
310         /* Calculate priority for operation nodes. */
311 #ifdef USE_EVAL_PRIORITY
312         foreach (OperationDepsNode *node, graph->operations) {
313                 calculate_eval_priority(node);
314         }
315 #endif
316
317         schedule_graph(task_pool, graph);
318
319         BLI_task_pool_work_and_wait(task_pool);
320         BLI_task_pool_free(task_pool);
321
322         /* Clear any uncleared tags - just in case. */
323         deg_graph_clear_tags(graph);
324
325         if (need_free_scheduler) {
326                 BLI_task_scheduler_free(task_scheduler);
327         }
328 }
329
330 }  // namespace DEG