diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2017-12-21 18:36:02 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2017-12-21 18:36:02 +0300 |
commit | 103dd660573bb77b8917387bb2773a96de56fb38 (patch) | |
tree | ae8799b3f30fa2c04907efe5464542e3b69a705d /source/blender/depsgraph/intern/eval/deg_eval.cc | |
parent | b38c0832596bee85cf88a62a1eb29e365dbcf99d (diff) | |
parent | 885bb5b137b5ea71869b741e6ee7acc1602ab5c6 (diff) |
Merge branch 'master' into blender2.8
Diffstat (limited to 'source/blender/depsgraph/intern/eval/deg_eval.cc')
-rw-r--r-- | source/blender/depsgraph/intern/eval/deg_eval.cc | 83 |
1 files changed, 40 insertions, 43 deletions
diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc index 583261024ee..ee58a3b02a5 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval.cc @@ -46,6 +46,7 @@ #include "atomic_ops.h" #include "intern/eval/deg_eval_flush.h" +#include "intern/eval/deg_eval_stats.h" #include "intern/nodes/deg_node.h" #include "intern/nodes/deg_node_component.h" #include "intern/nodes/deg_node_id.h" @@ -70,38 +71,28 @@ static void schedule_children(TaskPool *pool, struct DepsgraphEvalState { EvaluationContext *eval_ctx; Depsgraph *graph; + bool do_stats; }; static void deg_task_run_func(TaskPool *pool, void *taskdata, int thread_id) { - DepsgraphEvalState *state = - reinterpret_cast<DepsgraphEvalState *>(BLI_task_pool_userdata(pool)); - OperationDepsNode *node = reinterpret_cast<OperationDepsNode *>(taskdata); - + void *userdata_v = BLI_task_pool_userdata(pool); + DepsgraphEvalState *state = (DepsgraphEvalState *)userdata_v; + OperationDepsNode *node = (OperationDepsNode *)taskdata; + /* Sanity checks. */ BLI_assert(!node->is_noop() && "NOOP nodes should not actually be scheduled"); - - /* Should only be the case for NOOPs, which never get to this point. */ - BLI_assert(node->evaluate); - - /* Get context. */ - /* TODO: Who initialises this? "Init" operations aren't able to - * initialise it!!! - */ - /* TODO(sergey): We don't use component contexts at this moment. */ - /* ComponentDepsNode *comp = node->owner; */ - BLI_assert(node->owner != NULL); - - /* Since we're not leaving the thread for until the graph branches it is - * possible to have NO-OP on the way. for which evaluate() will be NULL. - * but that's all fine, we'll just scheduler it's children. - */ - if (node->evaluate) { - /* Perform operation. */ + /* Perform operation. */ + if (state->do_stats) { + const double start_time = PIL_check_seconds_timer(); node->evaluate(state->eval_ctx); + node->stats.current_time += PIL_check_seconds_timer() - start_time; } - + else { + node->evaluate(state->eval_ctx); + } + /* Schedule children. */ BLI_task_pool_delayed_push_begin(pool, thread_id); schedule_children(pool, state->graph, node, thread_id); BLI_task_pool_delayed_push_end(pool, thread_id); @@ -148,6 +139,19 @@ static void calculate_pending_parents(Depsgraph *graph) do_threads); } +static void initialize_execution(DepsgraphEvalState *state, Depsgraph *graph) +{ + const bool do_stats = state->do_stats; + calculate_pending_parents(graph); + /* Clear tags and other things which needs to be clear. */ + foreach (OperationDepsNode *node, graph->operations) { + node->done = 0; + if (do_stats) { + node->stats.reset_current(); + } + } +} + /* Schedule a node if it needs evaluation. * dec_parents: Decrement pending parents count, true when child nodes are * scheduled after a task has been completed. @@ -221,28 +225,23 @@ static void schedule_children(TaskPool *pool, void deg_evaluate_on_refresh(EvaluationContext *eval_ctx, Depsgraph *graph) { - /* Generate base evaluation context, upon which all the others are derived. */ - // TODO: this needs both main and scene access... - /* Nothing to update, early out. */ if (BLI_gset_size(graph->entry_tags) == 0) { return; } - /* Set time for the current graph evaluation context. */ TimeSourceDepsNode *time_src = graph->find_time_source(); eval_ctx->depsgraph = (::Depsgraph *)graph; eval_ctx->view_layer = DEG_get_evaluated_view_layer((::Depsgraph *)graph); eval_ctx->ctime = time_src->cfra; - - /* XXX could use a separate pool for each eval context */ + /* Set up evaluation context for depsgraph itself. */ DepsgraphEvalState state; state.eval_ctx = eval_ctx; state.graph = graph; - + state.do_stats = (G.debug_value != 0); + /* Set up task scheduler and pull for threaded evaluation. */ TaskScheduler *task_scheduler; bool need_free_scheduler; - if (G.debug & G_DEBUG_DEPSGRAPH_NO_THREADS) { task_scheduler = BLI_task_scheduler_create(1); need_free_scheduler = true; @@ -251,24 +250,22 @@ void deg_evaluate_on_refresh(EvaluationContext *eval_ctx, task_scheduler = BLI_task_scheduler_get(); need_free_scheduler = false; } - TaskPool *task_pool = BLI_task_pool_create_suspended(task_scheduler, &state); - - calculate_pending_parents(graph); - - /* Clear tags. */ - foreach (OperationDepsNode *node, graph->operations) { - node->done = 0; - } - + /* Prepare all nodes for evaluation. */ + initialize_execution(&state, graph); + /* Do actual evaluation now. */ schedule_graph(task_pool, graph); - BLI_task_pool_work_and_wait(task_pool); BLI_task_pool_free(task_pool); - + /* Finalize statistics gathering. This is because we only gather single + * operation timing here, without aggregating anything to avoid any extra + * synchronization. + */ + if (state.do_stats) { + deg_eval_stats_aggregate(graph); + } /* Clear any uncleared tags - just in case. */ deg_graph_clear_tags(graph); - if (need_free_scheduler) { BLI_task_scheduler_free(task_scheduler); } |