From 2f1d60a481e2099b5c92f4e23a9ab22f94ed07cf Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Thu, 8 Sep 2022 10:35:43 +0200 Subject: improve compute context docs --- source/blender/blenkernel/BKE_compute_contexts.hh | 41 +++++ source/blender/blenkernel/BKE_context_stack.hh | 40 ----- source/blender/blenkernel/CMakeLists.txt | 4 +- .../blender/blenkernel/intern/compute_contexts.cc | 38 +++++ source/blender/blenkernel/intern/context_stack.cc | 40 ----- source/blender/blenlib/BLI_compute_context.hh | 173 +++++++++++++++++++++ source/blender/blenlib/BLI_context_stack.hh | 119 -------------- source/blender/blenlib/CMakeLists.txt | 4 +- source/blender/blenlib/intern/compute_context.cc | 48 ++++++ source/blender/blenlib/intern/context_stack.cc | 48 ------ source/blender/editors/space_node/node_draw.cc | 11 +- .../spreadsheet_data_source_geometry.cc | 10 +- source/blender/modifiers/intern/MOD_nodes.cc | 34 ++-- source/blender/nodes/NOD_geometry_exec.hh | 6 +- source/blender/nodes/NOD_geometry_nodes_log.hh | 14 +- .../NOD_geometry_nodes_to_lazy_function_graph.hh | 6 +- source/blender/nodes/intern/geometry_nodes_log.cc | 43 ++--- .../geometry_nodes_to_lazy_function_graph.cc | 15 +- 18 files changed, 373 insertions(+), 321 deletions(-) create mode 100644 source/blender/blenkernel/BKE_compute_contexts.hh delete mode 100644 source/blender/blenkernel/BKE_context_stack.hh create mode 100644 source/blender/blenkernel/intern/compute_contexts.cc delete mode 100644 source/blender/blenkernel/intern/context_stack.cc create mode 100644 source/blender/blenlib/BLI_compute_context.hh delete mode 100644 source/blender/blenlib/BLI_context_stack.hh create mode 100644 source/blender/blenlib/intern/compute_context.cc delete mode 100644 source/blender/blenlib/intern/context_stack.cc (limited to 'source') diff --git a/source/blender/blenkernel/BKE_compute_contexts.hh b/source/blender/blenkernel/BKE_compute_contexts.hh new file mode 100644 index 00000000000..bb01aee788e --- /dev/null +++ b/source/blender/blenkernel/BKE_compute_contexts.hh @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +/** + * This file implements some specific compute contexts for concepts in Blender. + */ + +#include "BLI_compute_context.hh" + +namespace blender::bke { + +class ModifierComputeContext : public ComputeContext { + private: + static constexpr const char *s_static_type = "MODIFIER"; + + std::string modifier_name_; + + public: + ModifierComputeContext(const ComputeContext *parent, std::string modifier_name); + + private: + void print_current_in_line(std::ostream &stream) const override; +}; + +class NodeGroupComputeContext : public ComputeContext { + private: + static constexpr const char *s_static_type = "NODE_GROUP"; + + std::string node_name_; + + public: + NodeGroupComputeContext(const ComputeContext *parent, std::string node_name); + + StringRefNull node_name() const; + + private: + void print_current_in_line(std::ostream &stream) const override; +}; + +} // namespace blender::bke diff --git a/source/blender/blenkernel/BKE_context_stack.hh b/source/blender/blenkernel/BKE_context_stack.hh deleted file mode 100644 index 1415a5e21b7..00000000000 --- a/source/blender/blenkernel/BKE_context_stack.hh +++ /dev/null @@ -1,40 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BLI_context_stack.hh" - -namespace blender::bke { - -class ModifierContextStack : public ContextStack { - private: - static constexpr const char *s_static_type = "MODIFIER"; - - std::string modifier_name_; - - public: - ModifierContextStack(const ContextStack *parent, std::string modifier_name); - - private: - void print_current_in_line(std::ostream &stream) const override; -}; - -class NodeGroupContextStack : public ContextStack { - private: - static constexpr const char *s_static_type = "NODE_GROUP"; - - std::string node_name_; - std::string debug_group_name_; - - public: - NodeGroupContextStack(const ContextStack *parent, - std::string node_name, - std::string debug_group_name = ""); - - StringRefNull node_name() const; - - private: - void print_current_in_line(std::ostream &stream) const override; -}; - -} // namespace blender::bke diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 228902f5d02..f8fb609f1c3 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -98,9 +98,9 @@ set(SRC intern/collision.c intern/colorband.c intern/colortools.c + intern/compute_contexts.cc intern/constraint.c intern/context.c - intern/context_stack.cc intern/crazyspace.cc intern/cryptomatte.cc intern/curve.cc @@ -353,9 +353,9 @@ set(SRC BKE_collision.h BKE_colorband.h BKE_colortools.h + BKE_compute_contexts.hh BKE_constraint.h BKE_context.h - BKE_context_stack.hh BKE_crazyspace.h BKE_crazyspace.hh BKE_cryptomatte.h diff --git a/source/blender/blenkernel/intern/compute_contexts.cc b/source/blender/blenkernel/intern/compute_contexts.cc new file mode 100644 index 00000000000..026706d363e --- /dev/null +++ b/source/blender/blenkernel/intern/compute_contexts.cc @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "BKE_compute_contexts.hh" + +namespace blender::bke { + +ModifierComputeContext::ModifierComputeContext(const ComputeContext *parent, + std::string modifier_name) + : ComputeContext(s_static_type, parent), modifier_name_(std::move(modifier_name)) +{ + hash_.mix_in(s_static_type, strlen(s_static_type)); + hash_.mix_in(modifier_name_.data(), modifier_name_.size()); +} + +void ModifierComputeContext::print_current_in_line(std::ostream &stream) const +{ + stream << "Modifier: " << modifier_name_; +} + +NodeGroupComputeContext::NodeGroupComputeContext(const ComputeContext *parent, + std::string node_name) + : ComputeContext(s_static_type, parent), node_name_(std::move(node_name)) +{ + hash_.mix_in(s_static_type, strlen(s_static_type)); + hash_.mix_in(node_name_.data(), node_name_.size()); +} + +StringRefNull NodeGroupComputeContext::node_name() const +{ + return node_name_; +} + +void NodeGroupComputeContext::print_current_in_line(std::ostream &stream) const +{ + stream << "Node: " << node_name_; +} + +} // namespace blender::bke diff --git a/source/blender/blenkernel/intern/context_stack.cc b/source/blender/blenkernel/intern/context_stack.cc deleted file mode 100644 index 3e45bebb52a..00000000000 --- a/source/blender/blenkernel/intern/context_stack.cc +++ /dev/null @@ -1,40 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "BKE_context_stack.hh" - -namespace blender::bke { - -ModifierContextStack::ModifierContextStack(const ContextStack *parent, std::string modifier_name) - : ContextStack(s_static_type, parent), modifier_name_(std::move(modifier_name)) -{ - hash_.mix_in(s_static_type, strlen(s_static_type)); - hash_.mix_in(modifier_name_.data(), modifier_name_.size()); -} - -void ModifierContextStack::print_current_in_line(std::ostream &stream) const -{ - stream << "Modifier: " << modifier_name_; -} - -NodeGroupContextStack::NodeGroupContextStack(const ContextStack *parent, - std::string node_name, - std::string debug_group_name) - : ContextStack(s_static_type, parent), - node_name_(std::move(node_name)), - debug_group_name_(std::move(debug_group_name)) -{ - hash_.mix_in(s_static_type, strlen(s_static_type)); - hash_.mix_in(node_name_.data(), node_name_.size()); -} - -StringRefNull NodeGroupContextStack::node_name() const -{ - return node_name_; -} - -void NodeGroupContextStack::print_current_in_line(std::ostream &stream) const -{ - stream << "Node Group: " << debug_group_name_ << " \t Node Name: " << node_name_; -} - -} // namespace blender::bke diff --git a/source/blender/blenlib/BLI_compute_context.hh b/source/blender/blenlib/BLI_compute_context.hh new file mode 100644 index 00000000000..fc6858ad6a9 --- /dev/null +++ b/source/blender/blenlib/BLI_compute_context.hh @@ -0,0 +1,173 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +/** \file + * \ingroup bli + * + * When logging computed values, we generally want to know where the value was computed. For + * example, geometry nodes logs socket values so that they can be displayed in the ui. For that we + * can combine the logged value with a `ComputeContext`, which identifies the place where the value + * was computed. + * + * This is not a trivial problem because e.g. just storing storing a pointer to the socket a value + * belongs to is not enough. That's because the same socket may correspond to many different values + * when the socket is used in a node group that is used multiple times. In this case, not only does + * the socket has to be stored but also the entire nested node group path that led to the + * evaluation of the socket. + * + * Storing the entire "context path" for every logged value is not feasible, because that path can + * become quite long. So that would need much more memory, more compute overhead and makes it + * complicated to compare if two contexts are the same. If the identifier for a compute context + * would have a variable size, it would also be much harder to create a map from context to values. + * + * The solution implemented below uses the following key ideas: + * - Every compute context can be hashed to a unique fixed size value (`ComputeContextHash`). While + * technically there could be hash collisions, the hashing algorithm has to be chosen to make + * that practically impossible. This way an entire context path, possibly consisting of many + * nested contexts, is represented by a single value that can be stored easily. + * - A nested compute context is build as singly linked list, where every compute context has a + * pointer to the parent compute context. Note that a link in the other direction is not possible + * because the same parent compute context may be used by many different children which possibly + * run on different threads. + */ + +#include "BLI_array.hh" +#include "BLI_linear_allocator.hh" +#include "BLI_stack.hh" +#include "BLI_string_ref.hh" + +namespace blender { + +/** + * A hash that uniquely identifies a specific (non-fixed-size) compute context. The hash has to + * have enough bits to make collisions practically impossible. + */ +struct ComputeContextHash { + static constexpr int64_t HashSizeInBytes = 16; + uint64_t v1 = 0; + uint64_t v2 = 0; + + uint64_t hash() const + { + return v1; + } + + friend bool operator==(const ComputeContextHash &a, const ComputeContextHash &b) + { + return a.v1 == b.v1 && a.v2 == b.v2; + } + + void mix_in(const void *data, int64_t len); + + friend std::ostream &operator<<(std::ostream &stream, const ComputeContextHash &hash); +}; + +static_assert(sizeof(ComputeContextHash) == ComputeContextHash::HashSizeInBytes); + +/** + * Identifies the context in which a computation happens. This context can be used to identify + * values logged during the computation. For more details, see the comment at the top of the file. + * + * This class should be subclassed to implement specific contexts. + */ +class ComputeContext { + private: + /** + * Only used for debugging currently. + */ + const char *static_type_; + /** + * Pointer to the context that this context is child of. That allows nesting compute contexts. + */ + const ComputeContext *parent_ = nullptr; + + protected: + /** + * The hash that uniquely identifies this context. It's a combined hash of this context as well + * as all the parent contexts. + */ + ComputeContextHash hash_; + + public: + ComputeContext(const char *static_type, const ComputeContext *parent) + : static_type_(static_type), parent_(parent) + { + if (parent != nullptr) { + hash_ = parent_->hash_; + } + } + virtual ~ComputeContext() = default; + + const ComputeContextHash &hash() const + { + return hash_; + } + + const char *static_type() const + { + return static_type_; + } + + const ComputeContext *parent() const + { + return parent_; + } + + /** + * Print the entire nested context stack. + */ + void print_stack(std::ostream &stream, StringRef name) const; + + /** + * Print information about this specific context. This has to be implemented by each subclass. + */ + virtual void print_current_in_line(std::ostream &stream) const = 0; + + friend std::ostream &operator<<(std::ostream &stream, const ComputeContext &compute_context); +}; + +/** + * Utility class to build a context stack in one place. This is typically used to get the hash that + * corresponds to a specific nested compute context, in order to look up corresponding logged + * values. + */ +class ComputeContextBuilder { + private: + LinearAllocator<> allocator_; + Stack> contexts_; + + public: + bool is_empty() const + { + return contexts_.is_empty(); + } + + const ComputeContext *current() const + { + if (contexts_.is_empty()) { + return nullptr; + } + return contexts_.peek().get(); + } + + const ComputeContextHash hash() const + { + BLI_assert(!contexts_.is_empty()); + return this->current()->hash(); + } + + template void push(Args &&...args) + { + const ComputeContext *current = this->current(); + destruct_ptr context = allocator_.construct(current, std::forward(args)...); + contexts_.push(std::move(context)); + } + + void pop() + { + contexts_.pop(); + } +}; + +} // namespace blender diff --git a/source/blender/blenlib/BLI_context_stack.hh b/source/blender/blenlib/BLI_context_stack.hh deleted file mode 100644 index d399c13fd5c..00000000000 --- a/source/blender/blenlib/BLI_context_stack.hh +++ /dev/null @@ -1,119 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -/** \file - * \ingroup bli - */ - -#include "BLI_array.hh" -#include "BLI_linear_allocator.hh" -#include "BLI_stack.hh" -#include "BLI_string_ref.hh" - -namespace blender { - -/** - * A hash that unique identifies a specific context stack. The hash has to have enough bits to make - * collisions practically impossible. - */ -struct ContextStackHash { - static constexpr int64_t HashSizeInBytes = 16; - uint64_t v1 = 0; - uint64_t v2 = 0; - - uint64_t hash() const - { - return v1; - } - - friend bool operator==(const ContextStackHash &a, const ContextStackHash &b) - { - return a.v1 == b.v1 && a.v2 == b.v2; - } - - void mix_in(const void *data, int64_t len); - - friend std::ostream &operator<<(std::ostream &stream, const ContextStackHash &hash); -}; - -static_assert(sizeof(ContextStackHash) == ContextStackHash::HashSizeInBytes); - -class ContextStack { - private: - const char *static_type_; - const ContextStack *parent_ = nullptr; - - protected: - ContextStackHash hash_; - - public: - ContextStack(const char *static_type, const ContextStack *parent) - : static_type_(static_type), parent_(parent) - { - if (parent != nullptr) { - hash_ = parent_->hash_; - } - } - virtual ~ContextStack() = default; - - const ContextStackHash &hash() const - { - return hash_; - } - - const char *static_type() const - { - return static_type_; - } - - const ContextStack *parent() const - { - return parent_; - } - - void print_stack(std::ostream &stream, StringRef name) const; - virtual void print_current_in_line(std::ostream &stream) const = 0; - - friend std::ostream &operator<<(std::ostream &stream, const ContextStack &context_stack); -}; - -class ContextStackBuilder { - private: - LinearAllocator<> allocator_; - Stack> contexts_; - - public: - bool is_empty() const - { - return contexts_.is_empty(); - } - - const ContextStack *current() const - { - if (contexts_.is_empty()) { - return nullptr; - } - return contexts_.peek().get(); - } - - const ContextStackHash hash() const - { - BLI_assert(!contexts_.is_empty()); - return this->current()->hash(); - } - - template void push(Args &&...args) - { - const ContextStack *current = this->current(); - destruct_ptr context = allocator_.construct(current, std::forward(args)...); - contexts_.push(std::move(context)); - } - - void pop() - { - contexts_.pop(); - } -}; - -} // namespace blender diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index b52350c256f..4cd222165be 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -53,7 +53,7 @@ set(SRC intern/bitmap_draw_2d.c intern/boxpack_2d.c intern/buffer.c - intern/context_stack.cc + intern/compute_context.cc intern/convexhull_2d.c intern/cpp_type.cc intern/delaunay_2d.cc @@ -181,8 +181,8 @@ set(SRC BLI_compiler_attrs.h BLI_compiler_compat.h BLI_compiler_typecheck.h + BLI_compute_context.hh BLI_console.h - BLI_context_stack.hh BLI_convexhull_2d.h BLI_cpp_type.hh BLI_cpp_type_make.hh diff --git a/source/blender/blenlib/intern/compute_context.cc b/source/blender/blenlib/intern/compute_context.cc new file mode 100644 index 00000000000..50a4a90a4a9 --- /dev/null +++ b/source/blender/blenlib/intern/compute_context.cc @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "BLI_compute_context.hh" +#include "BLI_hash_md5.h" + +namespace blender { + +void ComputeContextHash::mix_in(const void *data, int64_t len) +{ + DynamicStackBuffer<> buffer_owner(HashSizeInBytes + len, 8); + char *buffer = static_cast(buffer_owner.buffer()); + memcpy(buffer, this, HashSizeInBytes); + memcpy(buffer + HashSizeInBytes, data, len); + + BLI_hash_md5_buffer(buffer, HashSizeInBytes + len, this); +} + +std::ostream &operator<<(std::ostream &stream, const ComputeContextHash &hash) +{ + std::stringstream ss; + ss << "0x" << std::hex << hash.v1 << hash.v2; + stream << ss.str(); + return stream; +} + +void ComputeContext::print_stack(std::ostream &stream, StringRef name) const +{ + Stack stack; + for (const ComputeContext *current = this; current; current = current->parent_) { + stack.push(current); + } + stream << "Context Stack: " << name << "\n"; + while (!stack.is_empty()) { + const ComputeContext *current = stack.pop(); + stream << "-> "; + current->print_current_in_line(stream); + const ComputeContextHash ¤t_hash = current->hash_; + stream << " \t(hash: " << current_hash << ")\n"; + } +} + +std::ostream &operator<<(std::ostream &stream, const ComputeContext &compute_context) +{ + compute_context.print_stack(stream, ""); + return stream; +} + +} // namespace blender diff --git a/source/blender/blenlib/intern/context_stack.cc b/source/blender/blenlib/intern/context_stack.cc deleted file mode 100644 index ea6736e7c3e..00000000000 --- a/source/blender/blenlib/intern/context_stack.cc +++ /dev/null @@ -1,48 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "BLI_context_stack.hh" -#include "BLI_hash_md5.h" - -namespace blender { - -void ContextStackHash::mix_in(const void *data, int64_t len) -{ - DynamicStackBuffer<> buffer_owner(HashSizeInBytes + len, 8); - char *buffer = static_cast(buffer_owner.buffer()); - memcpy(buffer, this, HashSizeInBytes); - memcpy(buffer + HashSizeInBytes, data, len); - - BLI_hash_md5_buffer(buffer, HashSizeInBytes + len, this); -} - -std::ostream &operator<<(std::ostream &stream, const ContextStackHash &hash) -{ - std::stringstream ss; - ss << "0x" << std::hex << hash.v1 << hash.v2; - stream << ss.str(); - return stream; -} - -void ContextStack::print_stack(std::ostream &stream, StringRef name) const -{ - Stack stack; - for (const ContextStack *current = this; current; current = current->parent_) { - stack.push(current); - } - stream << "Context Stack: " << name << "\n"; - while (!stack.is_empty()) { - const ContextStack *current = stack.pop(); - stream << "-> "; - current->print_current_in_line(stream); - const ContextStackHash ¤t_hash = current->hash_; - stream << " \t(hash: " << current_hash << ")\n"; - } -} - -std::ostream &operator<<(std::ostream &stream, const ContextStack &context_stack) -{ - context_stack.print_stack(stream, ""); - return stream; -} - -} // namespace blender diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index 58738449d4b..a8fa27c0313 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -30,8 +30,8 @@ #include "BLT_translation.h" +#include "BKE_compute_contexts.hh" #include "BKE_context.h" -#include "BKE_context_stack.hh" #include "BKE_idtype.h" #include "BKE_lib_id.h" #include "BKE_main.h" @@ -332,7 +332,7 @@ static nodes::geo_eval_log::GeoTreeLog *get_geo_tree_log(SpaceNode &snode) using namespace blender::nodes; using namespace blender::nodes::geo_eval_log; - ContextStackBuilder context_stack_builder; + ComputeContextBuilder compute_context_builder; if (snode.id == nullptr) { return nullptr; @@ -358,17 +358,16 @@ static nodes::geo_eval_log::GeoTreeLog *get_geo_tree_log(SpaceNode &snode) return nullptr; } GeoModifierLog &modifier_log = *static_cast(nmd->runtime_eval_log); - context_stack_builder.push(nmd->modifier.name); + compute_context_builder.push(nmd->modifier.name); Vector tree_path_vec{snode.treepath}; if (tree_path_vec.is_empty()) { return nullptr; } for (const bNodeTreePath *path : tree_path_vec.as_span().drop_front(1)) { - context_stack_builder.push(path->node_name, - path->nodetree->id.name + 2); + compute_context_builder.push(path->node_name); } - return &modifier_log.get_tree_log(context_stack_builder.hash()); + return &modifier_log.get_tree_log(compute_context_builder.hash()); } struct SocketTooltipData { diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc index e4ecd0c6f67..49483b3f25a 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc @@ -4,8 +4,8 @@ #include "BLI_virtual_array.hh" #include "BKE_attribute.hh" +#include "BKE_compute_contexts.hh" #include "BKE_context.h" -#include "BKE_context_stack.hh" #include "BKE_curves.hh" #include "BKE_editmesh.h" #include "BKE_geometry_fields.hh" @@ -448,17 +448,17 @@ static const ViewerNodeLog *try_find_viewer_node_log(const SpaceSpreadsheet &ssp nodes::geo_eval_log::GeoModifierLog *modifier_log = static_cast(nmd->runtime_eval_log); - ContextStackBuilder context_stack_builder; - context_stack_builder.push(modifier_context->modifier_name); + ComputeContextBuilder compute_context_builder; + compute_context_builder.push(modifier_context->modifier_name); for (const SpreadsheetContext *context : context_path.as_span().drop_front(2).drop_back(1)) { if (context->type != SPREADSHEET_CONTEXT_NODE) { return nullptr; } const SpreadsheetContextNode &node_context = *reinterpret_cast( context); - context_stack_builder.push(node_context.node_name); + compute_context_builder.push(node_context.node_name); } - const ContextStackHash context_hash = context_stack_builder.hash(); + const ComputeContextHash context_hash = compute_context_builder.hash(); nodes::geo_eval_log::GeoTreeLog &tree_log = modifier_log->get_tree_log(context_hash); tree_log.ensure_viewer_node_logs(); diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 4360650410e..a3c517864c0 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -36,7 +36,7 @@ #include "DNA_windowmanager_types.h" #include "BKE_attribute_math.hh" -#include "BKE_context_stack.hh" +#include "BKE_compute_contexts.hh" #include "BKE_customdata.h" #include "BKE_geometry_fields.hh" #include "BKE_geometry_set_instances.hh" @@ -856,7 +856,7 @@ static void find_side_effect_nodes_for_spreadsheet( const NodesModifierData &nmd, const ModifierEvalContext &ctx, const bNodeTree &root_tree, - MultiValueMap &r_side_effect_nodes) + MultiValueMap &r_side_effect_nodes) { Vector context_path = sspreadsheet.context_path; if (context_path.size() < 3) { @@ -882,8 +882,8 @@ static void find_side_effect_nodes_for_spreadsheet( } } - blender::ContextStackBuilder context_stack_builder; - context_stack_builder.push(nmd.modifier.name); + blender::ComputeContextBuilder compute_context_builder; + compute_context_builder.push(nmd.modifier.name); const Span nested_group_contexts = context_path.as_span().drop_front(2).drop_back(1).cast(); @@ -907,8 +907,7 @@ static void find_side_effect_nodes_for_spreadsheet( } group_node_stack.push(found_node); group = reinterpret_cast(found_node->id); - context_stack_builder.push(node_context->node_name, - group->id.name + 2); + compute_context_builder.push(node_context->node_name); } const bNode *found_viewer_node = nullptr; @@ -922,12 +921,13 @@ static void find_side_effect_nodes_for_spreadsheet( return; } - r_side_effect_nodes.add(context_stack_builder.hash(), &find_viewer_lf_node(*found_viewer_node)); - context_stack_builder.pop(); - while (!context_stack_builder.is_empty()) { - r_side_effect_nodes.add(context_stack_builder.hash(), + r_side_effect_nodes.add(compute_context_builder.hash(), + &find_viewer_lf_node(*found_viewer_node)); + compute_context_builder.pop(); + while (!compute_context_builder.is_empty()) { + r_side_effect_nodes.add(compute_context_builder.hash(), &find_group_lf_node(*group_node_stack.pop())); - context_stack_builder.pop(); + compute_context_builder.pop(); } } @@ -935,7 +935,7 @@ static void find_side_effect_nodes( const NodesModifierData &nmd, const ModifierEvalContext &ctx, const bNodeTree &tree, - MultiValueMap &r_side_effect_nodes) + MultiValueMap &r_side_effect_nodes) { Main *bmain = DEG_get_bmain(ctx.depsgraph); @@ -1157,13 +1157,13 @@ static GeometrySet compute_geometry(const bNodeTree &btree, if (logging_enabled(ctx)) { geo_nodes_modifier_data.eval_log = eval_log.get(); } - MultiValueMap r_side_effect_nodes; + MultiValueMap r_side_effect_nodes; find_side_effect_nodes(*nmd, *ctx, btree, r_side_effect_nodes); geo_nodes_modifier_data.side_effect_nodes = &r_side_effect_nodes; blender::nodes::GeoNodesLFUserData user_data; user_data.modifier_data = &geo_nodes_modifier_data; - blender::bke::ModifierContextStack modifier_context_stack{nullptr, nmd->modifier.name}; - user_data.context_stack = &modifier_context_stack; + blender::bke::ModifierComputeContext modifier_compute_context{nullptr, nmd->modifier.name}; + user_data.compute_context = &modifier_compute_context; blender::LinearAllocator<> allocator; @@ -1682,8 +1682,8 @@ static void panel_draw(const bContext *C, Panel *panel) /* Draw node warnings. */ if (nmd->runtime_eval_log != nullptr) { GeoModifierLog &modifier_log = *static_cast(nmd->runtime_eval_log); - blender::bke::ModifierContextStack context_stack{nullptr, nmd->modifier.name}; - GeoTreeLog &tree_log = modifier_log.get_tree_log(context_stack.hash()); + blender::bke::ModifierComputeContext compute_context{nullptr, nmd->modifier.name}; + GeoTreeLog &tree_log = modifier_log.get_tree_log(compute_context.hash()); tree_log.ensure_node_warnings(); for (const NodeWarning &warning : tree_log.all_warnings) { if (warning.type != NodeWarningType::Info) { diff --git a/source/blender/nodes/NOD_geometry_exec.hh b/source/blender/nodes/NOD_geometry_exec.hh index 9c53d4414a5..9c8d0398518 100644 --- a/source/blender/nodes/NOD_geometry_exec.hh +++ b/source/blender/nodes/NOD_geometry_exec.hh @@ -149,12 +149,12 @@ class GeoNodeExecParams { { GeoNodesLFUserData *user_data = this->user_data(); BLI_assert(user_data != nullptr); - const ContextStack *context_stack = user_data->context_stack; - BLI_assert(context_stack != nullptr); + const ComputeContext *compute_context = user_data->compute_context; + BLI_assert(compute_context != nullptr); if (user_data->modifier_data->eval_log == nullptr) { return nullptr; } - return &user_data->modifier_data->eval_log->get_local_tree_logger(*context_stack); + return &user_data->modifier_data->eval_log->get_local_tree_logger(*compute_context); } /** diff --git a/source/blender/nodes/NOD_geometry_nodes_log.hh b/source/blender/nodes/NOD_geometry_nodes_log.hh index a56ea39e98c..b04ae35a41f 100644 --- a/source/blender/nodes/NOD_geometry_nodes_log.hh +++ b/source/blender/nodes/NOD_geometry_nodes_log.hh @@ -4,7 +4,7 @@ #include -#include "BLI_context_stack.hh" +#include "BLI_compute_context.hh" #include "BLI_enumerable_thread_specific.hh" #include "BLI_generic_pointer.hh" #include "BLI_multi_value_map.hh" @@ -118,9 +118,9 @@ using TimePoint = Clock::time_point; class GeoTreeLogger { public: - std::optional parent_hash; + std::optional parent_hash; std::optional group_node_name; - Vector children_hashes; + Vector children_hashes; LinearAllocator<> *allocator = nullptr; Vector> node_warnings; @@ -177,15 +177,15 @@ class GeoModifierLog { private: struct LocalData { LinearAllocator<> allocator; - Map> tree_logger_by_context; + Map> tree_logger_by_context; }; threading::EnumerableThreadSpecific data_per_thread_; - Map> tree_logs_; + Map> tree_logs_; public: - GeoTreeLogger &get_local_tree_logger(const ContextStack &context_stack); - GeoTreeLog &get_tree_log(const ContextStackHash &context_stack_hash); + GeoTreeLogger &get_local_tree_logger(const ComputeContext &compute_context); + GeoTreeLog &get_tree_log(const ComputeContextHash &compute_context_hash); struct ObjectAndModifier { const Object *object; diff --git a/source/blender/nodes/NOD_geometry_nodes_to_lazy_function_graph.hh b/source/blender/nodes/NOD_geometry_nodes_to_lazy_function_graph.hh index c63f7dbb85f..8b05d56e596 100644 --- a/source/blender/nodes/NOD_geometry_nodes_to_lazy_function_graph.hh +++ b/source/blender/nodes/NOD_geometry_nodes_to_lazy_function_graph.hh @@ -8,7 +8,7 @@ #include "NOD_geometry_nodes_log.hh" #include "NOD_multi_function.hh" -#include "BLI_context_stack.hh" +#include "BLI_compute_context.hh" struct Object; struct Depsgraph; @@ -22,12 +22,12 @@ struct GeoNodesModifierData { const Object *self_object = nullptr; Depsgraph *depsgraph = nullptr; geo_eval_log::GeoModifierLog *eval_log = nullptr; - const MultiValueMap *side_effect_nodes; + const MultiValueMap *side_effect_nodes; }; struct GeoNodesLFUserData : public lf::UserData { GeoNodesModifierData *modifier_data = nullptr; - const ContextStack *context_stack = nullptr; + const ComputeContext *compute_context = nullptr; }; struct GeometryNodeLazyFunctionMapping { diff --git a/source/blender/nodes/intern/geometry_nodes_log.cc b/source/blender/nodes/intern/geometry_nodes_log.cc index 97e6c3a2af3..e099c8be2de 100644 --- a/source/blender/nodes/intern/geometry_nodes_log.cc +++ b/source/blender/nodes/intern/geometry_nodes_log.cc @@ -3,7 +3,7 @@ #include "NOD_geometry_nodes_log.hh" #include "NOD_geometry_nodes_to_lazy_function_graph.hh" -#include "BKE_context_stack.hh" +#include "BKE_compute_contexts.hh" #include "BKE_curves.hh" #include "FN_field_cpp_type.hh" @@ -180,7 +180,7 @@ void GeoTreeLog::ensure_node_warnings() this->nodes.lookup_or_add_default(warnings.first).warnings.append(warnings.second); this->all_warnings.append(warnings.second); } - for (const ContextStackHash &child_hash : tree_logger->children_hashes) { + for (const ComputeContextHash &child_hash : tree_logger->children_hashes) { GeoTreeLog &child_reduced_log = modifier_log_->get_tree_log(child_hash); child_reduced_log.ensure_node_warnings(); const std::optional &group_node_name = @@ -208,7 +208,7 @@ void GeoTreeLog::ensure_node_run_time() this->nodes.lookup_or_add_default_as(node_name).run_time += duration; this->run_time_sum += duration; } - for (const ContextStackHash &child_hash : tree_logger->children_hashes) { + for (const ComputeContextHash &child_hash : tree_logger->children_hashes) { GeoTreeLog &child_reduced_log = modifier_log_->get_tree_log(child_hash); child_reduced_log.ensure_node_run_time(); const std::optional &group_node_name = @@ -289,39 +289,39 @@ void GeoTreeLog::ensure_existing_attributes() reduced_existing_attributes_ = true; } -GeoTreeLogger &GeoModifierLog::get_local_tree_logger(const ContextStack &context_stack) +GeoTreeLogger &GeoModifierLog::get_local_tree_logger(const ComputeContext &compute_context) { LocalData &local_data = data_per_thread_.local(); - Map> &local_tree_loggers = + Map> &local_tree_loggers = local_data.tree_logger_by_context; destruct_ptr &tree_logger_ptr = local_tree_loggers.lookup_or_add_default( - context_stack.hash()); + compute_context.hash()); if (tree_logger_ptr) { return *tree_logger_ptr; } tree_logger_ptr = local_data.allocator.construct(); GeoTreeLogger &tree_logger = *tree_logger_ptr; tree_logger.allocator = &local_data.allocator; - const ContextStack *parent_context_stack = context_stack.parent(); - if (parent_context_stack != nullptr) { - tree_logger.parent_hash = parent_context_stack->hash(); - GeoTreeLogger &parent_logger = this->get_local_tree_logger(*parent_context_stack); - parent_logger.children_hashes.append(context_stack.hash()); + const ComputeContext *parent_compute_context = compute_context.parent(); + if (parent_compute_context != nullptr) { + tree_logger.parent_hash = parent_compute_context->hash(); + GeoTreeLogger &parent_logger = this->get_local_tree_logger(*parent_compute_context); + parent_logger.children_hashes.append(compute_context.hash()); } - if (const bke::NodeGroupContextStack *node_group_context_stack = - dynamic_cast(&context_stack)) { - tree_logger.group_node_name.emplace(node_group_context_stack->node_name()); + if (const bke::NodeGroupComputeContext *node_group_compute_context = + dynamic_cast(&compute_context)) { + tree_logger.group_node_name.emplace(node_group_compute_context->node_name()); } return tree_logger; } -GeoTreeLog &GeoModifierLog::get_tree_log(const ContextStackHash &context_stack_hash) +GeoTreeLog &GeoModifierLog::get_tree_log(const ComputeContextHash &compute_context_hash) { - GeoTreeLog &reduced_tree_log = *tree_logs_.lookup_or_add_cb(context_stack_hash, [&]() { + GeoTreeLog &reduced_tree_log = *tree_logs_.lookup_or_add_cb(compute_context_hash, [&]() { Vector tree_logs; for (LocalData &local_data : data_per_thread_) { destruct_ptr *tree_log = local_data.tree_logger_by_context.lookup_ptr( - context_stack_hash); + compute_context_hash); if (tree_log != nullptr) { tree_logs.append(tree_log->get()); } @@ -388,12 +388,13 @@ GeoTreeLog *GeoModifierLog::get_tree_log_for_node_editor(const SpaceNode &snode) if (tree_path.is_empty()) { return nullptr; } - ContextStackBuilder context_stack_builder; - context_stack_builder.push(object_and_modifier->nmd->modifier.name); + ComputeContextBuilder compute_context_builder; + compute_context_builder.push( + object_and_modifier->nmd->modifier.name); for (const bNodeTreePath *path_item : tree_path.as_span().drop_front(1)) { - context_stack_builder.push(path_item->node_name); + compute_context_builder.push(path_item->node_name); } - return &modifier_log->get_tree_log(context_stack_builder.hash()); + return &modifier_log->get_tree_log(compute_context_builder.hash()); } } // namespace blender::nodes::geo_eval_log diff --git a/source/blender/nodes/intern/geometry_nodes_to_lazy_function_graph.cc b/source/blender/nodes/intern/geometry_nodes_to_lazy_function_graph.cc index bcb39835a77..2c7c5cc932f 100644 --- a/source/blender/nodes/intern/geometry_nodes_to_lazy_function_graph.cc +++ b/source/blender/nodes/intern/geometry_nodes_to_lazy_function_graph.cc @@ -9,7 +9,7 @@ #include "DNA_ID.h" -#include "BKE_context_stack.hh" +#include "BKE_compute_contexts.hh" #include "BKE_geometry_set.hh" #include "BKE_type_conversions.hh" @@ -121,7 +121,7 @@ class LazyFunctionForGeometryNode : public LazyFunction { if (geo_eval_log::GeoModifierLog *modifier_log = user_data->modifier_data->eval_log) { geo_eval_log::GeoTreeLogger &tree_logger = modifier_log->get_local_tree_logger( - *user_data->context_stack); + *user_data->compute_context); tree_logger.node_execution_times.append_as(node_.name, start_time, end_time); } } @@ -474,7 +474,7 @@ class LazyFunctionForViewerNode : public LazyFunction { } geo_eval_log::GeoTreeLogger &tree_logger = - user_data->modifier_data->eval_log->get_local_tree_logger(*user_data->context_stack); + user_data->modifier_data->eval_log->get_local_tree_logger(*user_data->compute_context); tree_logger.log_viewer_node(bnode_, geometry, field); } }; @@ -534,10 +534,9 @@ class LazyFunctionForGroupNode : public LazyFunction { { GeoNodesLFUserData *user_data = dynamic_cast(context.user_data); BLI_assert(user_data != nullptr); - bke::NodeGroupContextStack context_stack{ - user_data->context_stack, group_node_.name, group_node_.id->name + 2}; + bke::NodeGroupComputeContext compute_context{user_data->compute_context, group_node_.name}; GeoNodesLFUserData group_user_data = *user_data; - group_user_data.context_stack = &context_stack; + group_user_data.compute_context = &compute_context; lf::Context group_context = context; group_context.user_data = &group_user_data; @@ -1156,7 +1155,7 @@ void GeometryNodesLazyFunctionLogger::log_socket_value(const fn::lazy_function:: return; } geo_eval_log::GeoTreeLogger &tree_logger = - user_data->modifier_data->eval_log->get_local_tree_logger(*user_data->context_stack); + user_data->modifier_data->eval_log->get_local_tree_logger(*user_data->compute_context); for (const bNodeSocket *bsocket : bsockets) { if (bsocket->is_input() && !bsocket->directly_linked_sockets().is_empty()) { continue; @@ -1174,7 +1173,7 @@ Vector GeometryNodesLazyFunctionSideEffectProvider:: { GeoNodesLFUserData *user_data = dynamic_cast(context.user_data); BLI_assert(user_data != nullptr); - const ContextStackHash &context_hash = user_data->context_stack->hash(); + const ComputeContextHash &context_hash = user_data->compute_context->hash(); const GeoNodesModifierData &modifier_data = *user_data->modifier_data; return modifier_data.side_effect_nodes->lookup(context_hash); } -- cgit v1.2.3