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>2017-10-18 15:35:34 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2017-10-18 15:35:34 +0300
commit3e8abc0535aaeb736310a1b7a5447df1721ff349 (patch)
treede35daa1ec122c33b2e6803cb7cb61bb20406882 /source/blender/depsgraph
parent46f0b97d208c21d3ce192b71b65e1fa0776f7825 (diff)
Depsgraph: Make Copy-on-Write a command line option
Before it was a compile time option which was not very easy to use or test. Now the project is getting more mature, so very soon we will be able to call for a public tests of limited features. The copy-on-write (which includes animation, modifiers) is enabled using --enable-copy-on-write command line argument.
Diffstat (limited to 'source/blender/depsgraph')
-rw-r--r--source/blender/depsgraph/CMakeLists.txt4
-rw-r--r--source/blender/depsgraph/DEG_depsgraph.h3
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder.cc10
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc40
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.h13
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_layer.cc14
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc28
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc24
-rw-r--r--source/blender/depsgraph/intern/depsgraph.cc24
-rw-r--r--source/blender/depsgraph/intern/depsgraph_build.cc6
-rw-r--r--source/blender/depsgraph/intern/depsgraph_tag.cc23
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_flush.cc6
-rw-r--r--source/blender/depsgraph/intern/nodes/deg_node.cc16
13 files changed, 112 insertions, 99 deletions
diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt
index 17a13b66aaa..b4509c7a61a 100644
--- a/source/blender/depsgraph/CMakeLists.txt
+++ b/source/blender/depsgraph/CMakeLists.txt
@@ -128,8 +128,4 @@ if(WITH_OPENSUBDIV)
add_definitions(-DWITH_OPENSUBDIV)
endif()
-if(WITH_DEPSGRAPH_COPY_ON_WRITE)
- add_definitions(-DWITH_COPY_ON_WRITE)
-endif()
-
blender_add_lib(bf_depsgraph "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/depsgraph/DEG_depsgraph.h b/source/blender/depsgraph/DEG_depsgraph.h
index f925c37e23e..894adbee8c9 100644
--- a/source/blender/depsgraph/DEG_depsgraph.h
+++ b/source/blender/depsgraph/DEG_depsgraph.h
@@ -105,6 +105,9 @@ enum {
extern "C" {
#endif
+bool DEG_depsgraph_use_copy_on_write(void);
+void DEG_depsgraph_enable_copy_on_write(void);
+
/* ************************************************ */
/* Depsgraph API */
diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc
index deee2227f81..587d2021b52 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder.cc
@@ -47,6 +47,7 @@ namespace DEG {
void deg_graph_build_finalize(Depsgraph *graph)
{
+ const bool use_copy_on_write = DEG_depsgraph_use_copy_on_write();
/* Re-tag IDs for update if it was tagged before the relations
* update tag.
*/
@@ -63,9 +64,12 @@ void deg_graph_build_finalize(Depsgraph *graph)
id_node->tag_update(graph);
}
}
-#ifdef WITH_COPY_ON_WRITE
- DEG_id_tag_update_ex(graph->bmain, id_node->id_orig, DEG_TAG_COPY_ON_WRITE);
-#endif
+ /* TODO(sergey): This is not ideal at all, since this forces
+ * re-evaluaiton of the whole tree.
+ */
+ if (use_copy_on_write) {
+ DEG_id_tag_update_ex(graph->bmain, id_node->id_orig, DEG_TAG_COPY_ON_WRITE);
+ }
}
GHASH_FOREACH_END();
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 02d20913177..a4c3c11d922 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -174,7 +174,9 @@ DepsgraphNodeBuilder::~DepsgraphNodeBuilder()
IDDepsNode *DepsgraphNodeBuilder::add_id_node(ID *id, bool do_tag)
{
-#ifdef WITH_COPY_ON_WRITE
+ if (!DEG_depsgraph_use_copy_on_write()) {
+ return m_graph->add_id_node(id);
+ }
IDDepsNode *id_node = NULL;
ID *id_cow = (ID *)BLI_ghash_lookup(m_cow_id_hash, id);
if (id_cow != NULL) {
@@ -197,10 +199,6 @@ IDDepsNode *DepsgraphNodeBuilder::add_id_node(ID *id, bool do_tag)
"", -1);
m_graph->operations.push_back(op_cow);
}
-#else
- IDDepsNode *id_node = m_graph->add_id_node(id);
- UNUSED_VARS(do_tag);
-#endif
return id_node;
}
@@ -358,23 +356,25 @@ void DepsgraphNodeBuilder::begin_build(Main *bmain) {
}
FOREACH_NODETREE_END;
-#ifdef WITH_COPY_ON_WRITE
- /* Store existing copy-on-write versions of datablock, so we can re-use
- * them for new ID nodes.
- */
- m_cow_id_hash = BLI_ghash_ptr_new("Depsgraph id hash");
- GHASH_FOREACH_BEGIN(IDDepsNode *, id_node, m_graph->id_hash)
- {
- if (GS(id_node->id_orig->name) != ID_SCE) {
- continue;
- }
- if (deg_copy_on_write_is_expanded(id_node->id_cow)) {
- BLI_ghash_insert(m_cow_id_hash, id_node->id_orig, id_node->id_cow);
- id_node->id_cow = NULL;
+ if (DEG_depsgraph_use_copy_on_write()) {
+ /* Store existing copy-on-write versions of datablock, so we can re-use
+ * them for new ID nodes.
+ */
+ m_cow_id_hash = BLI_ghash_ptr_new("Depsgraph id hash");
+ GHASH_FOREACH_BEGIN(IDDepsNode *, id_node, m_graph->id_hash)
+ {
+ if (GS(id_node->id_orig->name) != ID_SCE) {
+ continue;
+ }
+ if (deg_copy_on_write_is_expanded(id_node->id_cow)) {
+ BLI_ghash_insert(m_cow_id_hash,
+ id_node->id_orig,
+ id_node->id_cow);
+ id_node->id_cow = NULL;
+ }
}
+ GHASH_FOREACH_END();
}
- GHASH_FOREACH_END();
-#endif
/* Make sure graph has no nodes left from previous state. */
m_graph->clear_all_nodes();
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
index 7e28df1276d..dbb126e2078 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
@@ -32,6 +32,8 @@
#include "intern/depsgraph_types.h"
+#include "DEG_depsgraph.h" /* used for DEG_depsgraph_use_copy_on_write() */
+
struct CacheFile;
struct bGPdata;
struct ListBase;
@@ -98,11 +100,12 @@ struct DepsgraphNodeBuilder {
/* For a given COW datablock get corresponding original one. */
template<typename T>
T *get_orig_datablock(const T *cow) const {
-#ifdef WITH_COPY_ON_WRITE
- return (T *)cow->id.newid;
-#else
- return (T *)cow;
-#endif
+ if (DEG_depsgraph_use_copy_on_write()) {
+ return (T *)cow->id.newid;
+ }
+ else {
+ return (T *)cow;
+ }
}
void begin_build(Main *bmain);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer.cc
index b3a88d8ac4d..660d7fedb52 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer.cc
@@ -96,12 +96,14 @@ void DepsgraphNodeBuilder::build_layer_collections(Scene *scene,
void DepsgraphNodeBuilder::build_scene_layer_collections(Scene *scene)
{
-#ifdef WITH_COPY_ON_WRITE
- /* Make sure we've got ID node, so we can get pointer to CoW datablock. */
- Scene *scene_cow = expand_cow_datablock(scene);
-#else
- Scene *scene_cow = scene;
-#endif
+ Scene *scene_cow;
+ if (DEG_depsgraph_use_copy_on_write()) {
+ /* Make sure we've got ID node, so we can get pointer to CoW datablock. */
+ scene_cow = expand_cow_datablock(scene);
+ }
+ else {
+ scene_cow = scene;
+ }
LayerCollectionState state;
state.index = 0;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
index eb7fbaefb95..20263e1d751 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
@@ -138,18 +138,22 @@ void DepsgraphNodeBuilder::build_rig(Scene *scene, Object *object)
{
bArmature *armature = (bArmature *)object->data;
const short armature_tag = armature->id.tag;
-#ifdef WITH_COPY_ON_WRITE
- /* NOTE: We need to expand both object and armature, so this way we can
- * safely create object level pose.
- */
- Scene *scene_cow = get_cow_datablock(scene);
- Object *object_cow = expand_cow_datablock(object);
- bArmature *armature_cow = expand_cow_datablock(armature);
-#else
- Scene *scene_cow = scene;
- Object *object_cow = object;
- bArmature *armature_cow = armature;
-#endif
+ Scene *scene_cow;
+ Object *object_cow;
+ bArmature *armature_cow;
+ if (DEG_depsgraph_use_copy_on_write()) {
+ /* NOTE: We need to expand both object and armature, so this way we can
+ * safely create object level pose.
+ */
+ scene_cow = get_cow_datablock(scene);
+ object_cow = expand_cow_datablock(object);
+ armature_cow = expand_cow_datablock(armature);
+ }
+ else {
+ scene_cow = scene;
+ object_cow = object;
+ armature_cow = armature;
+ }
OperationDepsNode *op_node;
/* Animation and/or drivers linking posebones to base-armature used to
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 0c5150f2f42..10c4c44d14e 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -1803,18 +1803,18 @@ void DepsgraphRelationBuilder::build_lamp(Object *ob)
/* textures */
build_texture_stack(la->mtex);
-#ifdef WITH_COPY_ON_WRITE
- /* Make sure copy on write of lamp data is always properly updated for
- * visible lamps.
- */
- OperationKey ob_copy_on_write_key(&ob->id,
- DEG_NODE_TYPE_COPY_ON_WRITE,
- DEG_OPCODE_COPY_ON_WRITE);
- OperationKey lamp_copy_on_write_key(lamp_id,
- DEG_NODE_TYPE_COPY_ON_WRITE,
- DEG_OPCODE_COPY_ON_WRITE);
- add_relation(lamp_copy_on_write_key, ob_copy_on_write_key, "Eval Order");
-#endif
+ if (DEG_depsgraph_use_copy_on_write()) {
+ /* Make sure copy on write of lamp data is always properly updated for
+ * visible lamps.
+ */
+ OperationKey ob_copy_on_write_key(&ob->id,
+ DEG_NODE_TYPE_COPY_ON_WRITE,
+ DEG_OPCODE_COPY_ON_WRITE);
+ OperationKey lamp_copy_on_write_key(lamp_id,
+ DEG_NODE_TYPE_COPY_ON_WRITE,
+ DEG_OPCODE_COPY_ON_WRITE);
+ add_relation(lamp_copy_on_write_key, ob_copy_on_write_key, "Eval Order");
+ }
}
void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree)
diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc
index 81a4f2bc0cc..b146d4a432b 100644
--- a/source/blender/depsgraph/intern/depsgraph.cc
+++ b/source/blender/depsgraph/intern/depsgraph.cc
@@ -62,6 +62,18 @@ extern "C" {
#include "intern/depsgraph_intern.h"
#include "util/deg_util_foreach.h"
+static bool use_copy_on_write = true;
+
+bool DEG_depsgraph_use_copy_on_write(void)
+{
+ return use_copy_on_write;
+}
+
+void DEG_depsgraph_enable_copy_on_write(void)
+{
+ use_copy_on_write = true;
+}
+
namespace DEG {
static DEG_EditorUpdateIDCb deg_editor_update_id_cb = NULL;
@@ -252,14 +264,6 @@ DepsNode *Depsgraph::find_node_from_pointer(const PointerRNA *ptr,
/* Node Management ---------------------------- */
-#ifndef WITH_COPY_ON_WRITE
-static void id_node_deleter(void *value)
-{
- IDDepsNode *id_node = reinterpret_cast<IDDepsNode *>(value);
- OBJECT_GUARDED_DELETE(id_node, IDDepsNode);
-}
-#endif
-
TimeSourceDepsNode *Depsgraph::add_time_source()
{
if (time_source == NULL) {
@@ -305,9 +309,6 @@ IDDepsNode *Depsgraph::add_id_node(ID *id, bool do_tag, ID *id_cow_hint)
void Depsgraph::clear_id_nodes()
{
-#ifndef WITH_COPY_ON_WRITE
- BLI_ghash_clear(id_hash, NULL, id_node_deleter);
-#else
/* Stupid workaround to ensure we free IDs in a proper order. */
GHASH_FOREACH_BEGIN(IDDepsNode *, id_node, id_hash)
{
@@ -331,7 +332,6 @@ void Depsgraph::clear_id_nodes()
OBJECT_GUARDED_DELETE(id_node, IDDepsNode);
}
GHASH_FOREACH_END();
-#endif
}
/* Add new relationship between two nodes. */
diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc
index e21c3d29aa5..e4b6434b9c7 100644
--- a/source/blender/depsgraph/intern/depsgraph_build.cc
+++ b/source/blender/depsgraph/intern/depsgraph_build.cc
@@ -216,9 +216,9 @@ void DEG_graph_build_from_scene(Depsgraph *graph, Main *bmain, Scene *scene)
DEG::DepsgraphRelationBuilder relation_builder(deg_graph);
relation_builder.begin_build(bmain);
relation_builder.build_scene(bmain, scene);
-#ifdef WITH_COPY_ON_WRITE
- relation_builder.build_copy_on_write_relations();
-#endif
+ if (DEG_depsgraph_use_copy_on_write()) {
+ relation_builder.build_copy_on_write_relations();
+ }
/* Detect and solve cycles. */
DEG::deg_graph_detect_cycles(deg_graph);
diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc
index 0df2420d662..927593b6d8f 100644
--- a/source/blender/depsgraph/intern/depsgraph_tag.cc
+++ b/source/blender/depsgraph/intern/depsgraph_tag.cc
@@ -269,16 +269,17 @@ void id_tag_update_shading(Depsgraph *graph, IDDepsNode *id_node)
shading_comp->tag_update(graph);
}
-#ifdef WITH_COPY_ON_WRITE
/* Tag corresponding to DEG_TAG_COPY_ON_WRITE. */
void id_tag_update_copy_on_write(Depsgraph *graph, IDDepsNode *id_node)
{
+ if (!DEG_depsgraph_use_copy_on_write()) {
+ return;
+ }
ComponentDepsNode *cow_comp =
id_node->find_component(DEG_NODE_TYPE_COPY_ON_WRITE);
OperationDepsNode *cow_node = cow_comp->get_entry_operation();
cow_node->tag_update(graph);
}
-#endif
void id_tag_update_ntree_special(Main *bmain, Depsgraph *graph, ID *id, int flag)
{
@@ -320,16 +321,16 @@ void deg_graph_id_tag_update(Main *bmain, Depsgraph *graph, ID *id, int flag)
}
if (flag & OB_RECALC_DATA) {
id_tag_update_object_data(graph, id_node);
-#ifdef WITH_COPY_ON_WRITE
- if (flag & DEG_TAG_COPY_ON_WRITE) {
- const ID_Type id_type = GS(id_node->id_orig->name);
- if (id_type == ID_OB) {
- Object *object = (Object *)id_node->id_orig;
- ID *ob_data = (ID *)object->data;
- DEG_id_tag_update_ex(bmain, ob_data, flag);
+ if (DEG_depsgraph_use_copy_on_write()) {
+ if (flag & DEG_TAG_COPY_ON_WRITE) {
+ const ID_Type id_type = GS(id_node->id_orig->name);
+ if (id_type == ID_OB) {
+ Object *object = (Object *)id_node->id_orig;
+ ID *ob_data = (ID *)object->data;
+ DEG_id_tag_update_ex(bmain, ob_data, flag);
+ }
}
}
-#endif
}
if (flag & OB_RECALC_TIME) {
id_tag_update_object_time(graph, id_node);
@@ -340,11 +341,9 @@ void deg_graph_id_tag_update(Main *bmain, Depsgraph *graph, ID *id, int flag)
if (flag & DEG_TAG_SHADING_UPDATE) {
id_tag_update_shading(graph, id_node);
}
-#ifdef WITH_COPY_ON_WRITE
if (flag & DEG_TAG_COPY_ON_WRITE) {
id_tag_update_copy_on_write(graph, id_node);
}
-#endif
id_tag_update_ntree_special(bmain, graph, id, flag);
}
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
index 54a3a499e36..86e69458f41 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
@@ -82,6 +82,7 @@ static void flush_init_func(void *data_v, int i)
*/
void deg_graph_flush_updates(Main *bmain, Depsgraph *graph)
{
+ const bool use_copy_on_write = DEG_depsgraph_use_copy_on_write();
/* Sanity check. */
if (graph == NULL) {
return;
@@ -146,18 +147,17 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph)
}
if (comp_node->done != COMPONENT_STATE_DONE) {
-#ifdef WITH_COPY_ON_WRITE
/* Currently this is needed to get ob->mesh to be replaced with
* original mesh (rather than being evaluated_mesh).
*
* TODO(sergey): This is something we need to avoid.
*/
- if (comp_node->depends_on_cow()) {
+ if (use_copy_on_write && comp_node->depends_on_cow()) {
ComponentDepsNode *cow_comp =
id_node->find_component(DEG_NODE_TYPE_COPY_ON_WRITE);
cow_comp->tag_update(graph);
}
-#endif
+
Object *object = NULL;
if (GS(id_orig->name) == ID_OB) {
object = (Object *)id_orig;
diff --git a/source/blender/depsgraph/intern/nodes/deg_node.cc b/source/blender/depsgraph/intern/nodes/deg_node.cc
index 5e7ed249365..b313059e1bd 100644
--- a/source/blender/depsgraph/intern/nodes/deg_node.cc
+++ b/source/blender/depsgraph/intern/nodes/deg_node.cc
@@ -177,7 +177,14 @@ void IDDepsNode::init(const ID *id, const char *UNUSED(subdata))
void IDDepsNode::init_copy_on_write(ID *id_cow_hint)
{
-#ifdef WITH_COPY_ON_WRITE
+ /* Early output for non-copy-on-write case: we keep CoW pointer same as
+ * an original one.
+ */
+ if (!DEG_depsgraph_use_copy_on_write()) {
+ UNUSED_VARS(id_cow_hint);
+ id_cow = id_orig;
+ return;
+ }
/* Create pointer as early as possible, so we can use it for function
* bindings. Rest of data we'll be copying to the new datablock when
* it is actually needed.
@@ -200,10 +207,6 @@ void IDDepsNode::init_copy_on_write(ID *id_cow_hint)
else {
id_cow = id_orig;
}
-#else
- UNUSED_VARS(id_cow_hint);
- id_cow = id_orig;
-#endif
}
/* Free 'id' node. */
@@ -222,7 +225,6 @@ void IDDepsNode::destroy()
id_deps_node_hash_key_free,
id_deps_node_hash_value_free);
-#ifdef WITH_COPY_ON_WRITE
/* Free memory used by this CoW ID. */
if (id_cow != id_orig && id_cow != NULL) {
deg_free_copy_on_write_datablock(id_cow);
@@ -230,7 +232,7 @@ void IDDepsNode::destroy()
DEG_COW_PRINT("Destroy CoW for %s: id_orig=%p id_cow=%p\n",
id_orig->name, id_orig, id_cow);
}
-#endif
+
/* Tag that the node is freed. */
id_orig = NULL;
}