Merge branch 'master' into blender2.8
This commit is contained in:
@@ -59,7 +59,9 @@ set(SRC
|
||||
intern/eval/deg_eval_flush.cc
|
||||
intern/nodes/deg_node.cc
|
||||
intern/nodes/deg_node_component.cc
|
||||
intern/nodes/deg_node_id.cc
|
||||
intern/nodes/deg_node_operation.cc
|
||||
intern/nodes/deg_node_time.cc
|
||||
intern/depsgraph.cc
|
||||
intern/depsgraph_build.cc
|
||||
intern/depsgraph_debug.cc
|
||||
@@ -87,7 +89,9 @@ set(SRC
|
||||
intern/eval/deg_eval_flush.h
|
||||
intern/nodes/deg_node.h
|
||||
intern/nodes/deg_node_component.h
|
||||
intern/nodes/deg_node_id.h
|
||||
intern/nodes/deg_node_operation.h
|
||||
intern/nodes/deg_node_time.h
|
||||
intern/depsgraph.h
|
||||
intern/depsgraph_intern.h
|
||||
intern/depsgraph_types.h
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "intern/depsgraph.h"
|
||||
#include "intern/depsgraph_types.h"
|
||||
#include "intern/nodes/deg_node.h"
|
||||
#include "intern/nodes/deg_node_id.h"
|
||||
|
||||
#include "util/deg_util_foreach.h"
|
||||
|
||||
|
||||
@@ -106,9 +106,11 @@ extern "C" {
|
||||
#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"
|
||||
#include "intern/nodes/deg_node_operation.h"
|
||||
#include "intern/depsgraph_types.h"
|
||||
#include "intern/depsgraph_intern.h"
|
||||
|
||||
#include "util/deg_util_foreach.h"
|
||||
|
||||
namespace DEG {
|
||||
|
||||
@@ -104,7 +104,9 @@ extern "C" {
|
||||
|
||||
#include "intern/nodes/deg_node.h"
|
||||
#include "intern/nodes/deg_node_component.h"
|
||||
#include "intern/nodes/deg_node_id.h"
|
||||
#include "intern/nodes/deg_node_operation.h"
|
||||
#include "intern/nodes/deg_node_time.h"
|
||||
|
||||
#include "intern/depsgraph_intern.h"
|
||||
#include "intern/depsgraph_types.h"
|
||||
|
||||
@@ -59,6 +59,7 @@ extern "C" {
|
||||
|
||||
#include "intern/nodes/deg_node.h"
|
||||
#include "intern/nodes/deg_node_component.h"
|
||||
#include "intern/nodes/deg_node_id.h"
|
||||
#include "intern/nodes/deg_node_operation.h"
|
||||
|
||||
#include "intern/depsgraph_intern.h"
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "intern/nodes/deg_node_operation.h"
|
||||
|
||||
#include "intern/depsgraph.h"
|
||||
#include "intern/depsgraph_intern.h"
|
||||
|
||||
#include "util/deg_util_foreach.h"
|
||||
|
||||
@@ -79,13 +80,13 @@ static void deg_graph_tag_paths_recursive(DepsNode *node)
|
||||
|
||||
void deg_graph_transitive_reduction(Depsgraph *graph)
|
||||
{
|
||||
int num_removed_relations = 0;
|
||||
foreach (OperationDepsNode *target, graph->operations) {
|
||||
/* Clear tags. */
|
||||
foreach (OperationDepsNode *node, graph->operations) {
|
||||
node->done = 0;
|
||||
}
|
||||
|
||||
/* mark nodes from which we can reach the target
|
||||
/* Mark nodes from which we can reach the target
|
||||
* start with children, so the target node and direct children are not
|
||||
* flagged.
|
||||
*/
|
||||
@@ -93,27 +94,30 @@ void deg_graph_transitive_reduction(Depsgraph *graph)
|
||||
foreach (DepsRelation *rel, target->inlinks) {
|
||||
deg_graph_tag_paths_recursive(rel->from);
|
||||
}
|
||||
|
||||
/* Remove redundant paths to the target. */
|
||||
for (DepsNode::Relations::const_iterator it_rel = target->inlinks.begin();
|
||||
it_rel != target->inlinks.end();
|
||||
)
|
||||
{
|
||||
DepsRelation *rel = *it_rel;
|
||||
/* Increment in advance, so we can safely remove the relation. */
|
||||
++it_rel;
|
||||
|
||||
if (rel->from->type == DEG_NODE_TYPE_TIMESOURCE) {
|
||||
/* HACK: time source nodes don't get "done" flag set/cleared. */
|
||||
/* TODO: there will be other types in future, so iterators above
|
||||
* need modifying.
|
||||
*/
|
||||
++it_rel;
|
||||
}
|
||||
else if (rel->from->done & OP_REACHABLE) {
|
||||
rel->unlink();
|
||||
OBJECT_GUARDED_DELETE(rel, DepsRelation);
|
||||
++num_removed_relations;
|
||||
}
|
||||
else {
|
||||
++it_rel;
|
||||
}
|
||||
}
|
||||
}
|
||||
DEG_DEBUG_PRINTF("Removed %d relations\n", num_removed_relations);
|
||||
}
|
||||
|
||||
} // namespace DEG
|
||||
|
||||
@@ -41,6 +41,9 @@ extern "C" {
|
||||
#include "DEG_depsgraph_debug.h"
|
||||
|
||||
#include "intern/depsgraph_intern.h"
|
||||
#include "intern/nodes/deg_node_id.h"
|
||||
#include "intern/nodes/deg_node_time.h"
|
||||
|
||||
#include "util/deg_util_foreach.h"
|
||||
|
||||
/* ****************** */
|
||||
|
||||
@@ -49,6 +49,7 @@ extern "C" {
|
||||
#include "RNA_access.h"
|
||||
}
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
@@ -57,7 +58,9 @@ extern "C" {
|
||||
|
||||
#include "intern/nodes/deg_node.h"
|
||||
#include "intern/nodes/deg_node_component.h"
|
||||
#include "intern/nodes/deg_node_id.h"
|
||||
#include "intern/nodes/deg_node_operation.h"
|
||||
#include "intern/nodes/deg_node_time.h"
|
||||
|
||||
#include "intern/depsgraph_intern.h"
|
||||
#include "util/deg_util_foreach.h"
|
||||
@@ -79,6 +82,14 @@ namespace DEG {
|
||||
static DEG_EditorUpdateIDCb deg_editor_update_id_cb = NULL;
|
||||
static DEG_EditorUpdateSceneCb deg_editor_update_scene_cb = NULL;
|
||||
|
||||
/* TODO(sergey): Find a better place for this. */
|
||||
template <typename T>
|
||||
static void remove_from_vector(vector<T> *vector, const T& value)
|
||||
{
|
||||
vector->erase(std::remove(vector->begin(), vector->end(), value),
|
||||
vector->end());
|
||||
}
|
||||
|
||||
Depsgraph::Depsgraph()
|
||||
: time_source(NULL),
|
||||
need_update(true),
|
||||
@@ -431,7 +442,15 @@ DepsRelation::DepsRelation(DepsNode *from,
|
||||
DepsRelation::~DepsRelation()
|
||||
{
|
||||
/* Sanity check. */
|
||||
BLI_assert(this->from && this->to);
|
||||
BLI_assert(from != NULL && to != NULL);
|
||||
}
|
||||
|
||||
void DepsRelation::unlink()
|
||||
{
|
||||
/* Sanity check. */
|
||||
BLI_assert(from != NULL && to != NULL);
|
||||
remove_from_vector(&from->outlinks, this);
|
||||
remove_from_vector(&to->inlinks, this);
|
||||
}
|
||||
|
||||
/* Low level tagging -------------------------------------- */
|
||||
|
||||
@@ -87,6 +87,8 @@ struct DepsRelation {
|
||||
const char *description);
|
||||
|
||||
~DepsRelation();
|
||||
|
||||
void unlink();
|
||||
};
|
||||
|
||||
/* ********* */
|
||||
|
||||
@@ -68,6 +68,7 @@ extern "C" {
|
||||
|
||||
#include "intern/nodes/deg_node.h"
|
||||
#include "intern/nodes/deg_node_component.h"
|
||||
#include "intern/nodes/deg_node_id.h"
|
||||
#include "intern/nodes/deg_node_operation.h"
|
||||
|
||||
#include "intern/depsgraph_types.h"
|
||||
|
||||
@@ -42,6 +42,9 @@ extern "C" {
|
||||
#include "DEG_depsgraph_build.h"
|
||||
|
||||
#include "intern/depsgraph_intern.h"
|
||||
#include "intern/nodes/deg_node_id.h"
|
||||
#include "intern/nodes/deg_node_time.h"
|
||||
|
||||
#include "util/deg_util_foreach.h"
|
||||
|
||||
bool DEG_debug_compare(const struct Depsgraph *graph1,
|
||||
|
||||
@@ -48,6 +48,7 @@ extern "C" {
|
||||
|
||||
#include "intern/nodes/deg_node.h"
|
||||
#include "intern/nodes/deg_node_operation.h"
|
||||
#include "intern/nodes/deg_node_time.h"
|
||||
|
||||
#include "intern/depsgraph.h"
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ extern "C" {
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "intern/depsgraph_intern.h"
|
||||
#include "intern/nodes/deg_node_id.h"
|
||||
|
||||
bool DEG_id_type_tagged(Main *bmain, short id_type)
|
||||
{
|
||||
|
||||
@@ -50,6 +50,7 @@ extern "C" {
|
||||
|
||||
#include "intern/nodes/deg_node.h"
|
||||
#include "intern/nodes/deg_node_component.h"
|
||||
#include "intern/nodes/deg_node_id.h"
|
||||
#include "intern/nodes/deg_node_operation.h"
|
||||
|
||||
#include "util/deg_util_foreach.h"
|
||||
|
||||
@@ -50,6 +50,8 @@ extern "C" {
|
||||
#include "intern/depsgraph_intern.h"
|
||||
#include "util/deg_util_foreach.h"
|
||||
|
||||
#include "intern/nodes/deg_node_id.h"
|
||||
|
||||
#ifndef NDEBUG
|
||||
# include "intern/eval/deg_eval_copy_on_write.h"
|
||||
#endif
|
||||
|
||||
@@ -64,6 +64,7 @@ extern "C" {
|
||||
#include "intern/eval/deg_eval_flush.h"
|
||||
#include "intern/nodes/deg_node.h"
|
||||
#include "intern/nodes/deg_node_component.h"
|
||||
#include "intern/nodes/deg_node_id.h"
|
||||
#include "intern/nodes/deg_node_operation.h"
|
||||
|
||||
#include "intern/depsgraph_intern.h"
|
||||
|
||||
@@ -48,19 +48,14 @@
|
||||
#include "intern/eval/deg_eval_flush.h"
|
||||
#include "intern/nodes/deg_node.h"
|
||||
#include "intern/nodes/deg_node_component.h"
|
||||
#include "intern/nodes/deg_node_id.h"
|
||||
#include "intern/nodes/deg_node_operation.h"
|
||||
#include "intern/nodes/deg_node_time.h"
|
||||
#include "intern/depsgraph.h"
|
||||
#include "intern/depsgraph_intern.h"
|
||||
|
||||
#include "util/deg_util_foreach.h"
|
||||
|
||||
/* Unfinished and unused, and takes quite some pre-processing time. */
|
||||
#undef USE_EVAL_PRIORITY
|
||||
|
||||
/* Use integrated debugger to keep track how much each of the nodes was
|
||||
* evaluating.
|
||||
*/
|
||||
#undef USE_DEBUGGER
|
||||
|
||||
namespace DEG {
|
||||
|
||||
/* ********************** */
|
||||
@@ -103,22 +98,8 @@ static void deg_task_run_func(TaskPool *pool,
|
||||
* but that's all fine, we'll just scheduler it's children.
|
||||
*/
|
||||
if (node->evaluate) {
|
||||
/* Take note of current time. */
|
||||
#ifdef USE_DEBUGGER
|
||||
double start_time = PIL_check_seconds_timer();
|
||||
DepsgraphDebug::task_started(state->graph, node);
|
||||
#endif
|
||||
|
||||
/* Perform operation. */
|
||||
node->evaluate(state->eval_ctx);
|
||||
|
||||
/* Note how long this took. */
|
||||
#ifdef USE_DEBUGGER
|
||||
double end_time = PIL_check_seconds_timer();
|
||||
DepsgraphDebug::task_completed(state->graph,
|
||||
node,
|
||||
end_time - start_time);
|
||||
#endif
|
||||
}
|
||||
|
||||
BLI_task_pool_delayed_push_begin(pool, thread_id);
|
||||
@@ -167,33 +148,6 @@ static void calculate_pending_parents(Depsgraph *graph)
|
||||
do_threads);
|
||||
}
|
||||
|
||||
#ifdef USE_EVAL_PRIORITY
|
||||
static void calculate_eval_priority(OperationDepsNode *node)
|
||||
{
|
||||
if (node->done) {
|
||||
return;
|
||||
}
|
||||
node->done = 1;
|
||||
|
||||
if (node->flag & DEPSOP_FLAG_NEEDS_UPDATE) {
|
||||
/* XXX standard cost of a node, could be estimated somewhat later on */
|
||||
const float cost = 1.0f;
|
||||
/* NOOP nodes have no cost */
|
||||
node->eval_priority = node->is_noop() ? cost : 0.0f;
|
||||
|
||||
foreach (DepsRelation *rel, node->outlinks) {
|
||||
OperationDepsNode *to = (OperationDepsNode *)rel->to;
|
||||
BLI_assert(to->type == DEG_NODE_TYPE_OPERATION);
|
||||
calculate_eval_priority(to);
|
||||
node->eval_priority += to->eval_priority;
|
||||
}
|
||||
}
|
||||
else {
|
||||
node->eval_priority = 0.0f;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Schedule a node if it needs evaluation.
|
||||
* dec_parents: Decrement pending parents count, true when child nodes are
|
||||
* scheduled after a task has been completed.
|
||||
@@ -307,13 +261,6 @@ void deg_evaluate_on_refresh(EvaluationContext *eval_ctx,
|
||||
node->done = 0;
|
||||
}
|
||||
|
||||
/* Calculate priority for operation nodes. */
|
||||
#ifdef USE_EVAL_PRIORITY
|
||||
foreach (OperationDepsNode *node, graph->operations) {
|
||||
calculate_eval_priority(node);
|
||||
}
|
||||
#endif
|
||||
|
||||
schedule_graph(task_pool, graph);
|
||||
|
||||
BLI_task_pool_work_and_wait(task_pool);
|
||||
|
||||
@@ -80,6 +80,7 @@ extern "C" {
|
||||
#include "intern/depsgraph.h"
|
||||
#include "intern/builder/deg_builder_nodes.h"
|
||||
#include "intern/nodes/deg_node.h"
|
||||
#include "intern/nodes/deg_node_id.h"
|
||||
|
||||
namespace DEG {
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ extern "C" {
|
||||
|
||||
#include "intern/nodes/deg_node.h"
|
||||
#include "intern/nodes/deg_node_component.h"
|
||||
#include "intern/nodes/deg_node_id.h"
|
||||
#include "intern/nodes/deg_node_operation.h"
|
||||
|
||||
#include "intern/depsgraph_intern.h"
|
||||
|
||||
@@ -49,8 +49,11 @@ extern "C" {
|
||||
|
||||
#include "intern/eval/deg_eval_copy_on_write.h"
|
||||
#include "intern/nodes/deg_node_component.h"
|
||||
#include "intern/nodes/deg_node_id.h"
|
||||
#include "intern/nodes/deg_node_operation.h"
|
||||
#include "intern/nodes/deg_node_time.h"
|
||||
#include "intern/depsgraph_intern.h"
|
||||
|
||||
#include "util/deg_util_foreach.h"
|
||||
#include "util/deg_util_function.h"
|
||||
|
||||
@@ -103,186 +106,11 @@ string DepsNode::identifier() const
|
||||
return string(typebuf) + " : " + name;
|
||||
}
|
||||
|
||||
/* ************* */
|
||||
/* Generic Nodes */
|
||||
|
||||
/* Time Source Node ============================================== */
|
||||
|
||||
void TimeSourceDepsNode::tag_update(Depsgraph *graph)
|
||||
{
|
||||
foreach (DepsRelation *rel, outlinks) {
|
||||
DepsNode *node = rel->to;
|
||||
node->tag_update(graph);
|
||||
}
|
||||
}
|
||||
|
||||
/* Time Source Node ======================================= */
|
||||
|
||||
DEG_DEPSNODE_DEFINE(TimeSourceDepsNode, DEG_NODE_TYPE_TIMESOURCE, "Time Source");
|
||||
static DepsNodeFactoryImpl<TimeSourceDepsNode> DNTI_TIMESOURCE;
|
||||
|
||||
/* ID Node ================================================ */
|
||||
|
||||
IDDepsNode::ComponentIDKey::ComponentIDKey(eDepsNode_Type type,
|
||||
const char *name)
|
||||
: type(type), name(name)
|
||||
{
|
||||
}
|
||||
|
||||
bool IDDepsNode::ComponentIDKey::operator== (const ComponentIDKey &other) const
|
||||
{
|
||||
return type == other.type &&
|
||||
STREQ(name, other.name);
|
||||
}
|
||||
|
||||
static unsigned int id_deps_node_hash_key(const void *key_v)
|
||||
{
|
||||
const IDDepsNode::ComponentIDKey *key =
|
||||
reinterpret_cast<const IDDepsNode::ComponentIDKey *>(key_v);
|
||||
return BLI_ghashutil_combine_hash(BLI_ghashutil_uinthash(key->type),
|
||||
BLI_ghashutil_strhash_p(key->name));
|
||||
}
|
||||
|
||||
static bool id_deps_node_hash_key_cmp(const void *a, const void *b)
|
||||
{
|
||||
const IDDepsNode::ComponentIDKey *key_a =
|
||||
reinterpret_cast<const IDDepsNode::ComponentIDKey *>(a);
|
||||
const IDDepsNode::ComponentIDKey *key_b =
|
||||
reinterpret_cast<const IDDepsNode::ComponentIDKey *>(b);
|
||||
return !(*key_a == *key_b);
|
||||
}
|
||||
|
||||
static void id_deps_node_hash_key_free(void *key_v)
|
||||
{
|
||||
typedef IDDepsNode::ComponentIDKey ComponentIDKey;
|
||||
ComponentIDKey *key = reinterpret_cast<ComponentIDKey *>(key_v);
|
||||
OBJECT_GUARDED_DELETE(key, ComponentIDKey);
|
||||
}
|
||||
|
||||
static void id_deps_node_hash_value_free(void *value_v)
|
||||
{
|
||||
ComponentDepsNode *comp_node = reinterpret_cast<ComponentDepsNode *>(value_v);
|
||||
OBJECT_GUARDED_DELETE(comp_node, ComponentDepsNode);
|
||||
}
|
||||
|
||||
/* Initialize 'id' node - from pointer data given. */
|
||||
void IDDepsNode::init(const ID *id, const char *UNUSED(subdata))
|
||||
{
|
||||
BLI_assert(id != NULL);
|
||||
/* Store ID-pointer. */
|
||||
id_orig = (ID *)id;
|
||||
eval_flags = 0;
|
||||
linked_state = DEG_ID_LINKED_INDIRECTLY;
|
||||
|
||||
components = BLI_ghash_new(id_deps_node_hash_key,
|
||||
id_deps_node_hash_key_cmp,
|
||||
"Depsgraph id components hash");
|
||||
}
|
||||
|
||||
void IDDepsNode::init_copy_on_write(ID *id_cow_hint)
|
||||
{
|
||||
/* 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.
|
||||
*/
|
||||
if (id_cow_hint != NULL) {
|
||||
// BLI_assert(deg_copy_on_write_is_needed(id_orig));
|
||||
if (deg_copy_on_write_is_needed(id_orig)) {
|
||||
id_cow = id_cow_hint;
|
||||
}
|
||||
else {
|
||||
id_cow = id_orig;
|
||||
}
|
||||
}
|
||||
else if (deg_copy_on_write_is_needed(id_orig)) {
|
||||
id_cow = (ID *)BKE_libblock_alloc_notest(GS(id_orig->name));
|
||||
DEG_COW_PRINT("Create shallow copy for %s: id_orig=%p id_cow=%p\n",
|
||||
id_orig->name, id_orig, id_cow);
|
||||
deg_tag_copy_on_write_id(id_cow, id_orig);
|
||||
}
|
||||
else {
|
||||
id_cow = id_orig;
|
||||
}
|
||||
}
|
||||
|
||||
/* Free 'id' node. */
|
||||
IDDepsNode::~IDDepsNode()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
void IDDepsNode::destroy()
|
||||
{
|
||||
if (id_orig == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
BLI_ghash_free(components,
|
||||
id_deps_node_hash_key_free,
|
||||
id_deps_node_hash_value_free);
|
||||
|
||||
/* Free memory used by this CoW ID. */
|
||||
if (id_cow != id_orig && id_cow != NULL) {
|
||||
deg_free_copy_on_write_datablock(id_cow);
|
||||
MEM_freeN(id_cow);
|
||||
DEG_COW_PRINT("Destroy CoW for %s: id_orig=%p id_cow=%p\n",
|
||||
id_orig->name, id_orig, id_cow);
|
||||
}
|
||||
|
||||
/* Tag that the node is freed. */
|
||||
id_orig = NULL;
|
||||
}
|
||||
|
||||
ComponentDepsNode *IDDepsNode::find_component(eDepsNode_Type type,
|
||||
const char *name) const
|
||||
{
|
||||
ComponentIDKey key(type, name);
|
||||
return reinterpret_cast<ComponentDepsNode *>(BLI_ghash_lookup(components, &key));
|
||||
}
|
||||
|
||||
ComponentDepsNode *IDDepsNode::add_component(eDepsNode_Type type,
|
||||
const char *name)
|
||||
{
|
||||
ComponentDepsNode *comp_node = find_component(type, name);
|
||||
if (!comp_node) {
|
||||
DepsNodeFactory *factory = deg_type_get_factory(type);
|
||||
comp_node = (ComponentDepsNode *)factory->create_node(this->id_orig, "", name);
|
||||
|
||||
/* Register. */
|
||||
ComponentIDKey *key = OBJECT_GUARDED_NEW(ComponentIDKey, type, name);
|
||||
BLI_ghash_insert(components, key, comp_node);
|
||||
comp_node->owner = this;
|
||||
}
|
||||
return comp_node;
|
||||
}
|
||||
|
||||
void IDDepsNode::tag_update(Depsgraph *graph)
|
||||
{
|
||||
GHASH_FOREACH_BEGIN(ComponentDepsNode *, comp_node, components)
|
||||
{
|
||||
comp_node->tag_update(graph);
|
||||
}
|
||||
GHASH_FOREACH_END();
|
||||
}
|
||||
|
||||
void IDDepsNode::finalize_build(Depsgraph *graph)
|
||||
{
|
||||
/* Finalize build of all components. */
|
||||
GHASH_FOREACH_BEGIN(ComponentDepsNode *, comp_node, components)
|
||||
{
|
||||
comp_node->finalize_build(graph);
|
||||
}
|
||||
GHASH_FOREACH_END();
|
||||
}
|
||||
|
||||
DEG_DEPSNODE_DEFINE(IDDepsNode, DEG_NODE_TYPE_ID_REF, "ID Node");
|
||||
static DepsNodeFactoryImpl<IDDepsNode> DNTI_ID_REF;
|
||||
|
||||
|
||||
@@ -109,68 +109,6 @@ struct DepsNode {
|
||||
#define DEG_DEPSNODE_DEFINE(NodeType, type_, tname_) \
|
||||
const DepsNode::TypeInfo NodeType::typeinfo = DepsNode::TypeInfo(type_, tname_)
|
||||
|
||||
/* Generic Nodes ======================= */
|
||||
|
||||
struct ComponentDepsNode;
|
||||
struct IDDepsNode;
|
||||
|
||||
/* Time Source Node. */
|
||||
struct TimeSourceDepsNode : public DepsNode {
|
||||
/* New "current time". */
|
||||
float cfra;
|
||||
|
||||
/* time-offset relative to the "official" time source that this one has. */
|
||||
float offset;
|
||||
|
||||
// TODO: evaluate() operation needed
|
||||
|
||||
void tag_update(Depsgraph *graph);
|
||||
|
||||
DEG_DEPSNODE_DECLARE;
|
||||
};
|
||||
|
||||
/* ID-Block Reference */
|
||||
struct IDDepsNode : public DepsNode {
|
||||
struct ComponentIDKey {
|
||||
ComponentIDKey(eDepsNode_Type type, const char *name = "");
|
||||
bool operator==(const ComponentIDKey &other) const;
|
||||
|
||||
eDepsNode_Type type;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
void init(const ID *id, const char *subdata);
|
||||
void init_copy_on_write(ID *id_cow_hint = NULL);
|
||||
~IDDepsNode();
|
||||
void destroy();
|
||||
|
||||
ComponentDepsNode *find_component(eDepsNode_Type type,
|
||||
const char *name = "") const;
|
||||
ComponentDepsNode *add_component(eDepsNode_Type type,
|
||||
const char *name = "");
|
||||
|
||||
void tag_update(Depsgraph *graph);
|
||||
|
||||
void finalize_build(Depsgraph *graph);
|
||||
|
||||
/* ID Block referenced. */
|
||||
ID *id_orig;
|
||||
ID *id_cow;
|
||||
|
||||
/* Hash to make it faster to look up components. */
|
||||
GHash *components;
|
||||
|
||||
/* Additional flags needed for scene evaluation.
|
||||
* TODO(sergey): Only needed for until really granular updates
|
||||
* of all the entities.
|
||||
*/
|
||||
int eval_flags;
|
||||
|
||||
eDepsNode_LinkedState_Type linked_state;
|
||||
|
||||
DEG_DEPSNODE_DECLARE;
|
||||
};
|
||||
|
||||
void deg_register_base_depsnodes();
|
||||
|
||||
} // namespace DEG
|
||||
|
||||
@@ -42,6 +42,7 @@ extern "C" {
|
||||
#include "BKE_action.h"
|
||||
} /* extern "C" */
|
||||
|
||||
#include "intern/nodes/deg_node_id.h"
|
||||
#include "intern/nodes/deg_node_operation.h"
|
||||
#include "intern/depsgraph_intern.h"
|
||||
#include "util/deg_util_foreach.h"
|
||||
|
||||
@@ -46,6 +46,7 @@ namespace DEG {
|
||||
struct Depsgraph;
|
||||
struct OperationDepsNode;
|
||||
struct BoneComponentDepsNode;
|
||||
struct IDDepsNode;
|
||||
|
||||
/* ID Component - Base type for all components */
|
||||
struct ComponentDepsNode : public DepsNode {
|
||||
|
||||
219
source/blender/depsgraph/intern/nodes/deg_node_id.cc
Normal file
219
source/blender/depsgraph/intern/nodes/deg_node_id.cc
Normal file
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* 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) 2013 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Original Author: Joshua Leung
|
||||
* Contributor(s): None Yet
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/depsgraph/intern/nodes/deg_node_id.cc
|
||||
* \ingroup depsgraph
|
||||
*/
|
||||
|
||||
#include "intern/nodes/deg_node_id.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <cstring> /* required for STREQ later on. */
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_ghash.h"
|
||||
|
||||
extern "C" {
|
||||
#include "DNA_ID.h"
|
||||
#include "DNA_anim_types.h"
|
||||
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_library.h"
|
||||
}
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
|
||||
#include "intern/eval/deg_eval_copy_on_write.h"
|
||||
#include "intern/nodes/deg_node_component.h"
|
||||
#include "intern/nodes/deg_node_operation.h"
|
||||
#include "intern/nodes/deg_node_time.h"
|
||||
#include "intern/depsgraph_intern.h"
|
||||
|
||||
#include "util/deg_util_foreach.h"
|
||||
|
||||
namespace DEG {
|
||||
|
||||
IDDepsNode::ComponentIDKey::ComponentIDKey(eDepsNode_Type type,
|
||||
const char *name)
|
||||
: type(type), name(name)
|
||||
{
|
||||
}
|
||||
|
||||
bool IDDepsNode::ComponentIDKey::operator== (const ComponentIDKey &other) const
|
||||
{
|
||||
return type == other.type &&
|
||||
STREQ(name, other.name);
|
||||
}
|
||||
|
||||
static unsigned int id_deps_node_hash_key(const void *key_v)
|
||||
{
|
||||
const IDDepsNode::ComponentIDKey *key =
|
||||
reinterpret_cast<const IDDepsNode::ComponentIDKey *>(key_v);
|
||||
return BLI_ghashutil_combine_hash(BLI_ghashutil_uinthash(key->type),
|
||||
BLI_ghashutil_strhash_p(key->name));
|
||||
}
|
||||
|
||||
static bool id_deps_node_hash_key_cmp(const void *a, const void *b)
|
||||
{
|
||||
const IDDepsNode::ComponentIDKey *key_a =
|
||||
reinterpret_cast<const IDDepsNode::ComponentIDKey *>(a);
|
||||
const IDDepsNode::ComponentIDKey *key_b =
|
||||
reinterpret_cast<const IDDepsNode::ComponentIDKey *>(b);
|
||||
return !(*key_a == *key_b);
|
||||
}
|
||||
|
||||
static void id_deps_node_hash_key_free(void *key_v)
|
||||
{
|
||||
typedef IDDepsNode::ComponentIDKey ComponentIDKey;
|
||||
ComponentIDKey *key = reinterpret_cast<ComponentIDKey *>(key_v);
|
||||
OBJECT_GUARDED_DELETE(key, ComponentIDKey);
|
||||
}
|
||||
|
||||
static void id_deps_node_hash_value_free(void *value_v)
|
||||
{
|
||||
ComponentDepsNode *comp_node = reinterpret_cast<ComponentDepsNode *>(value_v);
|
||||
OBJECT_GUARDED_DELETE(comp_node, ComponentDepsNode);
|
||||
}
|
||||
|
||||
/* Initialize 'id' node - from pointer data given. */
|
||||
void IDDepsNode::init(const ID *id, const char *UNUSED(subdata))
|
||||
{
|
||||
BLI_assert(id != NULL);
|
||||
/* Store ID-pointer. */
|
||||
id_orig = (ID *)id;
|
||||
eval_flags = 0;
|
||||
linked_state = DEG_ID_LINKED_INDIRECTLY;
|
||||
|
||||
components = BLI_ghash_new(id_deps_node_hash_key,
|
||||
id_deps_node_hash_key_cmp,
|
||||
"Depsgraph id components hash");
|
||||
}
|
||||
|
||||
void IDDepsNode::init_copy_on_write(ID *id_cow_hint)
|
||||
{
|
||||
/* 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.
|
||||
*/
|
||||
if (id_cow_hint != NULL) {
|
||||
// BLI_assert(deg_copy_on_write_is_needed(id_orig));
|
||||
if (deg_copy_on_write_is_needed(id_orig)) {
|
||||
id_cow = id_cow_hint;
|
||||
}
|
||||
else {
|
||||
id_cow = id_orig;
|
||||
}
|
||||
}
|
||||
else if (deg_copy_on_write_is_needed(id_orig)) {
|
||||
id_cow = (ID *)BKE_libblock_alloc_notest(GS(id_orig->name));
|
||||
DEG_COW_PRINT("Create shallow copy for %s: id_orig=%p id_cow=%p\n",
|
||||
id_orig->name, id_orig, id_cow);
|
||||
deg_tag_copy_on_write_id(id_cow, id_orig);
|
||||
}
|
||||
else {
|
||||
id_cow = id_orig;
|
||||
}
|
||||
}
|
||||
|
||||
/* Free 'id' node. */
|
||||
IDDepsNode::~IDDepsNode()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
void IDDepsNode::destroy()
|
||||
{
|
||||
if (id_orig == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
BLI_ghash_free(components,
|
||||
id_deps_node_hash_key_free,
|
||||
id_deps_node_hash_value_free);
|
||||
|
||||
/* Free memory used by this CoW ID. */
|
||||
if (id_cow != id_orig && id_cow != NULL) {
|
||||
deg_free_copy_on_write_datablock(id_cow);
|
||||
MEM_freeN(id_cow);
|
||||
DEG_COW_PRINT("Destroy CoW for %s: id_orig=%p id_cow=%p\n",
|
||||
id_orig->name, id_orig, id_cow);
|
||||
}
|
||||
|
||||
/* Tag that the node is freed. */
|
||||
id_orig = NULL;
|
||||
}
|
||||
|
||||
ComponentDepsNode *IDDepsNode::find_component(eDepsNode_Type type,
|
||||
const char *name) const
|
||||
{
|
||||
ComponentIDKey key(type, name);
|
||||
return reinterpret_cast<ComponentDepsNode *>(BLI_ghash_lookup(components, &key));
|
||||
}
|
||||
|
||||
ComponentDepsNode *IDDepsNode::add_component(eDepsNode_Type type,
|
||||
const char *name)
|
||||
{
|
||||
ComponentDepsNode *comp_node = find_component(type, name);
|
||||
if (!comp_node) {
|
||||
DepsNodeFactory *factory = deg_type_get_factory(type);
|
||||
comp_node = (ComponentDepsNode *)factory->create_node(this->id_orig, "", name);
|
||||
|
||||
/* Register. */
|
||||
ComponentIDKey *key = OBJECT_GUARDED_NEW(ComponentIDKey, type, name);
|
||||
BLI_ghash_insert(components, key, comp_node);
|
||||
comp_node->owner = this;
|
||||
}
|
||||
return comp_node;
|
||||
}
|
||||
|
||||
void IDDepsNode::tag_update(Depsgraph *graph)
|
||||
{
|
||||
GHASH_FOREACH_BEGIN(ComponentDepsNode *, comp_node, components)
|
||||
{
|
||||
comp_node->tag_update(graph);
|
||||
}
|
||||
GHASH_FOREACH_END();
|
||||
}
|
||||
|
||||
void IDDepsNode::finalize_build(Depsgraph *graph)
|
||||
{
|
||||
/* Finalize build of all components. */
|
||||
GHASH_FOREACH_BEGIN(ComponentDepsNode *, comp_node, components)
|
||||
{
|
||||
comp_node->finalize_build(graph);
|
||||
}
|
||||
GHASH_FOREACH_END();
|
||||
}
|
||||
|
||||
} // namespace DEG
|
||||
81
source/blender/depsgraph/intern/nodes/deg_node_id.h
Normal file
81
source/blender/depsgraph/intern/nodes/deg_node_id.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* 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) 2013 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Original Author: Joshua Leung
|
||||
* Contributor(s): None Yet
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file depsgraph/intern/nodes/deg_node_id.h
|
||||
* \ingroup depsgraph
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "intern/nodes/deg_node.h"
|
||||
|
||||
namespace DEG {
|
||||
|
||||
struct ComponentDepsNode;
|
||||
|
||||
/* ID-Block Reference */
|
||||
struct IDDepsNode : public DepsNode {
|
||||
struct ComponentIDKey {
|
||||
ComponentIDKey(eDepsNode_Type type, const char *name = "");
|
||||
bool operator==(const ComponentIDKey &other) const;
|
||||
|
||||
eDepsNode_Type type;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
void init(const ID *id, const char *subdata);
|
||||
void init_copy_on_write(ID *id_cow_hint = NULL);
|
||||
~IDDepsNode();
|
||||
void destroy();
|
||||
|
||||
ComponentDepsNode *find_component(eDepsNode_Type type,
|
||||
const char *name = "") const;
|
||||
ComponentDepsNode *add_component(eDepsNode_Type type,
|
||||
const char *name = "");
|
||||
|
||||
void tag_update(Depsgraph *graph);
|
||||
|
||||
void finalize_build(Depsgraph *graph);
|
||||
|
||||
/* ID Block referenced. */
|
||||
ID *id_orig;
|
||||
ID *id_cow;
|
||||
|
||||
/* Hash to make it faster to look up components. */
|
||||
GHash *components;
|
||||
|
||||
/* Additional flags needed for scene evaluation.
|
||||
* TODO(sergey): Only needed for until really granular updates
|
||||
* of all the entities.
|
||||
*/
|
||||
int eval_flags;
|
||||
|
||||
eDepsNode_LinkedState_Type linked_state;
|
||||
|
||||
DEG_DEPSNODE_DECLARE;
|
||||
};
|
||||
|
||||
} // namespace DEG
|
||||
@@ -37,6 +37,7 @@
|
||||
|
||||
#include "intern/depsgraph.h"
|
||||
#include "intern/depsgraph_intern.h"
|
||||
#include "intern/nodes/deg_node_id.h"
|
||||
|
||||
namespace DEG {
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@ struct Depsgraph;
|
||||
|
||||
namespace DEG {
|
||||
|
||||
struct ComponentDepsNode;
|
||||
|
||||
/* Flags for Depsgraph Nodes */
|
||||
typedef enum eDepsOperation_Flag {
|
||||
/* node needs to be updated */
|
||||
|
||||
46
source/blender/depsgraph/intern/nodes/deg_node_time.cc
Normal file
46
source/blender/depsgraph/intern/nodes/deg_node_time.cc
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* 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) 2013 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Original Author: Joshua Leung
|
||||
* Contributor(s): None Yet
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/depsgraph/intern/nodes/deg_node_time.cc
|
||||
* \ingroup depsgraph
|
||||
*/
|
||||
|
||||
#include "intern/nodes/deg_node_time.h"
|
||||
|
||||
#include "intern/depsgraph_intern.h"
|
||||
#include "util/deg_util_foreach.h"
|
||||
|
||||
namespace DEG {
|
||||
|
||||
void TimeSourceDepsNode::tag_update(Depsgraph *graph)
|
||||
{
|
||||
foreach (DepsRelation *rel, outlinks) {
|
||||
DepsNode *node = rel->to;
|
||||
node->tag_update(graph);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace DEG
|
||||
52
source/blender/depsgraph/intern/nodes/deg_node_time.h
Normal file
52
source/blender/depsgraph/intern/nodes/deg_node_time.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* 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) 2013 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Original Author: Joshua Leung
|
||||
* Contributor(s): None Yet
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file depsgraph/intern/nodes/deg_node_time.h
|
||||
* \ingroup depsgraph
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "intern/nodes/deg_node.h"
|
||||
|
||||
namespace DEG {
|
||||
|
||||
/* Time Source Node. */
|
||||
struct TimeSourceDepsNode : public DepsNode {
|
||||
/* New "current time". */
|
||||
float cfra;
|
||||
|
||||
/* time-offset relative to the "official" time source that this one has. */
|
||||
float offset;
|
||||
|
||||
// TODO: evaluate() operation needed
|
||||
|
||||
void tag_update(Depsgraph *graph);
|
||||
|
||||
DEG_DEPSNODE_DECLARE;
|
||||
};
|
||||
|
||||
} // namespace DEG
|
||||
Reference in New Issue
Block a user