Nodes: Update dependency graph when removing some nodes

When removing a node that has a dependence on an ID, like the object
info node, the dependency graph relations weren't updated. This can
cause unexpected performance issues if a complex node tree continues
to depend on an ID that it doesn't actually use anymore. To fix this case,
tag relations for an update if the node has a data-block socket.

Fixes part of T88332

Differential Revision: https://developer.blender.org/D14121
This commit is contained in:
Hans Goudey 2022-02-18 09:24:28 -06:00
parent ceea3d0f80
commit 734c6a4405
Notes: blender-bot 2023-10-13 01:54:23 +02:00
Referenced by commit bdb85bdd98, Fix T100308: Removing scene time node does not update relations
Referenced by issue #88332, Geometry nodes impacting performance even when GN modifier fully disabled
1 changed files with 19 additions and 3 deletions

View File

@ -1562,13 +1562,15 @@ static void socket_id_user_increment(bNodeSocket *sock)
}
}
static void socket_id_user_decrement(bNodeSocket *sock)
/** \return True if the socket had an ID default value. */
static bool socket_id_user_decrement(bNodeSocket *sock)
{
switch ((eNodeSocketDatatype)sock->type) {
case SOCK_OBJECT: {
bNodeSocketValueObject *default_value = (bNodeSocketValueObject *)sock->default_value;
if (default_value->value != nullptr) {
id_us_min(&default_value->value->id);
return true;
}
break;
}
@ -1576,6 +1578,7 @@ static void socket_id_user_decrement(bNodeSocket *sock)
bNodeSocketValueImage *default_value = (bNodeSocketValueImage *)sock->default_value;
if (default_value->value != nullptr) {
id_us_min(&default_value->value->id);
return true;
}
break;
}
@ -1584,6 +1587,7 @@ static void socket_id_user_decrement(bNodeSocket *sock)
sock->default_value;
if (default_value->value != nullptr) {
id_us_min(&default_value->value->id);
return true;
}
break;
}
@ -1591,6 +1595,7 @@ static void socket_id_user_decrement(bNodeSocket *sock)
bNodeSocketValueTexture *default_value = (bNodeSocketValueTexture *)sock->default_value;
if (default_value->value != nullptr) {
id_us_min(&default_value->value->id);
return true;
}
break;
}
@ -1598,6 +1603,7 @@ static void socket_id_user_decrement(bNodeSocket *sock)
bNodeSocketValueMaterial *default_value = (bNodeSocketValueMaterial *)sock->default_value;
if (default_value->value != nullptr) {
id_us_min(&default_value->value->id);
return true;
}
break;
}
@ -1613,6 +1619,7 @@ static void socket_id_user_decrement(bNodeSocket *sock)
case SOCK_GEOMETRY:
break;
}
return false;
}
void nodeModifySocketType(bNodeTree *ntree,
@ -2972,6 +2979,8 @@ void nodeRemoveNode(Main *bmain, bNodeTree *ntree, bNode *node, bool do_id_user)
* do to ID user refcounting and removal of animdation data then. */
BLI_assert((ntree->id.tag & LIB_TAG_LOCALIZED) == 0);
bool node_has_id = false;
if (do_id_user) {
/* Free callback for NodeCustomGroup. */
if (node->typeinfo->freefunc_api) {
@ -2984,13 +2993,14 @@ void nodeRemoveNode(Main *bmain, bNodeTree *ntree, bNode *node, bool do_id_user)
/* Do user counting. */
if (node->id) {
id_us_min(node->id);
node_has_id = true;
}
LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
socket_id_user_decrement(sock);
node_has_id |= socket_id_user_decrement(sock);
}
LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
socket_id_user_decrement(sock);
node_has_id |= socket_id_user_decrement(sock);
}
}
@ -3007,6 +3017,12 @@ void nodeRemoveNode(Main *bmain, bNodeTree *ntree, bNode *node, bool do_id_user)
}
}
if (node_has_id) {
if (bmain != nullptr) {
DEG_relations_tag_update(bmain);
}
}
nodeUnlinkNode(ntree, node);
node_unlink_attached(ntree, node);