From 626201683ec0d96e86d681bb0273a324cdf91916 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dietrich?= Date: Tue, 22 Sep 2020 14:47:10 +0200 Subject: Cycles: add update flags to Node and SocketType Those flags are meant for detecting which socket has changed, so in the future we can have more granular updates. `Node` now stores an `update_flags` member which is modified every time a socket is changed though `Node::set`. The flags are or-able bits stored in `SocketType` instances. Each `SocketType` stores a unique bit out of 64, for the 64 bits of an uint64_t; the bit corresponds to the index of the socket in the `Node`'s sockets array + 1, so the socket at index 5 will have the 6th bit set as its flag. This limits us to 64 sockets per Node, which should be plenty for the current set of `Nodes` that we have. This does not change the behavior of other parts of Cycles. This is part of T79131. Reviewed By: brecht Maniphest Tasks: T79131 Differential Revision: https://developer.blender.org/D8644 --- intern/cycles/graph/node.cpp | 89 +++++++++++++++++++++++++++++++-------- intern/cycles/graph/node.h | 15 +++++++ intern/cycles/graph/node_type.cpp | 2 + intern/cycles/graph/node_type.h | 3 ++ 4 files changed, 91 insertions(+), 18 deletions(-) (limited to 'intern') diff --git a/intern/cycles/graph/node.cpp b/intern/cycles/graph/node.cpp index 37387053d97..4d32d52aa83 100644 --- a/intern/cycles/graph/node.cpp +++ b/intern/cycles/graph/node.cpp @@ -35,6 +35,7 @@ Node::Node(const NodeType *type_, ustring name_) : name(name_), type(type_) assert(type); owner = nullptr; + socket_modified = ~0; /* assign non-empty name, convenient for debugging */ if (name.empty()) { @@ -74,37 +75,37 @@ static bool is_socket_array_float3(const SocketType &socket) void Node::set(const SocketType &input, bool value) { assert(input.type == SocketType::BOOLEAN); - get_socket_value(this, input) = value; + set_if_different(input, value); } void Node::set(const SocketType &input, int value) { assert((input.type == SocketType::INT || input.type == SocketType::ENUM)); - get_socket_value(this, input) = value; + set_if_different(input, value); } void Node::set(const SocketType &input, uint value) { assert(input.type == SocketType::UINT); - get_socket_value(this, input) = value; + set_if_different(input, value); } void Node::set(const SocketType &input, float value) { assert(input.type == SocketType::FLOAT); - get_socket_value(this, input) = value; + set_if_different(input, value); } void Node::set(const SocketType &input, float2 value) { assert(input.type == SocketType::FLOAT); - get_socket_value(this, input) = value; + set_if_different(input, value); } void Node::set(const SocketType &input, float3 value) { assert(is_socket_float3(input)); - get_socket_value(this, input) = value; + set_if_different(input, value); } void Node::set(const SocketType &input, const char *value) @@ -115,12 +116,12 @@ void Node::set(const SocketType &input, const char *value) void Node::set(const SocketType &input, ustring value) { if (input.type == SocketType::STRING) { - get_socket_value(this, input) = value; + set_if_different(input, value); } else if (input.type == SocketType::ENUM) { const NodeEnum &enm = *input.enum_values; if (enm.exists(value)) { - get_socket_value(this, input) = enm[value]; + set_if_different(input, enm[value]); } else { assert(0); @@ -134,62 +135,62 @@ void Node::set(const SocketType &input, ustring value) void Node::set(const SocketType &input, const Transform &value) { assert(input.type == SocketType::TRANSFORM); - get_socket_value(this, input) = value; + set_if_different(input, value); } void Node::set(const SocketType &input, Node *value) { assert(input.type == SocketType::NODE); - get_socket_value(this, input) = value; + set_if_different(input, value); } /* set array values */ void Node::set(const SocketType &input, array &value) { assert(input.type == SocketType::BOOLEAN_ARRAY); - get_socket_value>(this, input).steal_data(value); + set_if_different(input, value); } void Node::set(const SocketType &input, array &value) { assert(input.type == SocketType::INT_ARRAY); - get_socket_value>(this, input).steal_data(value); + set_if_different(input, value); } void Node::set(const SocketType &input, array &value) { assert(input.type == SocketType::FLOAT_ARRAY); - get_socket_value>(this, input).steal_data(value); + set_if_different(input, value); } void Node::set(const SocketType &input, array &value) { assert(input.type == SocketType::FLOAT_ARRAY); - get_socket_value>(this, input).steal_data(value); + set_if_different(input, value); } void Node::set(const SocketType &input, array &value) { assert(is_socket_array_float3(input)); - get_socket_value>(this, input).steal_data(value); + set_if_different(input, value); } void Node::set(const SocketType &input, array &value) { assert(input.type == SocketType::STRING_ARRAY); - get_socket_value>(this, input).steal_data(value); + set_if_different(input, value); } void Node::set(const SocketType &input, array &value) { assert(input.type == SocketType::TRANSFORM_ARRAY); - get_socket_value>(this, input).steal_data(value); + set_if_different(input, value); } void Node::set(const SocketType &input, array &value) { assert(input.type == SocketType::TRANSFORM_ARRAY); - get_socket_value>(this, input).steal_data(value); + set_if_different(input, value); } /* get values */ @@ -696,4 +697,56 @@ void Node::set_owner(const NodeOwner *owner_) owner = owner_; } +bool Node::socket_is_modified(const SocketType &input) const +{ + return (socket_modified & input.modified_flag_bit) != 0; +} + +bool Node::is_modified() +{ + return socket_modified != 0; +} + +void Node::tag_modified() +{ + socket_modified = ~0u; +} + +void Node::clear_modified() +{ + socket_modified = 0; +} + +template void Node::set_if_different(const SocketType &input, T value) +{ + if (get_socket_value(this, input) == value) { + return; + } + + get_socket_value(this, input) = value; + socket_modified |= input.modified_flag_bit; +} + +template void Node::set_if_different(const SocketType &input, array &value) +{ + if (!socket_is_modified(input)) { + if (get_socket_value>(this, input) == value) { + return; + } + } + + get_socket_value>(this, input).steal_data(value); + socket_modified |= input.modified_flag_bit; +} + +void Node::print_modified_sockets() const +{ + printf("Node : %s\n", name.c_str()); + for (auto &socket : type->inputs) { + if (socket_is_modified(socket)) { + printf("-- socket modified : %s\n", socket.name.c_str()); + } + } +} + CCL_NAMESPACE_END diff --git a/intern/cycles/graph/node.h b/intern/cycles/graph/node.h index 3c84dbdb4a7..16bd5e4358a 100644 --- a/intern/cycles/graph/node.h +++ b/intern/cycles/graph/node.h @@ -101,6 +101,15 @@ struct Node { /* Type testing, taking into account base classes. */ bool is_a(const NodeType *type); + bool socket_is_modified(const SocketType &input) const; + + bool is_modified(); + + void tag_modified(); + void clear_modified(); + + void print_modified_sockets() const; + ustring name; const NodeType *type; @@ -109,6 +118,12 @@ struct Node { protected: const NodeOwner *owner; + + SocketModifiedFlags socket_modified; + + template void set_if_different(const SocketType &input, T value); + + template void set_if_different(const SocketType &input, array &value); }; CCL_NAMESPACE_END diff --git a/intern/cycles/graph/node_type.cpp b/intern/cycles/graph/node_type.cpp index 0283ed7c817..0ec421023a2 100644 --- a/intern/cycles/graph/node_type.cpp +++ b/intern/cycles/graph/node_type.cpp @@ -167,6 +167,8 @@ void NodeType::register_input(ustring name, socket.enum_values = enum_values; socket.node_type = node_type; socket.flags = flags | extra_flags; + assert(inputs.size() < std::numeric_limits::digits); + socket.modified_flag_bit = (1ul << inputs.size()); inputs.push_back(socket); } diff --git a/intern/cycles/graph/node_type.h b/intern/cycles/graph/node_type.h index a79d44b82f3..0d182945e16 100644 --- a/intern/cycles/graph/node_type.h +++ b/intern/cycles/graph/node_type.h @@ -28,6 +28,8 @@ CCL_NAMESPACE_BEGIN struct Node; struct NodeType; +typedef uint64_t SocketModifiedFlags; + /* Socket Type */ struct SocketType { @@ -88,6 +90,7 @@ struct SocketType { const NodeType **node_type; int flags; ustring ui_name; + SocketModifiedFlags modified_flag_bit; size_t size() const; bool is_array() const; -- cgit v1.2.3