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.cc238
1 files changed, 194 insertions, 44 deletions
diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc
index 34fb20ee2ba..bb340492a63 100644
--- a/source/blender/depsgraph/intern/depsgraph.cc
+++ b/source/blender/depsgraph/intern/depsgraph.cc
@@ -48,15 +48,18 @@ extern "C" {
#include "DNA_object_types.h"
#include "DNA_sequence_types.h"
-#include "BKE_depsgraph.h"
-
#include "RNA_access.h"
+
+#include "BKE_scene.h"
}
#include <algorithm>
#include <cstring>
#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_debug.h"
+
+#include "intern/eval/deg_eval_copy_on_write.h"
#include "intern/nodes/deg_node.h"
#include "intern/nodes/deg_node_component.h"
@@ -71,7 +74,6 @@ 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,14 +83,24 @@ static void remove_from_vector(vector<T> *vector, const T& value)
vector->end());
}
-Depsgraph::Depsgraph()
+Depsgraph::Depsgraph(Scene *scene,
+ ViewLayer *view_layer,
+ eEvaluationMode mode)
: time_source(NULL),
- need_update(false),
- layers(0)
+ need_update(true),
+ scene(scene),
+ view_layer(view_layer),
+ mode(mode),
+ ctime(BKE_scene_frame_get(scene)),
+ scene_cow(NULL),
+ is_active(false),
+ effector_relations(NULL)
{
BLI_spin_init(&lock);
id_hash = BLI_ghash_ptr_new("Depsgraph id hash");
entry_tags = BLI_gset_ptr_new("Depsgraph entry_tags");
+ debug_flags = G.debug;
+ memset(id_type_updated, 0, sizeof(id_type_updated));
}
Depsgraph::~Depsgraph()
@@ -214,6 +226,10 @@ static bool pointer_to_component_node_criteria(
*subdata = seq->name; // xxx?
return true;
}
+ else if (RNA_struct_is_a(ptr->type, &RNA_NodeSocket)) {
+ *type = DEG_NODE_TYPE_SHADING;
+ return true;
+ }
else if (ptr->type == &RNA_Curve) {
*id = (ID *)ptr->id.data;
*type = DEG_NODE_TYPE_GEOMETRY;
@@ -274,12 +290,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) {
@@ -299,23 +309,60 @@ 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, ID *id_cow_hint)
{
+ BLI_assert((id->tag & LIB_TAG_COPIED_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);
- /* register */
+ id_node = (IDDepsNode *)factory->create_node(id, "", id->name);
+ id_node->init_copy_on_write(id_cow_hint);
+ /* 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);
}
return id_node;
}
+void Depsgraph::clear_id_nodes_conditional(const std::function <bool (ID_Type id_type)>& filter)
+{
+ 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 (filter(id_type)) {
+ id_node->destroy();
+ }
+ }
+}
+
void Depsgraph::clear_id_nodes()
{
- BLI_ghash_clear(id_hash, NULL, id_node_deleter);
+ /* Free memory used by ID nodes. */
+
+ /* Stupid workaround to ensure we free IDs in a proper order. */
+ clear_id_nodes_conditional([](ID_Type id_type) { return id_type == ID_SCE; });
+ clear_id_nodes_conditional([](ID_Type id_type) { return id_type != ID_PA; });
+
+ foreach (IDDepsNode *id_node, id_nodes) {
+ OBJECT_GUARDED_DELETE(id_node, IDDepsNode);
+ }
+ /* Clear containers. */
+ BLI_ghash_clear(id_hash, NULL, NULL);
id_nodes.clear();
+ /* Clear physics relation caches. */
+ deg_clear_physics_relations(this);
}
/* Add new relationship between two nodes. */
@@ -339,7 +386,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;
@@ -433,9 +480,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...
*/
@@ -451,17 +498,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_COPIED_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);
}
}
@@ -496,9 +572,14 @@ string deg_color_end(void)
/* Public Graph API */
/* Initialize a new Depsgraph */
-Depsgraph *DEG_graph_new()
-{
- DEG::Depsgraph *deg_depsgraph = OBJECT_GUARDED_NEW(DEG::Depsgraph);
+Depsgraph *DEG_graph_new(Scene *scene,
+ ViewLayer *view_layer,
+ eEvaluationMode mode)
+{
+ DEG::Depsgraph *deg_depsgraph = OBJECT_GUARDED_NEW(DEG::Depsgraph,
+ scene,
+ view_layer,
+ mode);
return reinterpret_cast<Depsgraph *>(deg_depsgraph);
}
@@ -512,32 +593,68 @@ 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)
+bool DEG_is_active(const struct Depsgraph *depsgraph)
{
- if (DEG::deg_editor_update_scene_pre_cb != NULL) {
- DEG::deg_editor_update_scene_pre_cb(bmain, scene, time);
+ if (depsgraph == NULL) {
+ /* Happens for such cases as work object in what_does_obaction(),
+ * and sine render pipeline parts. Shouldn't really be accepting
+ * NULL depsgraph, but is quite hard to get proper one in those
+ * cases.
+ */
+ return false;
}
+ const DEG::Depsgraph *deg_graph =
+ reinterpret_cast<const DEG::Depsgraph *>(depsgraph);
+ return deg_graph->is_active;
+}
+
+void DEG_make_active(struct Depsgraph *depsgraph)
+{
+ DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(depsgraph);
+ deg_graph->is_active = true;
+ /* TODO(sergey): Copy data from evaluated state to original. */
+}
+
+void DEG_make_inactive(struct Depsgraph *depsgraph)
+{
+ DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(depsgraph);
+ deg_graph->is_active = false;
}
/* Evaluation and debug */
-void DEG_debug_print_eval(const char *function_name,
+static DEG::string depsgraph_name_for_logging(struct Depsgraph *depsgraph)
+{
+ const char *name = DEG_debug_name_get(depsgraph);
+ if (name[0] == '\0') {
+ return "";
+ }
+ return "[" + DEG::string(name) + "]: ";
+}
+
+void DEG_debug_print_begin(struct Depsgraph *depsgraph)
+{
+ fprintf(stdout, "%s",
+ depsgraph_name_for_logging(depsgraph).c_str());
+}
+
+void DEG_debug_print_eval(struct Depsgraph *depsgraph,
+ const char *function_name,
const char *object_name,
const void *object_address)
{
- if ((G.debug & G_DEBUG_DEPSGRAPH_EVAL) == 0) {
+ if ((DEG_debug_flags_get(depsgraph) & G_DEBUG_DEPSGRAPH_EVAL) == 0) {
return;
}
fprintf(stdout,
- "%s on %s %s(%p)%s\n",
+ "%s%s on %s %s(%p)%s\n",
+ depsgraph_name_for_logging(depsgraph).c_str(),
function_name,
object_name,
DEG::deg_color_for_pointer(object_address).c_str(),
@@ -546,18 +663,20 @@ void DEG_debug_print_eval(const char *function_name,
fflush(stdout);
}
-void DEG_debug_print_eval_subdata(const char *function_name,
+void DEG_debug_print_eval_subdata(struct Depsgraph *depsgraph,
+ const char *function_name,
const char *object_name,
const void *object_address,
const char *subdata_comment,
const char *subdata_name,
const void *subdata_address)
{
- if ((G.debug & G_DEBUG_DEPSGRAPH_EVAL) == 0) {
+ if ((DEG_debug_flags_get(depsgraph) & G_DEBUG_DEPSGRAPH_EVAL) == 0) {
return;
}
fprintf(stdout,
- "%s on %s %s(%p)%s %s %s %s(%p)%s\n",
+ "%s%s on %s %s(%p)%s %s %s %s(%p)%s\n",
+ depsgraph_name_for_logging(depsgraph).c_str(),
function_name,
object_name,
DEG::deg_color_for_pointer(object_address).c_str(),
@@ -571,7 +690,8 @@ void DEG_debug_print_eval_subdata(const char *function_name,
fflush(stdout);
}
-void DEG_debug_print_eval_subdata_index(const char *function_name,
+void DEG_debug_print_eval_subdata_index(struct Depsgraph *depsgraph,
+ const char *function_name,
const char *object_name,
const void *object_address,
const char *subdata_comment,
@@ -579,11 +699,12 @@ void DEG_debug_print_eval_subdata_index(const char *function_name,
const void *subdata_address,
const int subdata_index)
{
- if ((G.debug & G_DEBUG_DEPSGRAPH_EVAL) == 0) {
+ if ((DEG_debug_flags_get(depsgraph) & G_DEBUG_DEPSGRAPH_EVAL) == 0) {
return;
}
fprintf(stdout,
- "%s on %s %s(%p)^%s %s %s[%d] %s(%p)%s\n",
+ "%s%s on %s %s(%p)%s %s %s[%d] %s(%p)%s\n",
+ depsgraph_name_for_logging(depsgraph).c_str(),
function_name,
object_name,
DEG::deg_color_for_pointer(object_address).c_str(),
@@ -598,16 +719,45 @@ void DEG_debug_print_eval_subdata_index(const char *function_name,
fflush(stdout);
}
-void DEG_debug_print_eval_time(const char *function_name,
+void DEG_debug_print_eval_parent_typed(struct Depsgraph *depsgraph,
+ const char *function_name,
+ const char *object_name,
+ const void *object_address,
+ const char *parent_comment,
+ const char *parent_name,
+ const void *parent_address)
+{
+ if ((DEG_debug_flags_get(depsgraph) & G_DEBUG_DEPSGRAPH_EVAL) == 0) {
+ return;
+ }
+ fprintf(stdout,
+ "%s%s on %s %s(%p) [%s] %s %s %s(%p)%s\n",
+ depsgraph_name_for_logging(depsgraph).c_str(),
+ function_name,
+ object_name,
+ DEG::deg_color_for_pointer(object_address).c_str(),
+ object_address,
+ DEG::deg_color_end().c_str(),
+ parent_comment,
+ parent_name,
+ DEG::deg_color_for_pointer(parent_address).c_str(),
+ parent_address,
+ DEG::deg_color_end().c_str());
+ fflush(stdout);
+}
+
+void DEG_debug_print_eval_time(struct Depsgraph *depsgraph,
+ const char *function_name,
const char *object_name,
const void *object_address,
float time)
{
- if ((G.debug & G_DEBUG_DEPSGRAPH_EVAL) == 0) {
+ if ((DEG_debug_flags_get(depsgraph) & G_DEBUG_DEPSGRAPH_EVAL) == 0) {
return;
}
fprintf(stdout,
- "%s on %s %s(%p)%s at time %f\n",
+ "%s%s on %s %s(%p)%s at time %f\n",
+ depsgraph_name_for_logging(depsgraph).c_str(),
function_name,
object_name,
DEG::deg_color_for_pointer(object_address).c_str(),