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/intern/depsgraph.cc')
-rw-r--r--source/blender/depsgraph/intern/depsgraph.cc87
1 files changed, 76 insertions, 11 deletions
diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc
index aa21f0995be..9f25fcaaa32 100644
--- a/source/blender/depsgraph/intern/depsgraph.cc
+++ b/source/blender/depsgraph/intern/depsgraph.cc
@@ -46,8 +46,6 @@ extern "C" {
#include "DNA_object_types.h"
#include "DNA_sequence_types.h"
-#include "BKE_depsgraph.h"
-
#include "RNA_access.h"
}
@@ -55,6 +53,8 @@ extern "C" {
#include "DEG_depsgraph.h"
+#include "intern/eval/deg_eval_copy_on_write.h"
+
#include "intern/nodes/deg_node.h"
#include "intern/nodes/deg_node_component.h"
#include "intern/nodes/deg_node_operation.h"
@@ -70,8 +70,7 @@ static DEG_EditorUpdateScenePreCb deg_editor_update_scene_pre_cb = NULL;
Depsgraph::Depsgraph()
: time_source(NULL),
- need_update(false),
- layers(0)
+ need_update(false)
{
BLI_spin_init(&lock);
id_hash = BLI_ghash_ptr_new("Depsgraph id hash");
@@ -253,11 +252,13 @@ 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()
{
@@ -278,22 +279,58 @@ IDDepsNode *Depsgraph::find_id_node(const ID *id) const
return reinterpret_cast<IDDepsNode *>(BLI_ghash_lookup(id_hash, id));
}
-IDDepsNode *Depsgraph::add_id_node(ID *id, const char *name)
+IDDepsNode *Depsgraph::add_id_node(ID *id, bool do_tag, ID *id_cow_hint)
{
+ BLI_assert((id->tag & LIB_TAG_COPY_ON_WRITE) == 0);
IDDepsNode *id_node = find_id_node(id);
if (!id_node) {
DepsNodeFactory *factory = deg_get_node_factory(DEG_NODE_TYPE_ID_REF);
- id_node = (IDDepsNode *)factory->create_node(id, "", name);
- id->tag |= LIB_TAG_DOIT;
- /* register */
+ id_node = (IDDepsNode *)factory->create_node(id, "", id->name);
+ id_node->init_copy_on_write(id_cow_hint);
+ if (do_tag) {
+ id->tag |= LIB_TAG_DOIT;
+ }
+ /* Register node in ID hash.
+ *
+ * NOTE: We address ID nodes by the original ID pointer they are
+ * referencing to.
+ */
BLI_ghash_insert(id_hash, id, id_node);
+ } else if (do_tag) {
+ id->tag |= LIB_TAG_DOIT;
}
return id_node;
}
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)
+ {
+ if (id_node->id_cow == NULL) {
+ /* This means builder "stole" ownership of the copy-on-written
+ * datablock for her own dirty needs.
+ */
+ continue;
+ }
+ if (!deg_copy_on_write_is_expanded(id_node->id_cow)) {
+ continue;
+ }
+ const ID_Type id_type = GS(id_node->id_cow->name);
+ if (id_type != ID_PA) {
+ id_node->destroy();
+ }
+ }
+ GHASH_FOREACH_END();
+ GHASH_FOREACH_BEGIN(IDDepsNode *, id_node, id_hash)
+ {
+ OBJECT_GUARDED_DELETE(id_node, IDDepsNode);
+ }
+ GHASH_FOREACH_END();
+#endif
}
/* Add new relationship between two nodes. */
@@ -309,7 +346,7 @@ DepsRelation *Depsgraph::add_new_relation(OperationDepsNode *from,
if (comp_node->type == DEG_NODE_TYPE_GEOMETRY) {
IDDepsNode *id_to = to->owner->owner;
IDDepsNode *id_from = from->owner->owner;
- if (id_to != id_from && (id_to->id->tag & LIB_TAG_ID_RECALC_ALL)) {
+ if (id_to != id_from && (id_to->id_orig->tag & LIB_TAG_ID_RECALC_ALL)) {
if ((id_from->eval_flags & DAG_EVAL_NEED_CPU) == 0) {
id_from->tag_update(this);
id_from->eval_flags |= DAG_EVAL_NEED_CPU;
@@ -388,9 +425,9 @@ DepsRelation::~DepsRelation()
void Depsgraph::add_entry_tag(OperationDepsNode *node)
{
/* Sanity check. */
- if (!node)
+ if (node == NULL) {
return;
-
+ }
/* Add to graph-level set of directly modified nodes to start searching from.
* NOTE: this is necessary since we have several thousand nodes to play with...
*/
@@ -407,6 +444,34 @@ void Depsgraph::clear_all_nodes()
}
}
+ID *Depsgraph::get_cow_id(const ID *id_orig) const
+{
+ IDDepsNode *id_node = find_id_node(id_orig);
+ if (id_node == NULL) {
+ /* This function is used from places where we expect ID to be either
+ * already a copy-on-write version or have a corresponding copy-on-write
+ * version.
+ *
+ * We try to enforce that in debug builds, for for release we play a bit
+ * safer game here.
+ */
+ if ((id_orig->tag & LIB_TAG_COPY_ON_WRITE) == 0) {
+ /* TODO(sergey): This is nice sanity check to have, but it fails
+ * in following situations:
+ *
+ * - Material has link to texture, which is not needed by new
+ * shading system and hence can be ignored at construction.
+ * - Object or mesh has material at a slot which is not used (for
+ * example, object has material slot by materials are set to
+ * object data).
+ */
+ // BLI_assert(!"Request for non-existing copy-on-write ID");
+ }
+ return (ID *)id_orig;
+ }
+ return id_node->id_cow;
+}
+
void deg_editors_id_update(Main *bmain, ID *id)
{
if (deg_editor_update_id_cb != NULL) {