Nodes: Resolve performance bottleneck with mix node updates
Improve animation playback performance in EEVEE for materials using Mix nodes. Socket availability was being set and reset on every evaluation of Mix nodes, during animation playback, this was causing the graph to be marked dirty, and the whole graph being re-evaluated on every frame, causing performance issues during playback. Additionally, do a bit of cleanup, traversing the node sockets with the next link to improve clarity and reduce errors. Also refactoring `nodeSetSocketAvailability` to early out and increase clarity on no-op. Differential Revision: https://developer.blender.org/D16929
This commit is contained in:
parent
e0d70e6a9d
commit
a3a60e9647
|
@ -3561,16 +3561,16 @@ void nodeSetActive(bNodeTree *ntree, bNode *node)
|
|||
void nodeSetSocketAvailability(bNodeTree *ntree, bNodeSocket *sock, bool is_available)
|
||||
{
|
||||
const bool was_available = (sock->flag & SOCK_UNAVAIL) == 0;
|
||||
if (is_available != was_available) {
|
||||
BKE_ntree_update_tag_socket_availability(ntree, sock);
|
||||
if (is_available == was_available) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_available) {
|
||||
sock->flag &= ~SOCK_UNAVAIL;
|
||||
}
|
||||
else {
|
||||
sock->flag |= SOCK_UNAVAIL;
|
||||
}
|
||||
BKE_ntree_update_tag_socket_availability(ntree, sock);
|
||||
}
|
||||
|
||||
int nodeSocketLinkLimit(const bNodeSocket *sock)
|
||||
|
|
|
@ -108,22 +108,23 @@ static void sh_node_mix_update(bNodeTree *ntree, bNode *node)
|
|||
const NodeShaderMix &storage = node_storage(*node);
|
||||
const eNodeSocketDatatype data_type = static_cast<eNodeSocketDatatype>(storage.data_type);
|
||||
|
||||
LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
|
||||
bNodeSocket *sock_factor = static_cast<bNodeSocket *>(node->inputs.first);
|
||||
bNodeSocket *sock_factor_vec = static_cast<bNodeSocket *>(sock_factor->next);
|
||||
|
||||
bool use_vector_factor = data_type == SOCK_VECTOR &&
|
||||
storage.factor_mode != NODE_MIX_MODE_UNIFORM;
|
||||
|
||||
nodeSetSocketAvailability(ntree, sock_factor, !use_vector_factor);
|
||||
|
||||
nodeSetSocketAvailability(ntree, sock_factor_vec, use_vector_factor);
|
||||
|
||||
for (bNodeSocket *socket = sock_factor_vec->next; socket != nullptr; socket = socket->next) {
|
||||
nodeSetSocketAvailability(ntree, socket, socket->type == data_type);
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (bNodeSocket *, socket, &node->outputs) {
|
||||
nodeSetSocketAvailability(ntree, socket, socket->type == data_type);
|
||||
}
|
||||
|
||||
bool use_vector_factor = data_type == SOCK_VECTOR &&
|
||||
storage.factor_mode != NODE_MIX_MODE_UNIFORM;
|
||||
|
||||
bNodeSocket *sock_factor = (bNodeSocket *)BLI_findlink(&node->inputs, 0);
|
||||
nodeSetSocketAvailability(ntree, sock_factor, !use_vector_factor);
|
||||
|
||||
bNodeSocket *sock_factor_vec = (bNodeSocket *)BLI_findlink(&node->inputs, 1);
|
||||
nodeSetSocketAvailability(ntree, sock_factor_vec, use_vector_factor);
|
||||
}
|
||||
|
||||
class SocketSearchOp {
|
||||
|
|
Loading…
Reference in New Issue