diff options
author | Jacques Lucke <jacques@blender.org> | 2021-12-21 17:18:56 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2021-12-21 17:18:56 +0300 |
commit | 7e712b2d6a0d257d272ed35622b41d06274af8df (patch) | |
tree | d33cfb610da7fa43351a282f9c9a9ba25c77d1f8 /source/blender/makesrna/intern | |
parent | 1abf2f3c7c08051502ae0830ab5d4fa8d8d9f13a (diff) |
Nodes: refactor node tree update handling
Goals of this refactor:
* More unified approach to updating everything that needs to be updated
after a change in a node tree.
* The updates should happen in the correct order and quadratic or worse
algorithms should be avoided.
* Improve detection of changes to the output to avoid tagging the depsgraph
when it's not necessary.
* Move towards a more declarative style of defining nodes by having a
more centralized update procedure.
The refactor consists of two main parts:
* Node tree tagging and update refactor.
* Generally, when changes are done to a node tree, it is tagged dirty
until a global update function is called that updates everything in
the correct order.
* The tagging is more fine-grained compared to before, to allow for more
precise depsgraph update tagging.
* Depsgraph changes.
* The shading specific depsgraph node for node trees as been removed.
* Instead, there is a new `NTREE_OUTPUT` depsgrap node, which is only
tagged when the output of the node tree changed (e.g. the Group Output
or Material Output node).
* The copy-on-write relation from node trees to the data block they are
embedded in is now non-flushing. This avoids e.g. triggering a material
update after the shader node tree changed in unrelated ways. Instead
the material has a flushing relation to the new `NTREE_OUTPUT` node now.
* The depsgraph no longer reports data block changes through to cycles
through `Depsgraph.updates` when only the node tree changed in ways
that do not affect the output.
Avoiding unnecessary updates seems to work well for geometry nodes and cycles.
The situation is a bit worse when there are drivers on the node tree, but that
could potentially be improved separately in the future.
Avoiding updates in eevee and the compositor is more tricky, but also less urgent.
* Eevee updates are triggered by calling `DRW_notify_view_update` in
`ED_render_view3d_update` indirectly from `DEG_editors_update`.
* Compositor updates are triggered by `ED_node_composite_job` in `node_area_refresh`.
This is triggered by calling `ED_area_tag_refresh` in `node_area_listener`.
Removing updates always has the risk of breaking some dependency that no
one was aware of. It's not unlikely that this will happen here as well. Adding
back missing updates should be quite a bit easier than getting rid of
unnecessary updates though.
Differential Revision: https://developer.blender.org/D13246
Diffstat (limited to 'source/blender/makesrna/intern')
-rw-r--r-- | source/blender/makesrna/intern/rna_color.c | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_image.c | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_nodetree.c | 143 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_texture.c | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_tracking.c | 6 |
5 files changed, 56 insertions, 99 deletions
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c index 5c12fc3a227..091b457cc83 100644 --- a/source/blender/makesrna/intern/rna_color.c +++ b/source/blender/makesrna/intern/rna_color.c @@ -321,7 +321,7 @@ static void rna_ColorRamp_update(Main *bmain, Scene *UNUSED(scene), PointerRNA * CMP_NODE_VALTORGB, TEX_NODE_VALTORGB, GEO_NODE_LEGACY_ATTRIBUTE_COLOR_RAMP)) { - ED_node_tag_update_nodetree(bmain, ntree, node); + ED_node_tree_propagate_change(NULL, bmain, ntree); } } break; diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c index 2f42e521b52..0d86572357f 100644 --- a/source/blender/makesrna/intern/rna_image.c +++ b/source/blender/makesrna/intern/rna_image.c @@ -168,7 +168,7 @@ static void rna_ImageUser_update(Main *bmain, Scene *scene, PointerRNA *ptr) if (id) { if (GS(id->name) == ID_NT) { /* Special update for nodetrees to find parent datablock. */ - ED_node_tag_update_nodetree(bmain, (bNodeTree *)id, NULL); + ED_node_tree_propagate_change(NULL, bmain, NULL); } else { /* Update material or texture for render preview. */ diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index df0271d81d5..e8f9a0b423b 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -42,6 +42,7 @@ #include "BKE_geometry_set.h" #include "BKE_image.h" #include "BKE_node.h" +#include "BKE_node_tree_update.h" #include "BKE_texture.h" #include "RNA_access.h" @@ -1219,7 +1220,7 @@ static void rna_NodeTree_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *p WM_main_add_notifier(NC_NODE | NA_EDITED, NULL); WM_main_add_notifier(NC_SCENE | ND_NODES, &ntree->id); - ED_node_tag_update_nodetree(bmain, ntree, NULL); + ED_node_tree_propagate_change(NULL, bmain, ntree); } static bNode *rna_NodeTree_node_new(bNodeTree *ntree, @@ -1269,8 +1270,7 @@ static bNode *rna_NodeTree_node_new(bNodeTree *ntree, } Main *bmain = CTX_data_main(C); - ntreeUpdateTree(bmain, ntree); - nodeUpdate(ntree, node); + ED_node_tree_propagate_change(C, bmain, ntree); WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); if (node->type == GEO_NODE_INPUT_SCENE_TIME) { @@ -1300,7 +1300,7 @@ static void rna_NodeTree_node_remove(bNodeTree *ntree, RNA_POINTER_INVALIDATE(node_ptr); - ntreeUpdateTree(bmain, ntree); /* update group node socket links */ + ED_node_tree_propagate_change(NULL, bmain, ntree); WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); } @@ -1320,8 +1320,7 @@ static void rna_NodeTree_node_clear(bNodeTree *ntree, Main *bmain, ReportList *r node = next_node; } - ntreeUpdateTree(bmain, ntree); - + ED_node_tree_propagate_change(NULL, bmain, ntree); WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); } @@ -1400,13 +1399,7 @@ static bNodeLink *rna_NodeTree_link_new(bNodeTree *ntree, fromsock->flag &= ~SOCK_HIDDEN; tosock->flag &= ~SOCK_HIDDEN; - if (tonode) { - nodeUpdate(ntree, tonode); - } - - ntreeUpdateTree(bmain, ntree); - - ED_node_tag_update_nodetree(bmain, ntree, ret->tonode); + ED_node_tree_propagate_change(NULL, bmain, ntree); WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); } return ret; @@ -1431,7 +1424,7 @@ static void rna_NodeTree_link_remove(bNodeTree *ntree, nodeRemLink(ntree, link); RNA_POINTER_INVALIDATE(link_ptr); - ntreeUpdateTree(bmain, ntree); + ED_node_tree_propagate_change(NULL, bmain, ntree); WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); } @@ -1450,8 +1443,7 @@ static void rna_NodeTree_link_clear(bNodeTree *ntree, Main *bmain, ReportList *r link = next_link; } - ntreeUpdateTree(bmain, ntree); - + ED_node_tree_propagate_change(NULL, bmain, ntree); WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); } @@ -1508,7 +1500,7 @@ static bNodeSocket *rna_NodeTree_inputs_new( bNodeSocket *sock = ntreeAddSocketInterface(ntree, SOCK_IN, type, name); - ntreeUpdateTree(bmain, ntree); + ED_node_tree_propagate_change(NULL, bmain, ntree); WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); return sock; @@ -1523,7 +1515,7 @@ static bNodeSocket *rna_NodeTree_outputs_new( bNodeSocket *sock = ntreeAddSocketInterface(ntree, SOCK_OUT, type, name); - ntreeUpdateTree(bmain, ntree); + ED_node_tree_propagate_change(NULL, bmain, ntree); WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); return sock; @@ -1544,8 +1536,7 @@ static void rna_NodeTree_socket_remove(bNodeTree *ntree, else { ntreeRemoveSocketInterface(ntree, sock); - ntreeUpdateTree(bmain, ntree); - DEG_id_tag_update(&ntree->id, 0); + ED_node_tree_propagate_change(NULL, bmain, ntree); WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); } } @@ -1560,7 +1551,7 @@ static void rna_NodeTree_inputs_clear(bNodeTree *ntree, Main *bmain, ReportList ntreeRemoveSocketInterface(ntree, socket); } - ntreeUpdateTree(bmain, ntree); + ED_node_tree_propagate_change(NULL, bmain, ntree); WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); } @@ -1574,7 +1565,7 @@ static void rna_NodeTree_outputs_clear(bNodeTree *ntree, Main *bmain, ReportList ntreeRemoveSocketInterface(ntree, socket); } - ntreeUpdateTree(bmain, ntree); + ED_node_tree_propagate_change(NULL, bmain, ntree); WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); } @@ -1603,9 +1594,9 @@ static void rna_NodeTree_inputs_move(bNodeTree *ntree, Main *bmain, int from_ind } } - ntree->update |= NTREE_UPDATE_GROUP_IN; + BKE_ntree_update_tag_interface(ntree); - ntreeUpdateTree(bmain, ntree); + ED_node_tree_propagate_change(NULL, bmain, ntree); WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); } @@ -1634,9 +1625,9 @@ static void rna_NodeTree_outputs_move(bNodeTree *ntree, Main *bmain, int from_in } } - ntree->update |= NTREE_UPDATE_GROUP_OUT; + BKE_ntree_update_tag_interface(ntree); - ntreeUpdateTree(bmain, ntree); + ED_node_tree_propagate_change(NULL, bmain, ntree); WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); } @@ -1644,10 +1635,8 @@ static void rna_NodeTree_interface_update(bNodeTree *ntree, bContext *C) { Main *bmain = CTX_data_main(C); - ntree->update |= NTREE_UPDATE_GROUP; - ntreeUpdateTree(bmain, ntree); - - ED_node_tag_update_nodetree(bmain, ntree, NULL); + BKE_ntree_update_tag_interface(ntree); + ED_node_tree_propagate_change(NULL, bmain, ntree); } /* ******** NodeLink ******** */ @@ -2617,7 +2606,8 @@ static void rna_Node_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { bNodeTree *ntree = (bNodeTree *)ptr->owner_id; bNode *node = (bNode *)ptr->data; - ED_node_tag_update_nodetree(bmain, ntree, node); + BKE_ntree_update_tag_node_property(ntree, node); + ED_node_tree_propagate_change(NULL, bmain, ntree); } static void rna_Node_update_relations(Main *bmain, Scene *scene, PointerRNA *ptr) @@ -2626,9 +2616,10 @@ static void rna_Node_update_relations(Main *bmain, Scene *scene, PointerRNA *ptr DEG_relations_tag_update(bmain); } -static void rna_Node_socket_value_update(ID *id, bNode *node, bContext *C) +static void rna_Node_socket_value_update(ID *id, bNode *UNUSED(node), bContext *C) { - ED_node_tag_update_nodetree(CTX_data_main(C), (bNodeTree *)id, node); + BKE_ntree_update_tag_all((bNodeTree *)id); + ED_node_tree_propagate_change(C, CTX_data_main(C), (bNodeTree *)id); } static void rna_Node_select_set(PointerRNA *ptr, bool value) @@ -2682,7 +2673,7 @@ static bNodeSocket *rna_Node_inputs_new(ID *id, BKE_report(reports, RPT_ERROR, "Unable to create socket"); } else { - ntreeUpdateTree(bmain, ntree); + ED_node_tree_propagate_change(NULL, bmain, ntree); WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); } @@ -2716,7 +2707,7 @@ static bNodeSocket *rna_Node_outputs_new(ID *id, BKE_report(reports, RPT_ERROR, "Unable to create socket"); } else { - ntreeUpdateTree(bmain, ntree); + ED_node_tree_propagate_change(NULL, bmain, ntree); WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); } @@ -2734,7 +2725,7 @@ static void rna_Node_socket_remove( else { nodeRemoveSocket(ntree, node, sock); - ntreeUpdateTree(bmain, ntree); + ED_node_tree_propagate_change(NULL, bmain, ntree); WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); } } @@ -2749,7 +2740,7 @@ static void rna_Node_inputs_clear(ID *id, bNode *node, Main *bmain) nodeRemoveSocket(ntree, node, sock); } - ntreeUpdateTree(bmain, ntree); + ED_node_tree_propagate_change(NULL, bmain, ntree); WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); } @@ -2763,7 +2754,7 @@ static void rna_Node_outputs_clear(ID *id, bNode *node, Main *bmain) nodeRemoveSocket(ntree, node, sock); } - ntreeUpdateTree(bmain, ntree); + ED_node_tree_propagate_change(NULL, bmain, ntree); WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); } @@ -2795,7 +2786,7 @@ static void rna_Node_inputs_move(ID *id, bNode *node, Main *bmain, int from_inde } } - ntreeUpdateTree(bmain, ntree); + ED_node_tree_propagate_change(NULL, bmain, ntree); WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); } @@ -2827,7 +2818,7 @@ static void rna_Node_outputs_move(ID *id, bNode *node, Main *bmain, int from_ind } } - ntreeUpdateTree(bmain, ntree); + ED_node_tree_propagate_change(NULL, bmain, ntree); WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); } @@ -3055,10 +3046,9 @@ static void rna_NodeSocket_update(Main *bmain, Scene *UNUSED(scene), PointerRNA { bNodeTree *ntree = (bNodeTree *)ptr->owner_id; bNodeSocket *sock = (bNodeSocket *)ptr->data; - bNode *node; - if (nodeFindNode(ntree, sock, &node, NULL)) { - ED_node_tag_update_nodetree(bmain, ntree, node); - } + + BKE_ntree_update_tag_socket_property(ntree, sock); + ED_node_tree_propagate_change(NULL, bmain, ntree); } static bool rna_NodeSocket_is_output_get(PointerRNA *ptr) @@ -3351,10 +3341,8 @@ static void rna_NodeSocketInterface_update(Main *bmain, Scene *UNUSED(scene), Po return; } - ntree->update |= NTREE_UPDATE_GROUP; - ntreeUpdateTree(bmain, ntree); - - ED_node_tag_update_nodetree(bmain, ntree, NULL); + BKE_ntree_update_tag_interface(ntree); + ED_node_tree_propagate_change(NULL, bmain, ntree); } /* ******** Standard Node Socket Base Types ******** */ @@ -3452,28 +3440,14 @@ static void rna_NodeSocketStandard_vector_range( /* using a context update function here, to avoid searching the node if possible */ static void rna_NodeSocketStandard_value_update(struct bContext *C, PointerRNA *ptr) { - bNode *node; - /* default update */ rna_NodeSocket_update(CTX_data_main(C), CTX_data_scene(C), ptr); - - /* try to use node from context, faster */ - node = CTX_data_pointer_get(C, "node").data; - if (!node) { - bNodeTree *ntree = (bNodeTree *)ptr->owner_id; - bNodeSocket *sock = ptr->data; - - /* fall back to searching node in the tree */ - nodeFindNode(ntree, sock, &node, NULL); - } } static void rna_NodeSocketStandard_value_and_relation_update(struct bContext *C, PointerRNA *ptr) { rna_NodeSocketStandard_value_update(C, ptr); - bNodeTree *ntree = (bNodeTree *)ptr->owner_id; Main *bmain = CTX_data_main(C); - ntreeUpdateTree(bmain, ntree); DEG_relations_tag_update(bmain); } @@ -3567,12 +3541,11 @@ static bool rna_NodeInternal_poll_instance(bNode *node, bNodeTree *ntree) } } -static void rna_NodeInternal_update(ID *id, bNode *node) +static void rna_NodeInternal_update(ID *id, bNode *node, Main *bmain) { bNodeTree *ntree = (bNodeTree *)id; - if (node->typeinfo->updatefunc) { - node->typeinfo->updatefunc(ntree, node); - } + BKE_ntree_update_tag_node_property(ntree, node); + ED_node_tree_propagate_change(NULL, bmain, ntree); } static void rna_NodeInternal_draw_buttons(ID *id, @@ -3721,7 +3694,8 @@ static void rna_Node_tex_image_update(Main *bmain, Scene *UNUSED(scene), Pointer bNodeTree *ntree = (bNodeTree *)ptr->owner_id; bNode *node = (bNode *)ptr->data; - ED_node_tag_update_nodetree(bmain, ntree, node); + BKE_ntree_update_tag_node_property(ntree, node); + ED_node_tree_propagate_change(NULL, bmain, ntree); WM_main_add_notifier(NC_IMAGE, NULL); } @@ -3730,11 +3704,8 @@ static void rna_NodeGroup_update(Main *bmain, Scene *UNUSED(scene), PointerRNA * bNodeTree *ntree = (bNodeTree *)ptr->owner_id; bNode *node = (bNode *)ptr->data; - if (node->id) { - ntreeUpdateTree(bmain, (bNodeTree *)node->id); - } - - ED_node_tag_update_nodetree(bmain, ntree, node); + BKE_ntree_update_tag_node_property(ntree, node); + ED_node_tree_propagate_change(NULL, bmain, ntree); DEG_relations_tag_update(bmain); } @@ -4142,13 +4113,12 @@ static const EnumPropertyItem *rna_Node_channel_itemf(bContext *UNUSED(C), return item; } -static void rna_Image_Node_update_id(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +static void rna_Image_Node_update_id(Main *bmain, Scene *scene, PointerRNA *ptr) { - bNodeTree *ntree = (bNodeTree *)ptr->owner_id; bNode *node = (bNode *)ptr->data; node->update |= NODE_UPDATE_ID; - nodeUpdate(ntree, node); /* to update image node sockets */ + rna_Node_update(bmain, scene, ptr); } static void rna_NodeOutputFile_slots_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) @@ -4395,7 +4365,7 @@ static bNodeSocket *rna_NodeOutputFile_slots_new( sock = ntreeCompositOutputFileAddSocket(ntree, node, name, im_format); - ntreeUpdateTree(CTX_data_main(C), ntree); + ED_node_tree_propagate_change(C, CTX_data_main(C), ntree); WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); return sock; @@ -4504,42 +4474,27 @@ static void rna_ShaderNodeScript_update(Main *bmain, Scene *scene, PointerRNA *p RE_engine_free(engine); } - ED_node_tag_update_nodetree(bmain, ntree, node); + BKE_ntree_update_tag_node_property(ntree, node); + ED_node_tree_propagate_change(NULL, bmain, ntree); } static void rna_ShaderNode_socket_update(Main *bmain, Scene *scene, PointerRNA *ptr) { - bNodeTree *ntree = (bNodeTree *)ptr->owner_id; - bNode *node = (bNode *)ptr->data; - - nodeUpdate(ntree, node); rna_Node_update(bmain, scene, ptr); } static void rna_Node_socket_update(Main *bmain, Scene *scene, PointerRNA *ptr) { - bNodeTree *ntree = (bNodeTree *)ptr->owner_id; - bNode *node = (bNode *)ptr->data; - - nodeUpdate(ntree, node); rna_Node_update(bmain, scene, ptr); } static void rna_GeometryNode_socket_update(Main *bmain, Scene *scene, PointerRNA *ptr) { - bNodeTree *ntree = (bNodeTree *)ptr->owner_id; - bNode *node = (bNode *)ptr->data; - - nodeUpdate(ntree, node); rna_Node_update(bmain, scene, ptr); } static void rna_CompositorNodeScale_update(Main *bmain, Scene *scene, PointerRNA *ptr) { - bNodeTree *ntree = (bNodeTree *)ptr->owner_id; - bNode *node = (bNode *)ptr->data; - - nodeUpdate(ntree, node); rna_Node_update(bmain, scene, ptr); } @@ -12386,7 +12341,7 @@ static void rna_def_internal_node(BlenderRNA *brna) func = RNA_def_function(srna, "update", "rna_NodeInternal_update"); RNA_def_function_ui_description( func, "Update on node graph topology changes (adding or removing nodes and links)"); - RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_ALLOW_WRITE); + RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_ALLOW_WRITE); /* draw buttons */ func = RNA_def_function(srna, "draw_buttons", "rna_NodeInternal_draw_buttons"); diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index 5a74cfa9964..f66fb2653b5 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -199,7 +199,7 @@ static void rna_Texture_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *pt } else if (GS(id->name) == ID_NT) { bNodeTree *ntree = (bNodeTree *)ptr->owner_id; - ED_node_tag_update_nodetree(bmain, ntree, NULL); + ED_node_tree_propagate_change(NULL, bmain, ntree); } } diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index c81588aa8b5..03f4acdae79 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -24,6 +24,7 @@ #include "MEM_guardedalloc.h" #include "BKE_movieclip.h" +#include "BKE_node_tree_update.h" #include "BKE_tracking.h" #include "RNA_access.h" @@ -415,11 +416,12 @@ static void rna_tracking_stabRotTracks_active_index_range( *max = max_ii(0, clip->tracking.stabilization.tot_rot_track - 1); } -static void rna_tracking_flushUpdate(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr) +static void rna_tracking_flushUpdate(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { MovieClip *clip = (MovieClip *)ptr->owner_id; - nodeUpdateID(scene->nodetree, &clip->id); + BKE_ntree_update_tag_id_changed(bmain, &clip->id); + BKE_ntree_update_main(bmain, NULL); WM_main_add_notifier(NC_SCENE | ND_NODES, NULL); WM_main_add_notifier(NC_SCENE, NULL); |