Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/depsgraph')
-rw-r--r--source/blender/depsgraph/CMakeLists.txt5
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder.cc1
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_cycle.cc1
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc21
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc1
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_transitive.cc1
-rw-r--r--source/blender/depsgraph/intern/debug/deg_debug.cc40
-rw-r--r--source/blender/depsgraph/intern/debug/deg_debug.h33
-rw-r--r--source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc2
-rw-r--r--source/blender/depsgraph/intern/debug/deg_time_average.h71
-rw-r--r--source/blender/depsgraph/intern/depsgraph.cc39
-rw-r--r--source/blender/depsgraph/intern/depsgraph.h45
-rw-r--r--source/blender/depsgraph/intern/depsgraph_build.cc1
-rw-r--r--source/blender/depsgraph/intern/depsgraph_debug.cc9
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query_foreach.cc1
-rw-r--r--source/blender/depsgraph/intern/depsgraph_relation.cc73
-rw-r--r--source/blender/depsgraph/intern/depsgraph_relation.h63
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval.cc13
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_flush.cc1
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc7
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h2
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_animation.cc144
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_animation.h65
-rw-r--r--source/blender/depsgraph/intern/node/deg_node.cc1
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_time.cc1
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 {