Depsgraph: Make visible update to operate on per-component level
This commit is contained in:
@@ -163,16 +163,18 @@ IDDepsNode *DepsgraphNodeBuilder::add_id_node(ID *id)
|
||||
{
|
||||
IDDepsNode *id_node = NULL;
|
||||
ID *id_cow = NULL;
|
||||
bool is_previous_directly_visible = false;
|
||||
IDComponentsMask previously_visible_components_mask = 0;
|
||||
IDInfo *id_info = (IDInfo *)BLI_ghash_lookup(id_info_hash_, id);
|
||||
if (id_info != NULL) {
|
||||
id_cow = id_info->id_cow;
|
||||
is_previous_directly_visible = id_info->is_directly_visible;
|
||||
previously_visible_components_mask =
|
||||
id_info->previously_visible_components_mask;
|
||||
/* Tag ID info to not free the CoW ID pointer. */
|
||||
id_info->id_cow = NULL;
|
||||
}
|
||||
id_node = graph_->add_id_node(id, id_cow);
|
||||
id_node->is_previous_directly_visible = is_previous_directly_visible;
|
||||
id_node->previously_visible_components_mask =
|
||||
previously_visible_components_mask;
|
||||
/* Currently all ID nodes are supposed to have copy-on-write logic.
|
||||
*
|
||||
* NOTE: Zero number of components indicates that ID node was just created.
|
||||
@@ -352,7 +354,8 @@ void DepsgraphNodeBuilder::begin_build()
|
||||
else {
|
||||
id_info->id_cow = NULL;
|
||||
}
|
||||
id_info->is_directly_visible = id_node->is_directly_visible;
|
||||
id_info->previously_visible_components_mask =
|
||||
id_node->visible_components_mask;
|
||||
BLI_ghash_insert(id_info_hash_, id_node->id_orig, id_info);
|
||||
id_node->id_cow = NULL;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
|
||||
#include "intern/nodes/deg_node_id.h"
|
||||
|
||||
struct Base;
|
||||
struct bArmature;
|
||||
struct bAction;
|
||||
@@ -225,10 +227,10 @@ struct DepsgraphNodeBuilder {
|
||||
struct IDInfo {
|
||||
/* Copy-on-written pointer of the corresponding ID. */
|
||||
ID *id_cow;
|
||||
/* State of the is_visible from ID node from previous state of the
|
||||
/* Mask of visible components from previous state of the
|
||||
* dependency graph.
|
||||
*/
|
||||
bool is_directly_visible;
|
||||
IDComponentsMask previously_visible_components_mask;
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
@@ -485,17 +485,16 @@ void deg_id_tag_update(Main *bmain, ID *id, int flag)
|
||||
|
||||
void deg_graph_on_visible_update(Main *bmain, Depsgraph *graph)
|
||||
{
|
||||
/* TODO(sergey): We might want to tag components which did not affect
|
||||
* anything visible before new objects became visible.
|
||||
*/
|
||||
foreach (DEG::IDDepsNode *id_node, graph->id_nodes) {
|
||||
if (!id_node->is_directly_visible) {
|
||||
/* ID is not visible within the current dependency graph, no need
|
||||
* botherwith it to tag or anything.
|
||||
if (!id_node->visible_components_mask) {
|
||||
/* ID cas no components which affects anything visible. no meed
|
||||
* bother with it to tag or anything.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
if (id_node->is_previous_directly_visible) {
|
||||
if (id_node->visible_components_mask ==
|
||||
id_node->previously_visible_components_mask)
|
||||
{
|
||||
/* The ID was already visible and evaluated, all the subsequent
|
||||
* updates and tags are to be done explicitly.
|
||||
*/
|
||||
@@ -530,7 +529,8 @@ void deg_graph_on_visible_update(Main *bmain, Depsgraph *graph)
|
||||
* tags we request from here will be applied in the updated state of
|
||||
* dependency graph.
|
||||
*/
|
||||
id_node->is_previous_directly_visible = true;
|
||||
id_node->previously_visible_components_mask =
|
||||
id_node->visible_components_mask;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -105,7 +105,9 @@ void IDDepsNode::init(const ID *id, const char *UNUSED(subdata))
|
||||
eval_flags = 0;
|
||||
linked_state = DEG_ID_LINKED_INDIRECTLY;
|
||||
is_directly_visible = true;
|
||||
is_previous_directly_visible = false;
|
||||
|
||||
visible_components_mask = 0;
|
||||
previously_visible_components_mask = 0;
|
||||
|
||||
components = BLI_ghash_new(id_deps_node_hash_key,
|
||||
id_deps_node_hash_key_cmp,
|
||||
@@ -218,6 +220,21 @@ void IDDepsNode::finalize_build(Depsgraph *graph)
|
||||
comp_node->finalize_build(graph);
|
||||
}
|
||||
GHASH_FOREACH_END();
|
||||
visible_components_mask = get_visible_components_mask();
|
||||
}
|
||||
|
||||
IDComponentsMask IDDepsNode::get_visible_components_mask() const {
|
||||
IDComponentsMask result = 0;
|
||||
GHASH_FOREACH_BEGIN(ComponentDepsNode *, comp_node, components)
|
||||
{
|
||||
if (comp_node->affects_directly_visible) {
|
||||
const int component_type = comp_node->type;
|
||||
BLI_assert(component_type < 64);
|
||||
result |= (1 << component_type);
|
||||
}
|
||||
}
|
||||
GHASH_FOREACH_END();
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace DEG
|
||||
|
||||
@@ -31,11 +31,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "intern/nodes/deg_node.h"
|
||||
#include "BLI_sys_types.h"
|
||||
|
||||
namespace DEG {
|
||||
|
||||
struct ComponentDepsNode;
|
||||
|
||||
typedef uint64_t IDComponentsMask;
|
||||
|
||||
/* ID-Block Reference */
|
||||
struct IDDepsNode : public DepsNode {
|
||||
struct ComponentIDKey {
|
||||
@@ -62,6 +65,8 @@ struct IDDepsNode : public DepsNode {
|
||||
|
||||
void finalize_build(Depsgraph *graph);
|
||||
|
||||
IDComponentsMask get_visible_components_mask() const;
|
||||
|
||||
/* ID Block referenced. */
|
||||
ID *id_orig;
|
||||
ID *id_cow;
|
||||
@@ -79,13 +84,9 @@ struct IDDepsNode : public DepsNode {
|
||||
|
||||
/* Indicates the datablock is visible in the evaluated scene. */
|
||||
bool is_directly_visible;
|
||||
/* Is used to detect when ID becomes visible within a dependency graph,
|
||||
* this value equals to:
|
||||
* - False if the ID was never inside of the dependency graph.
|
||||
* - Value if is_visible of ID node from the previous state of the
|
||||
* dependency graph.
|
||||
*/
|
||||
bool is_previous_directly_visible;
|
||||
|
||||
IDComponentsMask visible_components_mask;
|
||||
IDComponentsMask previously_visible_components_mask;
|
||||
|
||||
DEG_DEPSNODE_DECLARE;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user