Commit: bb0fc675822f313c5546a2498a162472c2571ecb Author: Jacques Lucke Date: Mon May 30 12:54:07 2022 +0200 Branches: master https://developer.blender.org/rBbb0fc675822f313c5546a2498a162472c2571ecb
Nodes: add separately allocated run-time data for bNodeTree `bNodeTree` has a lot of run-time embedded in it currently. Having a separately allocated run-time struct has some benefits: * Run-time data is not stored in files. * Makes it easy to use c++ types as run-time data. * More clear distinction between what data only exists at run-time and which doesn't. This commit doesn't move all run-time data to the new struct yet, only the data where I know for sure how it is used. The remaining data can be moved separately. Differential Revision: https://developer.blender.org/D15033 =================================================================== A source/blender/blenkernel/BKE_node_runtime.hh M source/blender/blenkernel/CMakeLists.txt M source/blender/blenkernel/intern/node.cc M source/blender/blenkernel/intern/node_tree_update.cc M source/blender/depsgraph/intern/builder/deg_builder_nodes.cc M source/blender/depsgraph/intern/builder/deg_builder_relations.cc M source/blender/makesdna/DNA_node_types.h M source/blender/modifiers/intern/MOD_nodes.cc =================================================================== diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh new file mode 100644 index 00000000000..c9c4577a2d4 --- /dev/null +++ b/source/blender/blenkernel/BKE_node_runtime.hh @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +#include <memory> + +#include "BLI_sys_types.h" +#include "BLI_utility_mixins.hh" + +namespace blender::nodes { +struct FieldInferencingInterface; +} + +namespace blender::bke { + +class bNodeTreeRuntime : NonCopyable, NonMovable { + public: + /** + * Keeps track of what changed in the node tree until the next update. + * Should not be changed directly, instead use the functions in `BKE_node_tree_update.h`. + * #eNodeTreeChangedFlag. + */ + uint32_t changed_flag = 0; + /** + * A hash of the topology of the node tree leading up to the outputs. This is used to determine + * of the node tree changed in a way that requires updating geometry nodes or shaders. + */ + uint32_t output_topology_hash = 0; + + /** + * Used to cache run-time information of the node tree. + * #eNodeTreeRuntimeFlag. + */ + uint8_t runtime_flag = 0; + + /** Information about how inputs and outputs of the node group interact with fields. */ + std::unique_ptr<nodes::FieldInferencingInterface> field_inferencing_interface; +}; + +} // namespace blender::bke diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 0b4f81df452..4edec268fe8 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -431,6 +431,7 @@ set(SRC BKE_multires.h BKE_nla.h BKE_node.h + BKE_node_runtime.hh BKE_node_tree_update.h BKE_object.h BKE_object_deform.h diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 4d96ba58d28..95a514ef474 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -60,6 +60,7 @@ #include "BKE_lib_query.h" #include "BKE_main.h" #include "BKE_node.h" +#include "BKE_node_runtime.hh" #include "BKE_node_tree_update.h" #include "RNA_access.h" @@ -94,6 +95,7 @@ using blender::Stack; using blender::StringRef; using blender::Vector; using blender::VectorSet; +using blender::bke::bNodeTreeRuntime; using blender::nodes::FieldInferencingInterface; using blender::nodes::InputSocketFieldType; using blender::nodes::NodeDeclaration; @@ -123,6 +125,7 @@ static void nodeMuteRerouteOutputLinks(struct bNodeTree *ntree, static void ntree_init_data(ID *id) { bNodeTree *ntree = (bNodeTree *)id; + ntree->runtime = MEM_new<bNodeTreeRuntime>(__func__); ntree_set_typeinfo(ntree, nullptr); } @@ -134,6 +137,8 @@ static void ntree_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, c /* We never handle usercount here for own data. */ const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT; + ntree_dst->runtime = MEM_new<bNodeTreeRuntime>(__func__); + /* in case a running nodetree is copied */ ntree_dst->execdata = nullptr; @@ -203,9 +208,9 @@ static void ntree_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, c /* node tree will generate its own interface type */ ntree_dst->interface_type = nullptr; - if (ntree_src->field_inferencing_interface) { - ntree_dst->field_inferencing_interface = new FieldInferencingInterface( - *ntree_src->field_inferencing_interface); + if (ntree_src->runtime->field_inferencing_interface) { + ntree_dst->runtime->field_inferencing_interface = std::make_unique<FieldInferencingInterface>( + *ntree_src->runtime->field_inferencing_interface); } if (flag & LIB_ID_COPY_NO_PREVIEW) { @@ -258,8 +263,6 @@ static void ntree_free_data(ID *id) MEM_freeN(sock); } - delete ntree->field_inferencing_interface; - /* free preview hash */ if (ntree->previews) { BKE_node_instance_hash_free(ntree->previews, (bNodeInstanceValueFP)BKE_node_preview_free); @@ -270,6 +273,7 @@ static void ntree_free_data(ID *id) } BKE_previewimg_free(&ntree->preview); + MEM_delete(ntree->runtime); } static void library_foreach_node_socket(LibraryForeachIDData *data, bNodeSocket *sock) @@ -670,9 +674,7 @@ void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree) ntree->progress = nullptr; ntree->execdata = nullptr; - ntree->runtime_flag = 0; - - ntree->field_inferencing_interface = nullptr; + ntree->runtime = MEM_new<bNodeTreeRuntime>(__func__); BKE_ntree_update_tag_missing_runtime_data(ntree); BLO_read_data_address(reader, &ntree->adt); diff --git a/source/blender/blenkernel/intern/node_tree_update.cc b/source/blender/blenkernel/intern/node_tree_update.cc index 68e4cccba00..d4b7f695ee1 100644 --- a/source/blender/blenkernel/intern/node_tree_update.cc +++ b/source/blender/blenkernel/intern/node_tree_update.cc @@ -15,6 +15,7 @@ #include "BKE_image.h" #include "BKE_main.h" #include "BKE_node.h" +#include "BKE_node_runtime.hh" #include "BKE_node_tree_update.h" #include "MOD_nodes.h" @@ -48,7 +49,7 @@ enum eNodeTreeChangedFlag { static void add_tree_tag(bNodeTree *ntree, const eNodeTreeChangedFlag flag) { - ntree->changed_flag |= flag; + ntree->runtime->changed_flag |= flag; } static void add_node_tag(bNodeTree *ntree, bNode *node, const eNodeTreeChangedFlag flag) @@ -172,11 +173,11 @@ static FieldInferencingInterface get_node_field_inferencing_interface(const Node /* This can happen when there is a linked node group that was not found (see T92799). */ return get_dummy_field_inferencing_interface(node); } - if (group->field_inferencing_interface == nullptr) { + if (!group->runtime->field_inferencing_interface) { /* This shouldn't happen because referenced node groups should always be updated first. */ BLI_assert_unreachable(); } - return *group->field_inferencing_interface; + return *group->runtime->field_inferencing_interface; } FieldInferencingInterface inferencing_interface; @@ -551,7 +552,8 @@ static bool update_field_inferencing(const NodeTreeRef &tree) bNodeTree &btree = *tree.btree(); /* Create new inferencing interface for this node group. */ - FieldInferencingInterface *new_inferencing_interface = new FieldInferencingInterface(); + std::unique_ptr<FieldInferencingInterface> new_inferencing_interface = + std::make_unique<FieldInferencingInterface>(); new_inferencing_interface->inputs.resize(BLI_listbase_count(&btree.inputs), InputSocketFieldType::IsSupported); new_inferencing_interface->outputs.resize(BLI_listbase_count(&btree.outputs), @@ -567,11 +569,10 @@ static bool update_field_inferencing(const NodeTreeRef &tree) update_socket_shapes(tree, field_state_by_socket_id); /* Update the previous group interface. */ - const bool group_interface_changed = btree.field_inferencing_interface == nullptr || - *btree.field_inferencing_interface != + const bool group_interface_changed = !btree.runtime->field_inferencing_interface || + *btree.runtime->field_inferencing_interface != *new_inferencing_interface; - delete btree.field_inferencing_interface; - btree.field_inferencing_interface = new_inferencing_interface; + btree.runtime->field_inferencing_interface = std::move(new_inferencing_interface); return group_interface_changed; } @@ -799,7 +800,7 @@ class NodeTreeMainUpdater { { Vector<bNodeTree *> changed_ntrees; FOREACH_NODETREE_BEGIN (bmain_, ntree, id) { - if (ntree->changed_flag != NTREE_CHANGED_NOTHING) { + if (ntree->runtime->changed_flag != NTREE_CHANGED_NOTHING) { changed_ntrees.append(ntree); } } @@ -817,7 +818,7 @@ class NodeTreeMainUpdater { if (root_ntrees.size() == 1) { bNodeTree *ntree = root_ntrees[0]; - if (ntree->changed_flag == NTREE_CHANGED_NOTHING) { + if (ntree->runtime->changed_flag == NTREE_CHANGED_NOTHING) { return; } const TreeUpdateResult result = this->update_tree(*ntree); @@ -830,7 +831,7 @@ class NodeTreeMainUpdater { if (!is_single_tree_update) { Vector<bNodeTree *> ntrees_in_order = this->get_tree_update_order(root_ntrees); for (bNodeTree *ntree : ntrees_in_order) { - if (ntree->changed_flag == NTREE_CHANGED_NOTHING) { + if (ntree->runtime->changed_flag == NTREE_CHANGED_NOTHING) { continue; } if (!update_result_by_tree_.contains(ntree)) { @@ -1002,7 +1003,8 @@ class NodeTreeMainUpdater { ntreeTexCheckCyclics(&ntree); } - if (ntree.changed_flag & NTREE_CHANGED_INTERFACE || ntree.changed_flag & NTREE_CHANGED_ANY) { + if (ntree.runtime->changed_flag & NTREE_CHANGED_INTERFACE || + ntree.runtime->changed_flag & NTREE_CHANGED_ANY) { result.interface_changed = true; } @@ -1057,18 +1059,18 @@ class NodeTreeMainUpdater { this->ensure_tree_ref(ntree, tree_ref); const NodeRef &node = *tree_ref->find_node(*bnode); if (this->should_update_individual_node(node)) { - const uint32_t old_changed_flag = ntree.changed_flag; - ntree.changed_flag = NTREE_CHANGED_NOTHING; + const uint32_t old_changed_flag = ntree.runtime->changed_flag; + ntree.runtime->changed_flag = NTREE_CHANGED_NOTHING; - /* This may set #ntree.changed_flag which is detected below. */ + /* This may set #ntree.runtime->changed_flag which is detected below. */ this->update_individual_node(node); - if (ntree.changed_flag != NTREE_CHANGED_NOTHING) { + if (ntree.runtime->changed_flag != NTREE_CHANGED_NOTHING) { /* The tree ref is outdated and needs to be rebuilt. Generally, only very few update * functions change the node. Typically zero or one nodes change after an update. */ tree_ref.reset(); } - ntree.changed_flag |= old_changed_flag; + ntree.runtime->changed_flag |= old_changed_flag; } } } @@ -1077,13 +1079,13 @@ class NodeTre @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list [email protected] List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
