diff options
Diffstat (limited to 'source/blender/depsgraph')
25 files changed, 550 insertions, 91 deletions
diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt index 4abeec19645..fad8bc22e08 100644 --- a/source/blender/depsgraph/CMakeLists.txt +++ b/source/blender/depsgraph/CMakeLists.txt @@ -59,6 +59,7 @@ set(SRC intern/eval/deg_eval_copy_on_write.cc intern/eval/deg_eval_flush.cc intern/eval/deg_eval_runtime_backup.cc + intern/eval/deg_eval_runtime_backup_animation.cc intern/eval/deg_eval_runtime_backup_modifier.cc intern/eval/deg_eval_runtime_backup_movieclip.cc intern/eval/deg_eval_runtime_backup_object.cc @@ -82,6 +83,7 @@ set(SRC intern/depsgraph_query.cc intern/depsgraph_query_foreach.cc intern/depsgraph_query_iter.cc + intern/depsgraph_relation.cc intern/depsgraph_registry.cc intern/depsgraph_tag.cc intern/depsgraph_type.cc @@ -104,10 +106,12 @@ set(SRC intern/builder/deg_builder_rna.h intern/builder/deg_builder_transitive.h intern/debug/deg_debug.h + intern/debug/deg_time_average.h intern/eval/deg_eval.h intern/eval/deg_eval_copy_on_write.h intern/eval/deg_eval_flush.h intern/eval/deg_eval_runtime_backup.h + intern/eval/deg_eval_runtime_backup_animation.h intern/eval/deg_eval_runtime_backup_modifier.h intern/eval/deg_eval_runtime_backup_movieclip.h intern/eval/deg_eval_runtime_backup_object.h @@ -127,6 +131,7 @@ set(SRC intern/depsgraph.h intern/depsgraph_physics.h intern/depsgraph_registry.h + intern/depsgraph_relation.h intern/depsgraph_tag.h intern/depsgraph_type.h intern/depsgraph_update.h diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc index fb7104e7556..440d9dd07f6 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder.cc @@ -42,6 +42,7 @@ extern "C" { } #include "intern/depsgraph.h" +#include "intern/depsgraph_relation.h" #include "intern/depsgraph_tag.h" #include "intern/depsgraph_type.h" #include "intern/builder/deg_builder_cache.h" diff --git a/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc b/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc index bea59eceea2..f18583beb9c 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc @@ -35,6 +35,7 @@ #include "intern/node/deg_node_operation.h" #include "intern/depsgraph.h" +#include "intern/depsgraph_relation.h" namespace DEG { diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index fa7a63227f5..f6a6b6f77da 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -114,6 +114,7 @@ extern "C" { #include "intern/node/deg_node_operation.h" #include "intern/node/deg_node_time.h" +#include "intern/depsgraph_relation.h" #include "intern/depsgraph_type.h" namespace DEG { @@ -2666,6 +2667,26 @@ void DepsgraphRelationBuilder::build_copy_on_write_relations(IDNode *id_node) BLI_assert(object->type == OB_EMPTY); } } + +#if 0 + /* NOTE: Relation is disabled since AnimationBackup() is disabled. + * See comment in AnimationBackup:init_from_id(). */ + + /* Copy-on-write of write will iterate over f-curves to store current values corresponding + * to their RNA path. This means that action must be copied prior to the ID's copy-on-write, + * otherwise depsgraph might try to access freed data. */ + AnimData *animation_data = BKE_animdata_from_id(id_orig); + if (animation_data != NULL) { + if (animation_data->action != NULL) { + OperationKey action_copy_on_write_key( + &animation_data->action->id, NodeType::COPY_ON_WRITE, OperationCode::COPY_ON_WRITE); + add_relation(action_copy_on_write_key, + copy_on_write_key, + "Eval Order", + RELATION_FLAG_GODMODE | RELATION_FLAG_NO_FLUSH); + } + } +#endif } /* **** ID traversal callbacks functions **** */ diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc index e254f8df0d2..484a4d828e3 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc @@ -58,6 +58,7 @@ extern "C" { #include "intern/node/deg_node_operation.h" #include "intern/depsgraph_type.h" +#include "intern/depsgraph_relation.h" namespace DEG { diff --git a/source/blender/depsgraph/intern/builder/deg_builder_transitive.cc b/source/blender/depsgraph/intern/builder/deg_builder_transitive.cc index 13cf8e63832..fc7c546e294 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_transitive.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_transitive.cc @@ -30,6 +30,7 @@ #include "intern/node/deg_node_operation.h" #include "intern/depsgraph.h" +#include "intern/depsgraph_relation.h" #include "intern/debug/deg_debug.h" namespace DEG { diff --git a/source/blender/depsgraph/intern/debug/deg_debug.cc b/source/blender/depsgraph/intern/debug/deg_debug.cc index b811f11f721..74a042989db 100644 --- a/source/blender/depsgraph/intern/debug/deg_debug.cc +++ b/source/blender/depsgraph/intern/debug/deg_debug.cc @@ -28,10 +28,50 @@ #include "BLI_hash.h" #include "BLI_string.h" +#include "PIL_time_utildefines.h" + #include "BKE_global.h" namespace DEG { +DepsgraphDebug::DepsgraphDebug() + : flags(G.debug), is_ever_evaluated(false), graph_evaluation_start_time_(0) +{ +} + +bool DepsgraphDebug::do_time_debug() const +{ + return ((G.debug & G_DEBUG_DEPSGRAPH_TIME) != 0); +} + +void DepsgraphDebug::begin_graph_evaluation() +{ + if (!do_time_debug()) { + return; + } + + const double current_time = PIL_check_seconds_timer(); + + if (is_ever_evaluated) { + fps_samples_.add_sample(current_time - graph_evaluation_start_time_); + } + + graph_evaluation_start_time_ = current_time; +} + +void DepsgraphDebug::end_graph_evaluation() +{ + if (!do_time_debug()) { + return; + } + + const double graph_eval_end_time = PIL_check_seconds_timer(); + printf("Depsgraph updated in %f seconds.\n", graph_eval_end_time - graph_evaluation_start_time_); + printf("Depsgraph evaluation FPS: %f\n", 1.0f / fps_samples_.get_averaged()); + + is_ever_evaluated = true; +} + bool terminal_do_color(void) { return (G.debug & G_DEBUG_DEPSGRAPH_PRETTY) != 0; diff --git a/source/blender/depsgraph/intern/debug/deg_debug.h b/source/blender/depsgraph/intern/debug/deg_debug.h index 3e4da644641..21a802828dc 100644 --- a/source/blender/depsgraph/intern/debug/deg_debug.h +++ b/source/blender/depsgraph/intern/debug/deg_debug.h @@ -24,6 +24,7 @@ #pragma once #include "intern/depsgraph_type.h" +#include "intern/debug/deg_time_average.h" #include "BKE_global.h" @@ -31,6 +32,38 @@ namespace DEG { +class DepsgraphDebug { + public: + DepsgraphDebug(); + + bool do_time_debug() const; + + void begin_graph_evaluation(); + void end_graph_evaluation(); + + /* NOTE: Corresponds to G_DEBUG_DEPSGRAPH_* flags. */ + int flags; + + /* Name of this dependency graph (is used for debug prints, helping to distinguish graphs + * created for different view layer). */ + string name; + + /* Is true when dependency graph was evaluated at least once. + * This is NOT an indication that depsgraph is at its evaluated state. */ + bool is_ever_evaluated; + + protected: + /* Maximum number of counters used to calculate frame rate of depsgraph update. */ + static const constexpr int MAX_FPS_COUNTERS = 64; + + /* Point in time when last graph evaluation began. + * Is initialized from begin_graph_evaluation() when time debug is enabled. + */ + double graph_evaluation_start_time_; + + AveragedTimeSampler<MAX_FPS_COUNTERS> fps_samples_; +}; + #define DEG_DEBUG_PRINTF(depsgraph, type, ...) \ do { \ if (DEG_debug_flags_get(depsgraph) & G_DEBUG_DEPSGRAPH_##type) { \ diff --git a/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc b/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc index ee3959a0861..45d15c230d7 100644 --- a/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc +++ b/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc @@ -36,6 +36,8 @@ extern "C" { #include "DEG_depsgraph_debug.h" #include "intern/depsgraph.h" +#include "intern/depsgraph_relation.h" + #include "intern/node/deg_node_component.h" #include "intern/node/deg_node_id.h" #include "intern/node/deg_node_operation.h" diff --git a/source/blender/depsgraph/intern/debug/deg_time_average.h b/source/blender/depsgraph/intern/debug/deg_time_average.h new file mode 100644 index 00000000000..9794e9a88c3 --- /dev/null +++ b/source/blender/depsgraph/intern/debug/deg_time_average.h @@ -0,0 +1,71 @@ +/* + * 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) 2013 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup depsgraph + */ + +#pragma once + +namespace DEG { + +// Utility class which takes care of calculating average of time series, such as +// FPS counters. +template<int MaxSamples> class AveragedTimeSampler { + public: + AveragedTimeSampler() : num_samples_(0), next_sample_index_(0) + { + } + + void add_sample(double value) + { + samples_[next_sample_index_] = value; + + // Move to the next index, keeping wrapping at the end of array into account. + ++next_sample_index_; + if (next_sample_index_ == MaxSamples) { + next_sample_index_ = 0; + } + + // Update number of stored samples. + if (num_samples_ != MaxSamples) { + ++num_samples_; + } + } + + double get_averaged() const + { + double sum = 0.0; + for (int i = 0; i < num_samples_; ++i) { + sum += samples_[i]; + } + return sum / num_samples_; + } + + protected: + double samples_[MaxSamples]; + + // Number of samples which are actually stored in the array. + int num_samples_; + + // Index in the samples_ array under which next sample will be stored. + int next_sample_index_; +}; + +} // namespace DEG diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc index 292c3b361d8..7e26857e440 100644 --- a/source/blender/depsgraph/intern/depsgraph.cc +++ b/source/blender/depsgraph/intern/depsgraph.cc @@ -46,6 +46,7 @@ extern "C" { #include "intern/depsgraph_update.h" #include "intern/depsgraph_physics.h" +#include "intern/depsgraph_relation.h" #include "intern/depsgraph_registry.h" #include "intern/eval/deg_eval_copy_on_write.h" @@ -82,7 +83,6 @@ Depsgraph::Depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer, eEvaluati BLI_spin_init(&lock); id_hash = BLI_ghash_ptr_new("Depsgraph id hash"); entry_tags = BLI_gset_ptr_new("Depsgraph entry_tags"); - debug_flags = G.debug; memset(id_type_updated, 0, sizeof(id_type_updated)); memset(id_type_exist, 0, sizeof(id_type_exist)); memset(physics_relations, 0, sizeof(physics_relations)); @@ -220,43 +220,6 @@ Relation *Depsgraph::check_nodes_connected(const Node *from, return NULL; } -/* ************************ */ -/* Relationships Management */ - -Relation::Relation(Node *from, Node *to, const char *description) - : from(from), to(to), name(description), flag(0) -{ - /* Hook it up to the nodes which use it. - * - * NOTE: We register relation in the nodes which this link connects to here - * in constructor but we don't unregister it in the destructor. - * - * Reasoning: - * - * - Destructor is currently used on global graph destruction, so there's no - * real need in avoiding dangling pointers, all the memory is to be freed - * anyway. - * - * - Unregistering relation is not a cheap operation, so better to have it - * as an explicit call if we need this. */ - from->outlinks.push_back(this); - to->inlinks.push_back(this); -} - -Relation::~Relation() -{ - /* Sanity check. */ - BLI_assert(from != NULL && to != NULL); -} - -void Relation::unlink() -{ - /* Sanity check. */ - BLI_assert(from != NULL && to != NULL); - remove_from_vector(&from->outlinks, this); - remove_from_vector(&to->inlinks, this); -} - /* Low level tagging -------------------------------------- */ /* Tag a specific node as needing updates. */ diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h index 43829f4e045..a7ee5612af4 100644 --- a/source/blender/depsgraph/intern/depsgraph.h +++ b/source/blender/depsgraph/intern/depsgraph.h @@ -40,6 +40,7 @@ #include "DEG_depsgraph.h" #include "DEG_depsgraph_physics.h" +#include "intern/debug/deg_debug.h" #include "intern/depsgraph_type.h" struct GHash; @@ -53,47 +54,9 @@ namespace DEG { struct IDNode; struct Node; struct OperationNode; +struct Relation; struct TimeSourceNode; -/* *************************** */ -/* Relationships Between Nodes */ - -/* Settings/Tags on Relationship. - * NOTE: Is a bitmask, allowing accumulation. */ -enum RelationFlag { - /* "cyclic" link - when detecting cycles, this relationship was the one - * which triggers a cyclic relationship to exist in the graph. */ - RELATION_FLAG_CYCLIC = (1 << 0), - /* Update flush will not go through this relation. */ - RELATION_FLAG_NO_FLUSH = (1 << 1), - /* Only flush along the relation is update comes from a node which was - * affected by user input. */ - RELATION_FLAG_FLUSH_USER_EDIT_ONLY = (1 << 2), - /* The relation can not be killed by the cyclic dependencies solver. */ - RELATION_FLAG_GODMODE = (1 << 4), - /* Relation will check existence before being added. */ - RELATION_CHECK_BEFORE_ADD = (1 << 5), -}; - -/* B depends on A (A -> B) */ -struct Relation { - Relation(Node *from, Node *to, const char *description); - ~Relation(); - - void unlink(); - - /* the nodes in the relationship (since this is shared between the nodes) */ - Node *from; /* A */ - Node *to; /* B */ - - /* relationship attributes */ - const char *name; /* label for debugging */ - int flag; /* Bitmask of RelationFlag) */ -}; - -/* ********* */ -/* Depsgraph */ - /* Dependency Graph object */ struct Depsgraph { // TODO(sergey): Go away from C++ container and use some native BLI. @@ -194,9 +157,7 @@ struct Depsgraph { * to read stuff from. */ bool is_active; - /* NOTE: Corresponds to G_DEBUG_DEPSGRAPH_* flags. */ - int debug_flags; - string debug_name; + DepsgraphDebug debug; bool is_evaluating; diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc index 0acf777e2f0..4ecb8b8068c 100644 --- a/source/blender/depsgraph/intern/depsgraph_build.cc +++ b/source/blender/depsgraph/intern/depsgraph_build.cc @@ -59,6 +59,7 @@ extern "C" { #include "intern/node/deg_node_id.h" #include "intern/node/deg_node_operation.h" +#include "intern/depsgraph_relation.h" #include "intern/depsgraph_registry.h" #include "intern/depsgraph_type.h" diff --git a/source/blender/depsgraph/intern/depsgraph_debug.cc b/source/blender/depsgraph/intern/depsgraph_debug.cc index bb60db5209c..4cf3a150eac 100644 --- a/source/blender/depsgraph/intern/depsgraph_debug.cc +++ b/source/blender/depsgraph/intern/depsgraph_debug.cc @@ -38,6 +38,7 @@ extern "C" { #include "DEG_depsgraph_query.h" #include "intern/depsgraph.h" +#include "intern/depsgraph_relation.h" #include "intern/depsgraph_type.h" #include "intern/debug/deg_debug.h" #include "intern/node/deg_node_component.h" @@ -47,25 +48,25 @@ extern "C" { void DEG_debug_flags_set(Depsgraph *depsgraph, int flags) { DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(depsgraph); - deg_graph->debug_flags = flags; + deg_graph->debug.flags = flags; } int DEG_debug_flags_get(const Depsgraph *depsgraph) { const DEG::Depsgraph *deg_graph = reinterpret_cast<const DEG::Depsgraph *>(depsgraph); - return deg_graph->debug_flags; + return deg_graph->debug.flags; } void DEG_debug_name_set(struct Depsgraph *depsgraph, const char *name) { DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(depsgraph); - deg_graph->debug_name = name; + deg_graph->debug.name = name; } const char *DEG_debug_name_get(struct Depsgraph *depsgraph) { const DEG::Depsgraph *deg_graph = reinterpret_cast<const DEG::Depsgraph *>(depsgraph); - return deg_graph->debug_name.c_str(); + return deg_graph->debug.name.c_str(); } bool DEG_debug_compare(const struct Depsgraph *graph1, const struct Depsgraph *graph2) diff --git a/source/blender/depsgraph/intern/depsgraph_query_foreach.cc b/source/blender/depsgraph/intern/depsgraph_query_foreach.cc index b7a40fb69bd..cd5e8f8a8d9 100644 --- a/source/blender/depsgraph/intern/depsgraph_query_foreach.cc +++ b/source/blender/depsgraph/intern/depsgraph_query_foreach.cc @@ -40,6 +40,7 @@ extern "C" { #include "DEG_depsgraph_query.h" #include "intern/depsgraph.h" +#include "intern/depsgraph_relation.h" #include "intern/node/deg_node.h" #include "intern/node/deg_node_component.h" #include "intern/node/deg_node_id.h" diff --git a/source/blender/depsgraph/intern/depsgraph_relation.cc b/source/blender/depsgraph/intern/depsgraph_relation.cc new file mode 100644 index 00000000000..387582ca4e0 --- /dev/null +++ b/source/blender/depsgraph/intern/depsgraph_relation.cc @@ -0,0 +1,73 @@ +/* + * 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) 2020 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup depsgraph + */ + +#include "intern/depsgraph_relation.h" /* own include */ + +#include "BLI_utildefines.h" + +#include "intern/depsgraph_type.h" +#include "intern/node/deg_node.h" + +namespace DEG { + +/* TODO(sergey): Find a better place for this. */ +template<typename T> static void remove_from_vector(vector<T> *vector, const T &value) +{ + vector->erase(std::remove(vector->begin(), vector->end(), value), vector->end()); +} + +Relation::Relation(Node *from, Node *to, const char *description) + : from(from), to(to), name(description), flag(0) +{ + /* Hook it up to the nodes which use it. + * + * NOTE: We register relation in the nodes which this link connects to here + * in constructor but we don't unregister it in the destructor. + * + * Reasoning: + * + * - Destructor is currently used on global graph destruction, so there's no + * real need in avoiding dangling pointers, all the memory is to be freed + * anyway. + * + * - Unregistering relation is not a cheap operation, so better to have it + * as an explicit call if we need this. */ + from->outlinks.push_back(this); + to->inlinks.push_back(this); +} + +Relation::~Relation() +{ + /* Sanity check. */ + BLI_assert(from != NULL && to != NULL); +} + +void Relation::unlink() +{ + /* Sanity check. */ + BLI_assert(from != NULL && to != NULL); + remove_from_vector(&from->outlinks, this); + remove_from_vector(&to->inlinks, this); +} + +} // namespace DEG diff --git a/source/blender/depsgraph/intern/depsgraph_relation.h b/source/blender/depsgraph/intern/depsgraph_relation.h new file mode 100644 index 00000000000..9195e9abfbd --- /dev/null +++ b/source/blender/depsgraph/intern/depsgraph_relation.h @@ -0,0 +1,63 @@ +/* + * 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) 2020 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup depsgraph + */ + +#pragma once + +namespace DEG { + +class Node; + +/* Settings/Tags on Relationship. + * NOTE: Is a bitmask, allowing accumulation. */ +enum RelationFlag { + /* "cyclic" link - when detecting cycles, this relationship was the one + * which triggers a cyclic relationship to exist in the graph. */ + RELATION_FLAG_CYCLIC = (1 << 0), + /* Update flush will not go through this relation. */ + RELATION_FLAG_NO_FLUSH = (1 << 1), + /* Only flush along the relation is update comes from a node which was + * affected by user input. */ + RELATION_FLAG_FLUSH_USER_EDIT_ONLY = (1 << 2), + /* The relation can not be killed by the cyclic dependencies solver. */ + RELATION_FLAG_GODMODE = (1 << 4), + /* Relation will check existence before being added. */ + RELATION_CHECK_BEFORE_ADD = (1 << 5), +}; + +/* B depends on A (A -> B) */ +struct Relation { + Relation(Node *from, Node *to, const char *description); + ~Relation(); + + void unlink(); + + /* the nodes in the relationship (since this is shared between the nodes) */ + Node *from; /* A */ + Node *to; /* B */ + + /* relationship attributes */ + const char *name; /* label for debugging */ + int flag; /* Bitmask of RelationFlag) */ +}; + +} // namespace DEG diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc index ff30bf7571a..9a10177a462 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval.cc @@ -52,6 +52,7 @@ #include "intern/node/deg_node_operation.h" #include "intern/node/deg_node_time.h" #include "intern/depsgraph.h" +#include "intern/depsgraph_relation.h" namespace DEG { @@ -364,14 +365,15 @@ void deg_evaluate_on_refresh(Depsgraph *graph) if (BLI_gset_len(graph->entry_tags) == 0) { return; } - const bool do_time_debug = ((G.debug & G_DEBUG_DEPSGRAPH_TIME) != 0); - const double start_time = do_time_debug ? PIL_check_seconds_timer() : 0; + + graph->debug.begin_graph_evaluation(); + graph->is_evaluating = true; depsgraph_ensure_view_layer(graph); /* Set up evaluation state. */ DepsgraphEvalState state; state.graph = graph; - state.do_stats = do_time_debug; + state.do_stats = graph->debug.do_time_debug(); state.need_single_thread_pass = false; /* Set up task scheduler and pull for threaded evaluation. */ TaskScheduler *task_scheduler; @@ -418,9 +420,8 @@ void deg_evaluate_on_refresh(Depsgraph *graph) BLI_task_scheduler_free(task_scheduler); } graph->is_evaluating = false; - if (do_time_debug) { - printf("Depsgraph updated in %f seconds.\n", PIL_check_seconds_timer() - start_time); - } + + graph->debug.end_graph_evaluation(); } } // namespace DEG diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc index 96e2974a7ab..cf9b1259e4e 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc @@ -49,6 +49,7 @@ extern "C" { #include "intern/debug/deg_debug.h" #include "intern/depsgraph.h" +#include "intern/depsgraph_relation.h" #include "intern/depsgraph_update.h" #include "intern/node/deg_node.h" #include "intern/node/deg_node_component.h" diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc index 88390ab412f..4da5ca77fb8 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc @@ -32,7 +32,8 @@ namespace DEG { RuntimeBackup::RuntimeBackup(const Depsgraph *depsgraph) - : scene_backup(depsgraph), + : animation_backup(depsgraph), + scene_backup(depsgraph), sound_backup(depsgraph), object_backup(depsgraph), drawdata_ptr(NULL), @@ -47,6 +48,8 @@ void RuntimeBackup::init_from_id(ID *id) return; } + animation_backup.init_from_id(id); + const ID_Type id_type = GS(id->name); switch (id_type) { case ID_OB: @@ -76,6 +79,8 @@ void RuntimeBackup::init_from_id(ID *id) void RuntimeBackup::restore_to_id(ID *id) { + animation_backup.restore_to_id(id); + const ID_Type id_type = GS(id->name); switch (id_type) { case ID_OB: diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h index 31ae3164e37..892cc88002f 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h +++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h @@ -25,6 +25,7 @@ #include "DNA_ID.h" +#include "intern/eval/deg_eval_runtime_backup_animation.h" #include "intern/eval/deg_eval_runtime_backup_movieclip.h" #include "intern/eval/deg_eval_runtime_backup_object.h" #include "intern/eval/deg_eval_runtime_backup_scene.h" @@ -44,6 +45,7 @@ class RuntimeBackup { /* Restore fields to the given ID. */ void restore_to_id(ID *id); + AnimationBackup animation_backup; SceneBackup scene_backup; SoundBackup sound_backup; ObjectRuntimeBackup object_backup; diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_animation.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_animation.cc new file mode 100644 index 00000000000..cc4935431d1 --- /dev/null +++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_animation.cc @@ -0,0 +1,144 @@ +/* + * 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) 2019 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup depsgraph + */ + +#include "intern/eval/deg_eval_runtime_backup_animation.h" + +#include "DNA_anim_types.h" + +#include "BKE_animsys.h" + +#include "RNA_access.h" +#include "RNA_types.h" + +#include "intern/depsgraph.h" + +namespace DEG { + +namespace { + +struct AnimatedPropertyStoreCalbackData { + AnimationBackup *backup; + + /* ID which needs to be stored. + * Is used to check possibly nested IDs which f-curves are pointing to. */ + ID *id; + + PointerRNA id_pointer_rna; +}; + +void animated_property_store_cb(ID *id, FCurve *fcurve, void *data_v) +{ + AnimatedPropertyStoreCalbackData *data = reinterpret_cast<AnimatedPropertyStoreCalbackData *>( + data_v); + if (fcurve->rna_path == NULL || fcurve->rna_path[0] == '\0') { + return; + } + if (id != data->id) { + return; + } + + /* Resolve path to the property. */ + PathResolvedRNA resolved_rna; + if (!BKE_animsys_store_rna_setting( + &data->id_pointer_rna, fcurve->rna_path, fcurve->array_index, &resolved_rna)) { + return; + } + + /* Read property value. */ + float value; + if (!BKE_animsys_read_rna_setting(&resolved_rna, &value)) { + return; + } + + data->backup->values_backup.emplace_back(fcurve->rna_path, fcurve->array_index, value); +} + +} // namespace + +AnimationValueBackup::AnimationValueBackup() +{ +} + +AnimationValueBackup::AnimationValueBackup(const string &rna_path, int array_index, float value) + : rna_path(rna_path), array_index(array_index), value(value) +{ +} + +AnimationValueBackup::~AnimationValueBackup() +{ +} + +AnimationBackup::AnimationBackup(const Depsgraph *depsgraph) +{ + meed_value_backup = !depsgraph->is_active; + reset(); +} + +void AnimationBackup::reset() +{ +} + +void AnimationBackup::init_from_id(ID *id) +{ + /* NOTE: This animation backup nicely preserves values which are animated and + * are not touched by frame/depsgraph post_update handler. + * + * But it makes it impossible to have user edits to animated properties: for + * example, translation of object with animated location will not work with + * the current version of backup. */ + return; + + AnimatedPropertyStoreCalbackData data; + data.backup = this; + data.id = id; + RNA_id_pointer_create(id, &data.id_pointer_rna); + BKE_fcurves_id_cb(id, animated_property_store_cb, &data); +} + +void AnimationBackup::restore_to_id(ID *id) +{ + return; + + PointerRNA id_pointer_rna; + RNA_id_pointer_create(id, &id_pointer_rna); + for (const AnimationValueBackup &value_backup : values_backup) { + /* Resolve path to the property. + * + * NOTE: Do it again (after storing), since the sub-data pointers might be + * changed after copy-on-write. */ + PathResolvedRNA resolved_rna; + if (!BKE_animsys_store_rna_setting(&id_pointer_rna, + value_backup.rna_path.c_str(), + value_backup.array_index, + &resolved_rna)) { + return; + } + + /* Write property value. */ + if (!BKE_animsys_write_rna_setting(&resolved_rna, value_backup.value)) { + return; + } + } +} + +} // namespace DEG diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_animation.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_animation.h new file mode 100644 index 00000000000..d97ee2b0556 --- /dev/null +++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_animation.h @@ -0,0 +1,65 @@ +/* + * 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) 2019 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup depsgraph + */ + +#pragma once + +#include "BKE_modifier.h" + +#include "intern/depsgraph_type.h" + +namespace DEG { + +struct Depsgraph; + +class AnimationValueBackup { + public: + AnimationValueBackup(); + AnimationValueBackup(const string &rna_path, int array_index, float value); + ~AnimationValueBackup(); + + AnimationValueBackup(const AnimationValueBackup &other) = default; + AnimationValueBackup(AnimationValueBackup &&other) noexcept = default; + + AnimationValueBackup &operator=(const AnimationValueBackup &other) = default; + AnimationValueBackup &operator=(AnimationValueBackup &&other) = default; + + string rna_path; + int array_index; + float value; +}; + +/* Backup of animated properties values. */ +class AnimationBackup { + public: + AnimationBackup(const Depsgraph *depsgraph); + + void reset(); + + void init_from_id(ID *id); + void restore_to_id(ID *id); + + bool meed_value_backup; + vector<AnimationValueBackup> values_backup; +}; + +} // namespace DEG diff --git a/source/blender/depsgraph/intern/node/deg_node.cc b/source/blender/depsgraph/intern/node/deg_node.cc index 16c934e72fe..5002f2890ae 100644 --- a/source/blender/depsgraph/intern/node/deg_node.cc +++ b/source/blender/depsgraph/intern/node/deg_node.cc @@ -28,6 +28,7 @@ #include "BLI_utildefines.h" #include "intern/depsgraph.h" +#include "intern/depsgraph_relation.h" #include "intern/eval/deg_eval_copy_on_write.h" #include "intern/node/deg_node_component.h" #include "intern/node/deg_node_factory.h" diff --git a/source/blender/depsgraph/intern/node/deg_node_time.cc b/source/blender/depsgraph/intern/node/deg_node_time.cc index cae98ef56c0..ff3e950bb44 100644 --- a/source/blender/depsgraph/intern/node/deg_node_time.cc +++ b/source/blender/depsgraph/intern/node/deg_node_time.cc @@ -26,6 +26,7 @@ #include "DNA_scene_types.h" #include "intern/depsgraph.h" +#include "intern/depsgraph_relation.h" namespace DEG { |