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:
authorSergey Sharybin <sergey.vfx@gmail.com>2019-04-29 13:55:29 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2019-04-30 12:32:02 +0300
commitc8f3377d03531ec52fc8dd6fa5802679166997b8 (patch)
tree8a2ef328e1ccda447649a90cb54b6d1dc7ebd7d6 /source/blender/depsgraph
parent587ee46d884c7508017de2635372ffac8ef638a5 (diff)
Depsgraph: Add generic animated properties cache
Allows to speed up lookups like "is property FOO of data BAR animated". Can be used to optimize object's visibility check, but also allows to check animation on bones without too much of time penalty. The cache is shared between both nodes and relations builder. Currently is not used, just a boilerplate for an upcoming changes in an actual logic.
Diffstat (limited to 'source/blender/depsgraph')
-rw-r--r--source/blender/depsgraph/CMakeLists.txt2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder.cc9
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder.h5
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_cache.cc186
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_cache.h103
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc6
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.h3
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc6
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.h3
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_rna.cc7
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_rna.h4
-rw-r--r--source/blender/depsgraph/intern/depsgraph_build.cc6
12 files changed, 324 insertions, 16 deletions
diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt
index e30b77ea742..aee925ad8f8 100644
--- a/source/blender/depsgraph/CMakeLists.txt
+++ b/source/blender/depsgraph/CMakeLists.txt
@@ -37,6 +37,7 @@ set(INC_SYS
set(SRC
intern/builder/deg_builder.cc
+ intern/builder/deg_builder_cache.cc
intern/builder/deg_builder_cycle.cc
intern/builder/deg_builder_map.cc
intern/builder/deg_builder_nodes.cc
@@ -82,6 +83,7 @@ set(SRC
DEG_depsgraph_query.h
intern/builder/deg_builder.h
+ intern/builder/deg_builder_cache.h
intern/builder/deg_builder_cycle.h
intern/builder/deg_builder_map.h
intern/builder/deg_builder_nodes.h
diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc
index ef36dec6f34..bcf397da335 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder.cc
@@ -55,6 +55,11 @@ namespace DEG {
* Base class for builders.
*/
+DepsgraphBuilder::DepsgraphBuilder(Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache)
+ : bmain_(bmain), graph_(graph), cache_(cache)
+{
+}
+
namespace {
struct VisibilityCheckData {
@@ -108,10 +113,6 @@ bool deg_check_base_available_for_build(const Depsgraph *graph, Base *base)
return false;
}
-DepsgraphBuilder::DepsgraphBuilder(Main *bmain, Depsgraph *graph) : bmain_(bmain), graph_(graph)
-{
-}
-
bool DepsgraphBuilder::need_pull_base_into_graph(Base *base)
{
return deg_check_base_available_for_build(graph_, base);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder.h b/source/blender/depsgraph/intern/builder/deg_builder.h
index 310944f2f28..88df0e870f3 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder.h
@@ -29,17 +29,20 @@ struct Main;
namespace DEG {
struct Depsgraph;
+class DepsgraphBuilderCache;
class DepsgraphBuilder {
public:
bool need_pull_base_into_graph(struct Base *base);
protected:
- DepsgraphBuilder(Main *bmain, Depsgraph *graph);
+ /* NOTE: The builder does NOT take ownership over any of those resources. */
+ DepsgraphBuilder(Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache);
/* State which never changes, same for the whole builder time. */
Main *bmain_;
Depsgraph *graph_;
+ DepsgraphBuilderCache *cache_;
};
bool deg_check_base_available_for_build(const Depsgraph *graph, Base *base);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_cache.cc b/source/blender/depsgraph/intern/builder/deg_builder_cache.cc
new file mode 100644
index 00000000000..3df707e92c1
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/deg_builder_cache.cc
@@ -0,0 +1,186 @@
+/*
+ * 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) 2018 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#include "intern/builder/deg_builder_cache.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_anim_types.h"
+
+#include "BLI_utildefines.h"
+
+extern "C" {
+#include "BKE_animsys.h"
+}
+
+namespace DEG {
+
+/* Animated property storage. */
+
+AnimatedPropertyID::AnimatedPropertyID() : data(NULL), property_rna(NULL)
+{
+}
+
+AnimatedPropertyID::AnimatedPropertyID(const PointerRNA *pointer_rna,
+ const PropertyRNA *property_rna)
+ : AnimatedPropertyID(*pointer_rna, property_rna)
+{
+}
+
+AnimatedPropertyID::AnimatedPropertyID(const PointerRNA &pointer_rna,
+ const PropertyRNA *property_rna)
+ : data(pointer_rna.data), property_rna(property_rna)
+{
+}
+
+AnimatedPropertyID::AnimatedPropertyID(ID *id, StructRNA *type, const char *property_name)
+ : data(id)
+{
+ property_rna = RNA_struct_type_find_property(type, property_name);
+}
+
+AnimatedPropertyID::AnimatedPropertyID(ID * /*id*/,
+ StructRNA *type,
+ void *data,
+ const char *property_name)
+ : data(data)
+{
+ property_rna = RNA_struct_type_find_property(type, property_name);
+}
+
+bool AnimatedPropertyID::operator<(const AnimatedPropertyID &other) const
+{
+ if (data < other.data) {
+ return true;
+ }
+ else if (data == other.data) {
+ return property_rna < other.property_rna;
+ }
+ return false;
+}
+
+namespace {
+
+struct AnimatedPropertyCallbackData {
+ PointerRNA pointer_rna;
+ AnimatedPropertyStorage *animated_property_storage;
+ DepsgraphBuilderCache *builder_cache;
+};
+
+void animated_property_cb(ID * /*id*/, FCurve *fcurve, void *data_v)
+{
+ if (fcurve->rna_path == NULL || fcurve->rna_path[0] == '\0') {
+ return;
+ }
+ AnimatedPropertyCallbackData *data = static_cast<AnimatedPropertyCallbackData *>(data_v);
+ /* Resolve property. */
+ PointerRNA pointer_rna;
+ PropertyRNA *property_rna = NULL;
+ if (!RNA_path_resolve_property(
+ &data->pointer_rna, fcurve->rna_path, &pointer_rna, &property_rna)) {
+ return;
+ }
+ /* Get storage for the ID.
+ * This is needed to deal with cases when nested datablock is animated by its parent. */
+ AnimatedPropertyStorage *animated_property_storage = data->animated_property_storage;
+ if (pointer_rna.id.data != data->pointer_rna.id.data) {
+ animated_property_storage = data->builder_cache->ensureAnimatedPropertyStorage(
+ reinterpret_cast<ID *>(pointer_rna.id.data));
+ }
+ /* Set the property as animated. */
+ animated_property_storage->tagPropertyAsAnimated(&pointer_rna, property_rna);
+}
+
+} // namespace
+
+AnimatedPropertyStorage::AnimatedPropertyStorage() : is_fully_initialized(false)
+{
+}
+
+void AnimatedPropertyStorage::initializeFromID(DepsgraphBuilderCache *builder_cache, ID *id)
+{
+ AnimatedPropertyCallbackData data;
+ RNA_id_pointer_create(id, &data.pointer_rna);
+ data.animated_property_storage = this;
+ data.builder_cache = builder_cache;
+ BKE_fcurves_id_cb(id, animated_property_cb, &data);
+}
+
+void AnimatedPropertyStorage::tagPropertyAsAnimated(const AnimatedPropertyID &property_id)
+{
+ animated_properties_set.insert(property_id);
+}
+
+void AnimatedPropertyStorage::tagPropertyAsAnimated(const PointerRNA *pointer_rna,
+ const PropertyRNA *property_rna)
+{
+ tagPropertyAsAnimated(AnimatedPropertyID(pointer_rna, property_rna));
+}
+
+bool AnimatedPropertyStorage::isPropertyAnimated(const AnimatedPropertyID &property_id)
+{
+ return animated_properties_set.find(property_id) != animated_properties_set.end();
+}
+
+bool AnimatedPropertyStorage::isPropertyAnimated(const PointerRNA *pointer_rna,
+ const PropertyRNA *property_rna)
+{
+ return isPropertyAnimated(AnimatedPropertyID(pointer_rna, property_rna));
+}
+
+/* Builder cache itself. */
+
+DepsgraphBuilderCache::DepsgraphBuilderCache()
+{
+}
+
+DepsgraphBuilderCache::~DepsgraphBuilderCache()
+{
+ for (AnimatedPropertyStorageMap::value_type &iter : animated_property_storage_map_) {
+ AnimatedPropertyStorage *animated_property_storage = iter.second;
+ OBJECT_GUARDED_DELETE(animated_property_storage, AnimatedPropertyStorage);
+ }
+}
+
+AnimatedPropertyStorage *DepsgraphBuilderCache::ensureAnimatedPropertyStorage(ID *id)
+{
+ AnimatedPropertyStorageMap::iterator it = animated_property_storage_map_.find(id);
+ if (it != animated_property_storage_map_.end()) {
+ return it->second;
+ }
+ AnimatedPropertyStorage *animated_property_storage = OBJECT_GUARDED_NEW(AnimatedPropertyStorage);
+ animated_property_storage_map_.insert(make_pair(id, animated_property_storage));
+ return animated_property_storage;
+}
+
+AnimatedPropertyStorage *DepsgraphBuilderCache::ensureInitializedAnimatedPropertyStorage(ID *id)
+{
+ AnimatedPropertyStorage *animated_property_storage = ensureAnimatedPropertyStorage(id);
+ if (!animated_property_storage->is_fully_initialized) {
+ animated_property_storage->initializeFromID(this, id);
+ animated_property_storage->is_fully_initialized = true;
+ }
+ return animated_property_storage;
+}
+
+} // namespace DEG
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_cache.h b/source/blender/depsgraph/intern/builder/deg_builder_cache.h
new file mode 100644
index 00000000000..949020e3a81
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/deg_builder_cache.h
@@ -0,0 +1,103 @@
+/*
+ * 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) 2018 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#pragma once
+
+#include "intern/depsgraph_type.h"
+
+#include "RNA_access.h"
+
+struct ID;
+struct PointerRNA;
+struct PropertyRNA;
+
+namespace DEG {
+
+class DepsgraphBuilderCache;
+
+/* Identifier for animated property. */
+class AnimatedPropertyID {
+ public:
+ AnimatedPropertyID();
+ AnimatedPropertyID(const PointerRNA *pointer_rna, const PropertyRNA *property_rna);
+ AnimatedPropertyID(const PointerRNA &pointer_rna, const PropertyRNA *property_rna);
+ AnimatedPropertyID(ID *id, StructRNA *type, const char *property_name);
+ AnimatedPropertyID(ID *id, StructRNA *type, void *data, const char *property_name);
+
+ bool operator<(const AnimatedPropertyID &other) const;
+
+ /* Corresponds to PointerRNA.data. */
+ void *data;
+ const PropertyRNA *property_rna;
+};
+
+class AnimatedPropertyStorage {
+ public:
+ AnimatedPropertyStorage();
+
+ void initializeFromID(DepsgraphBuilderCache *builder_cache, ID *id);
+
+ void tagPropertyAsAnimated(const AnimatedPropertyID &property_id);
+ void tagPropertyAsAnimated(const PointerRNA *pointer_rna, const PropertyRNA *property_rna);
+
+ bool isPropertyAnimated(const AnimatedPropertyID &property_id);
+ bool isPropertyAnimated(const PointerRNA *pointer_rna, const PropertyRNA *property_rna);
+
+ /* The storage is fully initialized from all F-Curves from corresponding ID. */
+ bool is_fully_initialized;
+
+ /* indexed by PointerRNA.data. */
+ set<AnimatedPropertyID> animated_properties_set;
+};
+
+typedef map<ID *, AnimatedPropertyStorage *> AnimatedPropertyStorageMap;
+
+/* Cached data which can be re-used by multiple builders. */
+class DepsgraphBuilderCache {
+ public:
+ DepsgraphBuilderCache();
+ ~DepsgraphBuilderCache();
+
+ /* Makes sure storage for animated properties exists and initialized for the given ID. */
+ AnimatedPropertyStorage *ensureAnimatedPropertyStorage(ID *id);
+ AnimatedPropertyStorage *ensureInitializedAnimatedPropertyStorage(ID *id);
+
+ /* Shortcuts to go through ensureInitializedAnimatedPropertyStorage and its
+ * isPropertyAnimated.
+ *
+ * NOTE: Avoid using for multiple subsequent lookups, query for the storage once, and then query
+ * the storage.
+ *
+ * TODO(sergey): Technically, this makes this class something else than just a cache, but what is
+ * the better name? */
+ template<typename... Args> bool isPropertyAnimated(ID *id, Args... args)
+ {
+ AnimatedPropertyStorage *animated_property_storage = ensureInitializedAnimatedPropertyStorage(
+ id);
+ return animated_property_storage->isPropertyAnimated(args...);
+ }
+
+ AnimatedPropertyStorageMap animated_property_storage_map_;
+};
+
+} // namespace DEG
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index a4c269886a3..27823bffb87 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -129,8 +129,10 @@ void free_copy_on_write_datablock(void *id_info_v)
/* **** General purpose functions **** */
-DepsgraphNodeBuilder::DepsgraphNodeBuilder(Main *bmain, Depsgraph *graph)
- : DepsgraphBuilder(bmain, graph),
+DepsgraphNodeBuilder::DepsgraphNodeBuilder(Main *bmain,
+ Depsgraph *graph,
+ DepsgraphBuilderCache *cache)
+ : DepsgraphBuilder(bmain, graph, cache),
scene_(NULL),
view_layer_(NULL),
view_layer_index_(-1),
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
index d88f5a792e0..cf7cf1a62d8 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
@@ -69,6 +69,7 @@ namespace DEG {
struct ComponentNode;
struct Depsgraph;
+class DepsgraphBuilderCache;
struct IDNode;
struct Node;
struct OperationNode;
@@ -76,7 +77,7 @@ struct TimeSourceNode;
class DepsgraphNodeBuilder : public DepsgraphBuilder {
public:
- DepsgraphNodeBuilder(Main *bmain, Depsgraph *graph);
+ DepsgraphNodeBuilder(Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache);
~DepsgraphNodeBuilder();
/* For given original ID get ID which is created by CoW system. */
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 9ea41e54a59..36cc105273d 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -209,8 +209,10 @@ static bool bone_has_segments(Object *object, const char *bone_name)
/* **** General purpose functions **** */
-DepsgraphRelationBuilder::DepsgraphRelationBuilder(Main *bmain, Depsgraph *graph)
- : DepsgraphBuilder(bmain, graph), scene_(NULL), rna_node_query_(graph)
+DepsgraphRelationBuilder::DepsgraphRelationBuilder(Main *bmain,
+ Depsgraph *graph,
+ DepsgraphBuilderCache *cache)
+ : DepsgraphBuilder(bmain, graph, cache), scene_(NULL), rna_node_query_(graph, this)
{
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
index 5b2d34a270c..90bdb9bae65 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
@@ -86,6 +86,7 @@ namespace DEG {
struct ComponentNode;
struct DepsNodeHandle;
struct Depsgraph;
+class DepsgraphBuilderCache;
struct IDNode;
struct Node;
struct OperationNode;
@@ -155,7 +156,7 @@ struct RNAPathKey {
class DepsgraphRelationBuilder : public DepsgraphBuilder {
public:
- DepsgraphRelationBuilder(Main *bmain, Depsgraph *graph);
+ DepsgraphRelationBuilder(Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache);
void begin_build();
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
index 27899abc972..ac4e8e84d44 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
@@ -45,6 +45,7 @@ extern "C" {
#include "RNA_access.h"
#include "intern/depsgraph.h"
+#include "intern/builder/deg_builder.h"
#include "intern/node/deg_node.h"
#include "intern/node/deg_node_component.h"
#include "intern/node/deg_node_id.h"
@@ -130,8 +131,10 @@ void ghash_id_data_free_func(void *value)
} // namespace
-RNANodeQuery::RNANodeQuery(Depsgraph *depsgraph)
- : depsgraph_(depsgraph), id_data_map_(BLI_ghash_ptr_new("rna node query id data hash"))
+RNANodeQuery::RNANodeQuery(Depsgraph *depsgraph, DepsgraphBuilder *builder)
+ : depsgraph_(depsgraph),
+ builder_(builder),
+ id_data_map_(BLI_ghash_ptr_new("rna node query id data hash"))
{
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.h b/source/blender/depsgraph/intern/builder/deg_builder_rna.h
index e8dbd7fb523..26d7963e0a8 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_rna.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.h
@@ -36,6 +36,7 @@ namespace DEG {
struct Depsgraph;
struct Node;
class RNANodeQueryIDData;
+class DepsgraphBuilder;
/* For queries which gives operation node or key defines whether we are
* interested in a result of the given property or whether we are linking some
@@ -72,13 +73,14 @@ class RNANodeIdentifier {
* dependency graph which satisfies given RNA pointer or RAN path. */
class RNANodeQuery {
public:
- RNANodeQuery(Depsgraph *depsgraph);
+ RNANodeQuery(Depsgraph *depsgraph, DepsgraphBuilder *builder);
~RNANodeQuery();
Node *find_node(const PointerRNA *ptr, const PropertyRNA *prop, RNAPointerSource source);
protected:
Depsgraph *depsgraph_;
+ DepsgraphBuilder *builder_;
/* Indexed by an ID, returns RNANodeQueryIDData associated with that ID. */
GHash *id_data_map_;
diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc
index e4c84264960..dd2979160cd 100644
--- a/source/blender/depsgraph/intern/depsgraph_build.cc
+++ b/source/blender/depsgraph/intern/depsgraph_build.cc
@@ -46,6 +46,7 @@ extern "C" {
#include "DEG_depsgraph_build.h"
#include "builder/deg_builder.h"
+#include "builder/deg_builder_cache.h"
#include "builder/deg_builder_cycle.h"
#include "builder/deg_builder_nodes.h"
#include "builder/deg_builder_relations.h"
@@ -238,14 +239,15 @@ void DEG_graph_build_from_view_layer(Depsgraph *graph,
BLI_assert(BLI_findindex(&scene->view_layers, view_layer) != -1);
BLI_assert(deg_graph->scene == scene);
BLI_assert(deg_graph->view_layer == view_layer);
+ DEG::DepsgraphBuilderCache builder_cache;
/* Generate all the nodes in the graph first */
- DEG::DepsgraphNodeBuilder node_builder(bmain, deg_graph);
+ DEG::DepsgraphNodeBuilder node_builder(bmain, deg_graph, &builder_cache);
node_builder.begin_build();
node_builder.build_view_layer(scene, view_layer, DEG::DEG_ID_LINKED_DIRECTLY);
node_builder.end_build();
/* Hook up relationships between operations - to determine evaluation
* order. */
- DEG::DepsgraphRelationBuilder relation_builder(bmain, deg_graph);
+ DEG::DepsgraphRelationBuilder relation_builder(bmain, deg_graph, &builder_cache);
relation_builder.begin_build();
relation_builder.build_view_layer(scene, view_layer);
relation_builder.build_copy_on_write_relations();