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.cc126
1 files changed, 93 insertions, 33 deletions
diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc
index a016d623ea9..3a78c9050f7 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"
}
@@ -56,6 +54,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_id.h"
@@ -65,11 +65,22 @@ extern "C" {
#include "intern/depsgraph_intern.h"
#include "util/deg_util_foreach.h"
+static bool use_copy_on_write = false;
+
+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;
static DEG_EditorUpdateSceneCb deg_editor_update_scene_cb = NULL;
-static DEG_EditorUpdateScenePreCb deg_editor_update_scene_pre_cb = NULL;
/* TODO(sergey): Find a better place for this. */
template <typename T>
@@ -81,8 +92,9 @@ static void remove_from_vector(vector<T> *vector, const T& value)
Depsgraph::Depsgraph()
: time_source(NULL),
- need_update(false),
- layers(0)
+ need_update(true),
+ scene(NULL),
+ view_layer(NULL)
{
BLI_spin_init(&lock);
id_hash = BLI_ghash_ptr_new("Depsgraph id hash");
@@ -255,12 +267,6 @@ DepsNode *Depsgraph::find_node_from_pointer(const PointerRNA *ptr,
/* Node Management ---------------------------- */
-static void id_node_deleter(void *value)
-{
- IDDepsNode *id_node = reinterpret_cast<IDDepsNode *>(value);
- OBJECT_GUARDED_DELETE(id_node, IDDepsNode);
-}
-
TimeSourceDepsNode *Depsgraph::add_time_source()
{
if (time_source == NULL) {
@@ -280,23 +286,57 @@ 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_type_get_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);
id_nodes.push_back(id_node);
}
+ else if (do_tag) {
+ id->tag |= LIB_TAG_DOIT;
+ }
return id_node;
}
void Depsgraph::clear_id_nodes()
{
- BLI_ghash_clear(id_hash, NULL, id_node_deleter);
+ /* Free memory used by ID nodes. */
+ if (use_copy_on_write) {
+ /* Stupid workaround to ensure we free IDs in a proper order. */
+ foreach (IDDepsNode *id_node, id_nodes) {
+ 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();
+ }
+ }
+ }
+ foreach (IDDepsNode *id_node, id_nodes) {
+ OBJECT_GUARDED_DELETE(id_node, IDDepsNode);
+ }
+ /* Clear containers. */
+ BLI_ghash_clear(id_hash, NULL, NULL);
id_nodes.clear();
}
@@ -321,7 +361,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->recalc & ID_RECALC_ALL)) {
+ if (id_to != id_from && (id_to->id_orig->recalc & 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;
@@ -415,9 +455,9 @@ void DepsRelation::unlink()
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...
*/
@@ -433,17 +473,46 @@ void Depsgraph::clear_all_nodes()
}
}
-void deg_editors_id_update(Main *bmain, ID *id)
+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(const DEGEditorUpdateContext *update_ctx, ID *id)
{
if (deg_editor_update_id_cb != NULL) {
- deg_editor_update_id_cb(bmain, id);
+ deg_editor_update_id_cb(update_ctx, id);
}
}
-void deg_editors_scene_update(Main *bmain, Scene *scene, bool updated)
+void deg_editors_scene_update(const DEGEditorUpdateContext *update_ctx,
+ bool updated)
{
if (deg_editor_update_scene_cb != NULL) {
- deg_editor_update_scene_cb(bmain, scene, updated);
+ deg_editor_update_scene_cb(update_ctx, updated);
}
}
@@ -469,17 +538,8 @@ void DEG_graph_free(Depsgraph *graph)
/* Set callbacks which are being called when depsgraph changes. */
void DEG_editors_set_update_cb(DEG_EditorUpdateIDCb id_func,
- DEG_EditorUpdateSceneCb scene_func,
- DEG_EditorUpdateScenePreCb scene_pre_func)
+ DEG_EditorUpdateSceneCb scene_func)
{
DEG::deg_editor_update_id_cb = id_func;
DEG::deg_editor_update_scene_cb = scene_func;
- DEG::deg_editor_update_scene_pre_cb = scene_pre_func;
-}
-
-void DEG_editors_update_pre(Main *bmain, Scene *scene, bool time)
-{
- if (DEG::deg_editor_update_scene_pre_cb != NULL) {
- DEG::deg_editor_update_scene_pre_cb(bmain, scene, time);
- }
}