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 | |
parent | b38c0832596bee85cf88a62a1eb29e365dbcf99d (diff) | |
parent | 885bb5b137b5ea71869b741e6ee7acc1602ab5c6 (diff) |
Merge branch 'master' into blender2.8
-rw-r--r-- | intern/cycles/kernel/filter/filter_prefilter.h | 97 | ||||
-rw-r--r-- | source/blender/depsgraph/CMakeLists.txt | 5 | ||||
-rw-r--r-- | source/blender/depsgraph/DEG_depsgraph_debug.h | 9 | ||||
-rw-r--r-- | source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc (renamed from source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc) | 6 | ||||
-rw-r--r-- | source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc | 126 | ||||
-rw-r--r-- | source/blender/depsgraph/intern/eval/deg_eval.cc | 83 | ||||
-rw-r--r-- | source/blender/depsgraph/intern/eval/deg_eval_stats.cc | 70 | ||||
-rw-r--r-- | source/blender/depsgraph/intern/eval/deg_eval_stats.h | 40 | ||||
-rw-r--r-- | source/blender/depsgraph/intern/nodes/deg_node.cc | 36 | ||||
-rw-r--r-- | source/blender/depsgraph/intern/nodes/deg_node.h | 16 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_depsgraph.c | 27 |
11 files changed, 408 insertions, 107 deletions
diff --git a/intern/cycles/kernel/filter/filter_prefilter.h b/intern/cycles/kernel/filter/filter_prefilter.h index eefcbfea230..4af209341f6 100644 --- a/intern/cycles/kernel/filter/filter_prefilter.h +++ b/intern/cycles/kernel/filter/filter_prefilter.h @@ -117,61 +117,58 @@ ccl_device void kernel_filter_detect_outliers(int x, int y, { int buffer_w = align_up(rect.z - rect.x, 4); - int idx = (y-rect.y)*buffer_w + (x-rect.x); - float3 color = make_float3(image[idx], image[idx+pass_stride], image[idx+2*pass_stride]); - - float fac = 1.0f; - if(color.x < 0.0f || color.y < 0.0f || color.z < 0.0f) { - depth[idx] = -depth[idx]; - fac = 0.0f; - } - else { - float L = average(color); - int n = 0; - float values[25]; - for(int y1 = max(y-2, rect.y); y1 < min(y+3, rect.w); y1++) { - for(int x1 = max(x-2, rect.x); x1 < min(x+3, rect.z); x1++) { - int idx = (y1-rect.y)*buffer_w + (x1-rect.x); - float L = average(make_float3(image[idx], image[idx+pass_stride], image[idx+2*pass_stride])); - - /* Find the position of L. */ - int i; - for(i = 0; i < n; i++) { - if(values[i] > L) break; - } - /* Make space for L by shifting all following values to the right. */ - for(int j = n; j > i; j--) { - values[j] = values[j-1]; - } - /* Insert L. */ - values[i] = L; - n++; + int n = 0; + float values[25]; + for(int y1 = max(y-2, rect.y); y1 < min(y+3, rect.w); y1++) { + for(int x1 = max(x-2, rect.x); x1 < min(x+3, rect.z); x1++) { + int idx = (y1-rect.y)*buffer_w + (x1-rect.x); + float3 color = make_float3(image[idx], image[idx+pass_stride], image[idx+2*pass_stride]); + color = max(color, make_float3(0.0f, 0.0f, 0.0f)); + float L = average(color); + + /* Find the position of L. */ + int i; + for(i = 0; i < n; i++) { + if(values[i] > L) break; + } + /* Make space for L by shifting all following values to the right. */ + for(int j = n; j > i; j--) { + values[j] = values[j-1]; } + /* Insert L. */ + values[i] = L; + n++; } + } - float ref = 2.0f*values[(int)(n*0.75f)]; - if(L > ref) { - /* The pixel appears to be an outlier. - * However, it may just be a legitimate highlight. Therefore, it is checked how likely it is that the pixel - * should actually be at the reference value: - * If the reference is within the 3-sigma interval, the pixel is assumed to be a statistical outlier. - * Otherwise, it is very unlikely that the pixel should be darker, which indicates a legitimate highlight. - */ - float stddev = sqrtf(average(make_float3(variance[idx], variance[idx+pass_stride], variance[idx+2*pass_stride]))); - if(L - 3*stddev < ref) { - /* The pixel is an outlier, so negate the depth value to mark it as one. - * Also, scale its brightness down to the outlier threshold to avoid trouble with the NLM weights. */ - depth[idx] = -depth[idx]; - fac = ref/L; - variance[idx ] *= fac*fac; - variance[idx + pass_stride] *= fac*fac; - variance[idx+2*pass_stride] *= fac*fac; - } + int idx = (y-rect.y)*buffer_w + (x-rect.x); + float3 color = make_float3(image[idx], image[idx+pass_stride], image[idx+2*pass_stride]); + color = max(color, make_float3(0.0f, 0.0f, 0.0f)); + float L = average(color); + + float ref = 2.0f*values[(int)(n*0.75f)]; + if(L > ref) { + /* The pixel appears to be an outlier. + * However, it may just be a legitimate highlight. Therefore, it is checked how likely it is that the pixel + * should actually be at the reference value: + * If the reference is within the 3-sigma interval, the pixel is assumed to be a statistical outlier. + * Otherwise, it is very unlikely that the pixel should be darker, which indicates a legitimate highlight. + */ + float stddev = sqrtf(average(make_float3(variance[idx], variance[idx+pass_stride], variance[idx+2*pass_stride]))); + if(L - 3*stddev < ref) { + /* The pixel is an outlier, so negate the depth value to mark it as one. + * Also, scale its brightness down to the outlier threshold to avoid trouble with the NLM weights. */ + depth[idx] = -depth[idx]; + float fac = ref/L; + color *= fac; + variance[idx ] *= fac*fac; + variance[idx + pass_stride] *= fac*fac; + variance[idx+2*pass_stride] *= fac*fac; } } - out[idx ] = fac*image[idx]; - out[idx + pass_stride] = fac*image[idx + pass_stride]; - out[idx+2*pass_stride] = fac*image[idx+2*pass_stride]; + out[idx ] = color.x; + out[idx + pass_stride] = color.y; + out[idx+2*pass_stride] = color.z; } /* Combine A/B buffers. diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt index f5e43c71f93..c42d06bd0a2 100644 --- a/source/blender/depsgraph/CMakeLists.txt +++ b/source/blender/depsgraph/CMakeLists.txt @@ -53,10 +53,12 @@ set(SRC intern/builder/deg_builder_relations_rig.cc intern/builder/deg_builder_relations_view_layer.cc intern/builder/deg_builder_transitive.cc - intern/debug/deg_debug_graphviz.cc + intern/debug/deg_debug_relations_graphviz.cc + intern/debug/deg_debug_stats_gnuplot.cc intern/eval/deg_eval.cc intern/eval/deg_eval_copy_on_write.cc intern/eval/deg_eval_flush.cc + intern/eval/deg_eval_stats.cc intern/nodes/deg_node.cc intern/nodes/deg_node_component.cc intern/nodes/deg_node_id.cc @@ -87,6 +89,7 @@ set(SRC intern/eval/deg_eval.h intern/eval/deg_eval_copy_on_write.h intern/eval/deg_eval_flush.h + intern/eval/deg_eval_stats.h intern/nodes/deg_node.h intern/nodes/deg_node_component.h intern/nodes/deg_node_id.h diff --git a/source/blender/depsgraph/DEG_depsgraph_debug.h b/source/blender/depsgraph/DEG_depsgraph_debug.h index 93487cce645..363749dab26 100644 --- a/source/blender/depsgraph/DEG_depsgraph_debug.h +++ b/source/blender/depsgraph/DEG_depsgraph_debug.h @@ -53,7 +53,14 @@ void DEG_stats_simple(const struct Depsgraph *graph, /* ************************************************ */ /* Diagram-Based Graph Debugging */ -void DEG_debug_graphviz(const struct Depsgraph *graph, FILE *stream, const char *label); +void DEG_debug_relations_graphviz(const struct Depsgraph *graph, + FILE *stream, + const char *label); + +void DEG_debug_stats_gnuplot(const struct Depsgraph *graph, + FILE *stream, + const char *label, + const char *output_filename); /* ************************************************ */ diff --git a/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc b/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc index 68c2eb12914..827bb4d10ad 100644 --- a/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc +++ b/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc @@ -24,7 +24,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/depsgraph/intern/debug/deg_debug_graphviz.cc +/** \file blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc * \ingroup depsgraph * * Implementation of tools for debugging the depsgraph @@ -517,7 +517,9 @@ static void deg_debug_graphviz_graph_relations(const DebugContext &ctx, } // namespace DEG -void DEG_debug_graphviz(const Depsgraph *graph, FILE *f, const char *label) +void DEG_debug_relations_graphviz(const Depsgraph *graph, + FILE *f, + const char *label) { if (!graph) { return; diff --git a/source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc b/source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc new file mode 100644 index 00000000000..3e20196c2ea --- /dev/null +++ b/source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc @@ -0,0 +1,126 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2017 Blender Foundation. + * All rights reserved. + * + * Original Author: Sergey Sharybin + * Contributor(s): None Yet + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc + * \ingroup depsgraph + */ + +#include "DEG_depsgraph_debug.h" + +#include <stdarg.h> + +#include "BLI_compiler_attrs.h" + +#include "intern/depsgraph.h" +#include "intern/nodes/deg_node_id.h" + +#include "util/deg_util_foreach.h" + +extern "C" { +#include "DNA_ID.h" +} /* extern "C" */ + +#define NL "\r\n" + +namespace DEG { +namespace { + +struct DebugContext { + FILE *file; + const Depsgraph *graph; + const char *label; + const char *output_filename; +}; + +/* TODO(sergey): De-duplicate with graphviz relation debugger. */ +static void deg_debug_fprintf(const DebugContext &ctx, + const char *fmt, + ...) ATTR_PRINTF_FORMAT(2, 3); +static void deg_debug_fprintf(const DebugContext &ctx, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + vfprintf(ctx.file, fmt, args); + va_end(args); +} + +void write_stats_data(const DebugContext& ctx) +{ + deg_debug_fprintf(ctx, "$data << EOD" NL); + // TODO(sergey): Sort nodes by time. + foreach (const IDDepsNode *id_node, ctx.graph->id_nodes) { + // TODO(sergey): Figure out a nice way to define which exact time + // we want to show. + const double time = id_node->stats.current_time; + if (time == 0.0) { + continue; + } + deg_debug_fprintf(ctx, "\"%s\",%f" NL, + id_node->id_orig->name + 2, + time); + } + deg_debug_fprintf(ctx, "EOD" NL); +} + +void deg_debug_stats_gnuplot(const DebugContext& ctx) +{ + // Data itself. + write_stats_data(ctx); + // Optional label. + if (ctx.label && ctx.label[0]) { + deg_debug_fprintf(ctx, "set title \"%s\"" NL, ctx.label); + } + // Rest of the commands. + // TODO(sergey): Need to decide on the resolution somehow. + deg_debug_fprintf(ctx, "set terminal pngcairo size 1920,1080" NL); + deg_debug_fprintf(ctx, "set output \"%s\"" NL, ctx.output_filename); + deg_debug_fprintf(ctx, "set grid" NL); + deg_debug_fprintf(ctx, "set datafile separator ','" NL); + deg_debug_fprintf(ctx, "set style fill solid" NL); + deg_debug_fprintf(ctx, "plot \"$data\" using " \ + "($2*0.5):0:($2*0.5):(0.2):yticlabels(1) " + "with boxxyerrorbars t '' lt rgb \"#406090\"" NL); + +} + +} // namespace +} // namespace DEG + +void DEG_debug_stats_gnuplot(const Depsgraph *depsgraph, + FILE *f, + const char *label, + const char *output_filename) +{ + if (depsgraph == NULL) { + return; + } + DEG::DebugContext ctx; + ctx.file = f; + ctx.graph = (DEG::Depsgraph *)depsgraph; + ctx.label = label; + ctx.output_filename = output_filename; + DEG::deg_debug_stats_gnuplot(ctx); +} 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); } diff --git a/source/blender/depsgraph/intern/eval/deg_eval_stats.cc b/source/blender/depsgraph/intern/eval/deg_eval_stats.cc new file mode 100644 index 00000000000..52ce744cc0a --- /dev/null +++ b/source/blender/depsgraph/intern/eval/deg_eval_stats.cc @@ -0,0 +1,70 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2017 Blender Foundation. + * All rights reserved. + * + * Original Author: Sergey Sharybin + * Contributor(s): None Yet + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/depsgraph/intern/eval/deg_eval_stats.cc + * \ingroup depsgraph + */ + +#include "intern/eval/deg_eval_stats.h" + +#include "BLI_utildefines.h" +#include "BLI_ghash.h" + +#include "intern/depsgraph.h" + +#include "intern/nodes/deg_node.h" +#include "intern/nodes/deg_node_component.h" +#include "intern/nodes/deg_node_id.h" +#include "intern/nodes/deg_node_operation.h" + +#include "util/deg_util_foreach.h" + +namespace DEG { + +void deg_eval_stats_aggregate(Depsgraph *graph) +{ + /* Reset current evaluation stats for ID and component nodes. + * Those are not filled in by the evaluation engine. + */ + foreach (DepsNode *node, graph->id_nodes) { + IDDepsNode *id_node = (IDDepsNode *)node; + GHASH_FOREACH_BEGIN(ComponentDepsNode *, comp_node, id_node->components) + { + comp_node->stats.reset_current(); + } + GHASH_FOREACH_END(); + id_node->stats.reset_current(); + } + /* Now accumulate operation timings to components and IDs. */ + foreach (OperationDepsNode *op_node, graph->operations) { + ComponentDepsNode *comp_node = op_node->owner; + IDDepsNode *id_node = comp_node->owner; + id_node->stats.current_time += op_node->stats.current_time; + comp_node->stats.current_time += op_node->stats.current_time; + } +} + +} // namespace DEG diff --git a/source/blender/depsgraph/intern/eval/deg_eval_stats.h b/source/blender/depsgraph/intern/eval/deg_eval_stats.h new file mode 100644 index 00000000000..8a7272ac89c --- /dev/null +++ b/source/blender/depsgraph/intern/eval/deg_eval_stats.h @@ -0,0 +1,40 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2017 Blender Foundation. + * All rights reserved. + * + * Original Author: Sergey Sharybin + * Contributor(s): None Yet + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/depsgraph/intern/eval/deg_eval_stats.h + * \ingroup depsgraph + */ + +#pragma once + +namespace DEG { + +struct Depsgraph; + +/* Aggregate operation timings to overall component and ID nodes timing. */ +void deg_eval_stats_aggregate(Depsgraph *graph); + +} // namespace DEG diff --git a/source/blender/depsgraph/intern/nodes/deg_node.cc b/source/blender/depsgraph/intern/nodes/deg_node.cc index 1387ce01445..fdcfc129073 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node.cc @@ -46,10 +46,9 @@ namespace DEG { -/* *************** */ -/* Node Management */ - -/* Add ------------------------------------------------ */ +/******************************************************************************* + * Type information. + */ DepsNode::TypeInfo::TypeInfo(eDepsNode_Type type, const char *tname, @@ -60,6 +59,29 @@ DepsNode::TypeInfo::TypeInfo(eDepsNode_Type type, { } +/******************************************************************************* + * Evaluation statistics. + */ + +DepsNode::Stats::Stats() +{ + reset(); +} + +void DepsNode::Stats::reset() +{ + current_time = 0.0; +} + +void DepsNode::Stats::reset_current() +{ + current_time = 0.0; +} + +/******************************************************************************* + * Node itself. + */ + DepsNode::DepsNode() { name = ""; @@ -99,8 +121,10 @@ eDepsNode_Class DepsNode::get_class() const { } } -/* Generic Nodes */ - +/******************************************************************************* + * Generic nodes definition. + */ +\ DEG_DEPSNODE_DEFINE(TimeSourceDepsNode, DEG_NODE_TYPE_TIMESOURCE, "Time Source"); static DepsNodeFactoryImpl<TimeSourceDepsNode> DNTI_TIMESOURCE; diff --git a/source/blender/depsgraph/intern/nodes/deg_node.h b/source/blender/depsgraph/intern/nodes/deg_node.h index cc741224c71..603a6be7ceb 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node.h +++ b/source/blender/depsgraph/intern/nodes/deg_node.h @@ -56,6 +56,19 @@ struct DepsNode { const char *tname; int id_recalc_tag; }; + struct Stats { + Stats(); + /* Reset all the counters. Including all stats needed for average + * evaluation time calculation. + */ + void reset(); + /* Reset counters needed for the current graph evaluation, does not + * touch averaging accumulators. + */ + void reset_current(); + /* Time spend on this node during current graph evaluation. */ + double current_time; + }; /* Relationships between nodes * The reason why all depsgraph nodes are descended from this type (apart * from basic serialization benefits - from the typeinfo) is that we can have @@ -67,7 +80,8 @@ struct DepsNode { eDepsNode_Type type; /* Structural type of node. */ Relations inlinks; /* Nodes which this one depends on. */ Relations outlinks; /* Nodes which depend on this one. */ - int done; /* Generic tags for traversal algorithms. */ + int done; /* Generic tags for traversal algorithms. */ + Stats stats; /* Evaluation statistics. */ /* Methods. */ DepsNode(); diff --git a/source/blender/makesrna/intern/rna_depsgraph.c b/source/blender/makesrna/intern/rna_depsgraph.c index a5b8845b120..20ce54a4a01 100644 --- a/source/blender/makesrna/intern/rna_depsgraph.c +++ b/source/blender/makesrna/intern/rna_depsgraph.c @@ -120,13 +120,26 @@ static int rna_DepsgraphIter_is_instance_get(PointerRNA *ptr) /* **************** Depsgraph **************** */ -static void rna_Depsgraph_debug_graphviz(Depsgraph *graph, const char *filename) +static void rna_Depsgraph_debug_relations_graphviz(Depsgraph *graph, + const char *filename) { FILE *f = fopen(filename, "w"); if (f == NULL) { return; } - DEG_debug_graphviz(graph, f, "Depsgraph"); + DEG_debug_relations_graphviz(graph, f, "Depsgraph"); + fclose(f); +} + +static void rna_Depsgraph_debug_stats_gnuplot(Depsgraph *graph, + const char *filename, + const char *output_filename) +{ + FILE *f = fopen(filename, "w"); + if (f == NULL) { + return; + } + DEG_debug_stats_gnuplot(graph, f, "Timing Statistics", output_filename); fclose(f); } @@ -297,10 +310,18 @@ static void rna_def_depsgraph(BlenderRNA *brna) srna = RNA_def_struct(brna, "Depsgraph", NULL); RNA_def_struct_ui_text(srna, "Dependency Graph", ""); - func = RNA_def_function(srna, "debug_graphviz", "rna_Depsgraph_debug_graphviz"); + func = RNA_def_function(srna, "debug_relations_graphviz", "rna_Depsgraph_debug_relations_graphviz"); + parm = RNA_def_string_file_path(func, "filename", NULL, FILE_MAX, "File Name", + "File in which to store graphviz debug output"); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + + func = RNA_def_function(srna, "debug_stats_gnuplot", "rna_Depsgraph_debug_stats_gnuplot"); parm = RNA_def_string_file_path(func, "filename", NULL, FILE_MAX, "File Name", "File in which to store graphviz debug output"); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + parm = RNA_def_string_file_path(func, "output_filename", NULL, FILE_MAX, "Output File Name", + "File name where gnuplot script will save the result"); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); func = RNA_def_function(srna, "debug_tag_update", "rna_Depsgraph_debug_tag_update"); |