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:
authorJacques Lucke <jacques@blender.org>2020-02-25 19:30:37 +0300
committerJacques Lucke <jacques@blender.org>2020-02-25 19:30:37 +0300
commitb206f0ae0f3774f08e95663610165ebb5f5b0a24 (patch)
treef282cabf50d6f2d3e6573a1602c3ca3df0ecc563
parent2f2e2d17486d00b057c349ee8744893b02bc1d45 (diff)
run node declaration function only once per update
-rw-r--r--source/blender/blenlib/BLI_index_mask.h9
-rw-r--r--source/blender/blenlib/BLI_linear_allocated_vector.h7
-rw-r--r--source/blender/simulations/nodes/my_test_node.cc110
3 files changed, 82 insertions, 44 deletions
diff --git a/source/blender/blenlib/BLI_index_mask.h b/source/blender/blenlib/BLI_index_mask.h
index 85cb3025fae..cbd6110de7f 100644
--- a/source/blender/blenlib/BLI_index_mask.h
+++ b/source/blender/blenlib/BLI_index_mask.h
@@ -102,6 +102,15 @@ class IndexMask {
}
}
+ template<typename T, typename FuncT>
+ void foreach_element(ArrayRef<T> elements, const FuncT &func)
+ {
+ for (uint i : m_indices) {
+ const T &value = elements[i];
+ func(value);
+ }
+ }
+
IndexRange index_range() const
{
return m_indices.index_range();
diff --git a/source/blender/blenlib/BLI_linear_allocated_vector.h b/source/blender/blenlib/BLI_linear_allocated_vector.h
index a70f83c98fb..bdcf026ba63 100644
--- a/source/blender/blenlib/BLI_linear_allocated_vector.h
+++ b/source/blender/blenlib/BLI_linear_allocated_vector.h
@@ -130,6 +130,13 @@ template<typename T> class LinearAllocatedVector : BLI::NonCopyable {
return index;
}
+ template<typename AllocT> void reserve(uint reserve_size, LinearAllocator<AllocT> &allocator)
+ {
+ if (this->size() < reserve_size) {
+ this->grow(reserve_size, allocator);
+ }
+ }
+
bool contains(const T &value) const
{
for (const T &current : *this) {
diff --git a/source/blender/simulations/nodes/my_test_node.cc b/source/blender/simulations/nodes/my_test_node.cc
index bd978d9d8cf..21b960079a6 100644
--- a/source/blender/simulations/nodes/my_test_node.cc
+++ b/source/blender/simulations/nodes/my_test_node.cc
@@ -16,6 +16,8 @@
#include "BLI_map.h"
#include "BLI_listbase_wrapper.h"
#include "BLI_string_utils.h"
+#include "BLI_linear_allocated_vector.h"
+#include "BLI_index_mask.h"
#include "PIL_time.h"
@@ -29,9 +31,12 @@
using BLI::Array;
using BLI::ArrayRef;
+using BLI::IndexMask;
using BLI::IntrusiveListBaseWrapper;
+using BLI::LinearAllocatedVector;
using BLI::LinearAllocator;
using BLI::Map;
+using BLI::MutableArrayRef;
using BLI::rgba_f;
using BLI::Set;
using BLI::StringRef;
@@ -221,31 +226,38 @@ class MockupSocketDecl final : public SocketDecl {
class NodeDecl {
public:
- bNodeTree &m_ntree;
- bNode &m_node;
- Vector<SocketDecl *> m_inputs;
- Vector<SocketDecl *> m_outputs;
+ bNodeTree *m_ntree;
+ bNode *m_node;
+ LinearAllocatedVector<SocketDecl *> m_inputs;
+ LinearAllocatedVector<SocketDecl *> m_outputs;
- NodeDecl(bNodeTree &ntree, bNode &node) : m_ntree(ntree), m_node(node)
+ NodeDecl(bNodeTree *ntree, bNode *node) : m_ntree(ntree), m_node(node)
{
}
+ void reserve_decls(LinearAllocator<> &allocator, uint input_amount, uint output_amount)
+ {
+ m_inputs.reserve(input_amount, allocator);
+ m_outputs.reserve(output_amount, allocator);
+ }
+
void build() const
{
+ nodeRemoveAllSockets(m_ntree, m_node);
for (SocketDecl *decl : m_inputs) {
- decl->build(&m_ntree, &m_node, SOCK_IN);
+ decl->build(m_ntree, m_node, SOCK_IN);
}
for (SocketDecl *decl : m_outputs) {
- decl->build(&m_ntree, &m_node, SOCK_OUT);
+ decl->build(m_ntree, m_node, SOCK_OUT);
}
}
bool sockets_are_correct() const
{
- if (!this->sockets_are_correct(m_node.inputs, m_inputs)) {
+ if (!this->sockets_are_correct(m_node->inputs, m_inputs)) {
return false;
}
- if (!this->sockets_are_correct(m_node.outputs, m_outputs)) {
+ if (!this->sockets_are_correct(m_node->outputs, m_outputs)) {
return false;
}
return true;
@@ -289,28 +301,28 @@ class NodeBuilder {
template<typename T> T *node_storage()
{
- return get_node_storage<T>(&m_node_decl.m_node);
+ return get_node_storage<T>(m_node_decl.m_node);
}
void fixed_input(StringRef identifier, StringRef ui_name, SocketDataType &type)
{
FixedDataTypeSocketDecl *decl = m_allocator.construct<FixedDataTypeSocketDecl>(
m_allocator.copy_string(identifier), m_allocator.copy_string(ui_name), &type);
- m_node_decl.m_inputs.append(decl);
+ m_node_decl.m_inputs.append(decl, m_allocator);
}
void fixed_output(StringRef identifier, StringRef ui_name, SocketDataType &type)
{
FixedDataTypeSocketDecl *decl = m_allocator.construct<FixedDataTypeSocketDecl>(
m_allocator.copy_string(identifier), m_allocator.copy_string(ui_name), &type);
- m_node_decl.m_outputs.append(decl);
+ m_node_decl.m_outputs.append(decl, m_allocator);
}
void operator_input(StringRef identifier, StringRef ui_name, OperatorSocketFn callback)
{
OperatorSocketDecl *decl = m_allocator.construct<OperatorSocketDecl>(
m_allocator.copy_string(ui_name), m_allocator.copy_string(identifier), callback);
- m_node_decl.m_inputs.append(decl);
+ m_node_decl.m_inputs.append(decl, m_allocator);
}
void float_input(StringRef identifier, StringRef ui_name)
@@ -701,7 +713,7 @@ class NodeDefinition {
NodeDefinition *def = type_from_node(node);
LinearAllocator<> allocator;
- NodeDecl node_decl{*ntree, *node};
+ NodeDecl node_decl{ntree, node};
NodeBuilder node_builder{allocator, node_decl};
node->storage = def->m_new_storage_fn();
def->m_declare_node_fn(node_builder);
@@ -995,13 +1007,13 @@ template<> class DefaultHash<SocketID> {
}; // namespace BLI
static void rebuild_nodes_and_keep_state(VirtualNodeTree &vtree,
- ArrayRef<const VNode *> vnodes,
- LinearAllocator<> &allocator)
+ IndexMask index_mask,
+ ArrayRef<const NodeDecl *> node_decls)
{
Set<std::pair<SocketID, SocketID>> links_to_restore;
Map<SocketID, std::pair<const SocketDefinition *, void *>> value_per_socket;
- for (const VNode *vnode : vnodes) {
+ index_mask.foreach_element(vtree.nodes(), [&](const VNode *vnode) {
for (const VInputSocket *vinput : vnode->inputs()) {
SocketID id_to = {vinput->node().bnode(), SOCK_IN, vinput->identifier()};
const SocketDefinition *def = SocketDefinition::get_from_socket(vinput->bsocket());
@@ -1028,19 +1040,11 @@ static void rebuild_nodes_and_keep_state(VirtualNodeTree &vtree,
links_to_restore.add({id_from, std::move(id_to)});
}
}
- }
-
- bNodeTree *ntree = vtree.btree();
+ });
- for (const VNode *vnode : vnodes) {
- bNode *node = vnode->bnode();
- NodeDecl node_decl{*ntree, *node};
- NodeBuilder builder{allocator, node_decl};
- NodeDefinition::declare_node(node, builder);
- nodeRemoveAllSockets(ntree, node);
- node_decl.build();
- }
+ index_mask.foreach_element(node_decls, [&](const NodeDecl *node_decl) { node_decl->build(); });
+ bNodeTree *ntree = vtree.btree();
for (const std::pair<SocketID, SocketID> &link_info : links_to_restore) {
const SocketID &from_id = link_info.first;
const SocketID &to_id = link_info.second;
@@ -1069,28 +1073,21 @@ static void rebuild_nodes_and_keep_state(VirtualNodeTree &vtree,
});
}
-static bool rebuild_currently_outdated_nodes(VirtualNodeTree &vtree)
+static bool rebuild_currently_outdated_nodes(VirtualNodeTree &vtree,
+ ArrayRef<const NodeDecl *> node_decls)
{
LinearAllocator<> allocator;
- Vector<const VNode *> vnodes_to_update;
-
- bNodeTree *ntree = vtree.btree();
- for (const VNode *vnode : vtree.nodes()) {
- bNode *node = vnode->bnode();
- NodeDecl node_decl{*ntree, *node};
- NodeBuilder builder{allocator, node_decl};
- NodeDefinition::declare_node(node, builder);
-
- if (!node_decl.sockets_are_correct()) {
- vnodes_to_update.append(vnode);
- node_decl.build();
+ Vector<uint> node_indices_to_update;
+ for (uint i : node_decls.index_range()) {
+ if (!node_decls[i]->sockets_are_correct()) {
+ node_indices_to_update.append(i);
}
}
- rebuild_nodes_and_keep_state(vtree, vnodes_to_update, allocator);
+ rebuild_nodes_and_keep_state(vtree, node_indices_to_update, node_decls);
- return vnodes_to_update.size() > 0;
+ return node_indices_to_update.size() > 0;
}
static bool remove_invalid_links(VirtualNodeTree &vtree)
@@ -1111,10 +1108,35 @@ static bool remove_invalid_links(VirtualNodeTree &vtree)
return links_to_remove.size() > 0;
}
+static void get_node_declarations(bNodeTree *ntree,
+ ArrayRef<const VNode *> vnodes,
+ LinearAllocator<> &allocator,
+ MutableArrayRef<const NodeDecl *> r_node_decls)
+{
+ BLI::assert_same_size(vnodes, r_node_decls);
+
+ /* TODO: handle reroute and frames */
+ for (uint i : vnodes.index_range()) {
+ const VNode &vnode = *vnodes[i];
+ bNode *node = vnode.bnode();
+ NodeDecl *node_decl = allocator.construct<NodeDecl>(ntree, node);
+ node_decl->reserve_decls(allocator, vnode.inputs().size(), vnode.outputs().size());
+
+ NodeBuilder builder{allocator, *node_decl};
+ NodeDefinition::declare_node(node, builder);
+ r_node_decls[i] = node_decl;
+ }
+}
+
void update_sim_node_tree(bNodeTree *ntree)
{
VirtualNodeTree vtree(ntree);
- if (rebuild_currently_outdated_nodes(vtree)) {
+ LinearAllocator<> allocator;
+
+ Array<const NodeDecl *> node_decls(vtree.nodes().size());
+ get_node_declarations(ntree, vtree.nodes(), allocator, node_decls);
+
+ if (rebuild_currently_outdated_nodes(vtree, node_decls)) {
vtree.~VirtualNodeTree();
new (&vtree) VirtualNodeTree(ntree);
}