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
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-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();