From bef0d6c067cd7dd46c9683079c84775a2b052e1f Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 6 Oct 2023 22:32:51 +0200 Subject: [PATCH] Functions: extract remapped-params to make it reusable This idea is of remapping parameters of lazy-functions is useful not only for the repeat zone. For example, it could be used for the for-each zone as well. Also, moving it to a more general place indicates that there is no repeat-zone specific stuff in it. --- .../functions/FN_lazy_function_execute.hh | 28 +++++++ .../functions/intern/lazy_function_execute.cc | 72 ++++++++++++++++++ .../intern/geometry_nodes_lazy_function.cc | 76 ++----------------- 3 files changed, 108 insertions(+), 68 deletions(-) diff --git a/source/blender/functions/FN_lazy_function_execute.hh b/source/blender/functions/FN_lazy_function_execute.hh index f75f61b8afd..267a5da5825 100644 --- a/source/blender/functions/FN_lazy_function_execute.hh +++ b/source/blender/functions/FN_lazy_function_execute.hh @@ -46,6 +46,34 @@ class BasicParams : public Params { bool try_enable_multi_threading_impl() override; }; +/** + * Wraps an existing #Params. This should be used when a lazy-function internally contains another + * lazy-function that handles a subset or the inputs and outputs. + */ +class RemappedParams : public Params { + private: + Params &base_params_; + Span input_map_; + Span output_map_; + bool &multi_threading_enabled_; + + public: + RemappedParams(const LazyFunction &fn, + Params &base_params, + Span input_map, + Span output_map, + bool &multi_threading_enabled); + + void *try_get_input_data_ptr_impl(const int index) const override; + void *try_get_input_data_ptr_or_request_impl(const int index) override; + void *get_output_data_ptr_impl(const int index) override; + void output_set_impl(const int index) override; + bool output_was_set_impl(const int index) const override; + ValueUsage get_output_usage_impl(const int index) const override; + void set_input_unused_impl(const int index) override; + bool try_enable_multi_threading_impl() override; +}; + namespace detail { /** diff --git a/source/blender/functions/intern/lazy_function_execute.cc b/source/blender/functions/intern/lazy_function_execute.cc index f50621d66ac..eb446cbbea7 100644 --- a/source/blender/functions/intern/lazy_function_execute.cc +++ b/source/blender/functions/intern/lazy_function_execute.cc @@ -10,6 +10,10 @@ namespace blender::fn::lazy_function { +/* -------------------------------------------------------------------- */ +/** \name BasicParams. + * \{ */ + BasicParams::BasicParams(const LazyFunction &fn, const Span inputs, const Span outputs, @@ -69,4 +73,72 @@ bool BasicParams::try_enable_multi_threading_impl() return true; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name RemappedParams. + * \{ */ + +RemappedParams::RemappedParams(const LazyFunction &fn, + Params &base_params, + const Span input_map, + const Span output_map, + bool &multi_threading_enabled) + : Params(fn, multi_threading_enabled), + base_params_(base_params), + input_map_(input_map), + output_map_(output_map), + multi_threading_enabled_(multi_threading_enabled) +{ +} + +void *RemappedParams::try_get_input_data_ptr_impl(const int index) const +{ + return base_params_.try_get_input_data_ptr(input_map_[index]); +} + +void *RemappedParams::try_get_input_data_ptr_or_request_impl(const int index) +{ + return base_params_.try_get_input_data_ptr_or_request(input_map_[index]); +} + +void *RemappedParams::get_output_data_ptr_impl(const int index) +{ + return base_params_.get_output_data_ptr(output_map_[index]); +} + +void RemappedParams::output_set_impl(const int index) +{ + return base_params_.output_set(output_map_[index]); +} + +bool RemappedParams::output_was_set_impl(const int index) const +{ + return base_params_.output_was_set(output_map_[index]); +} + +lf::ValueUsage RemappedParams::get_output_usage_impl(const int index) const +{ + return base_params_.get_output_usage(output_map_[index]); +} + +void RemappedParams::set_input_unused_impl(const int index) +{ + return base_params_.set_input_unused(input_map_[index]); +} + +bool RemappedParams::try_enable_multi_threading_impl() +{ + if (multi_threading_enabled_) { + return true; + } + if (base_params_.try_enable_multi_threading()) { + multi_threading_enabled_ = true; + return true; + } + return false; +} + +/** \} */ + } // namespace blender::fn::lazy_function diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index abfb40401ca..8c43a198728 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -1478,75 +1478,10 @@ struct RepeatEvalStorage { std::optional graph_executor; void *graph_executor_storage = nullptr; bool multi_threading_enabled = false; - IndexRange input_index_map; + Vector input_index_map; Vector output_index_map; }; -class ParamsForRepeatZoneGraph : public lf::Params { - private: - lf::Params &zone_params_; - RepeatEvalStorage &eval_storage_; - - public: - ParamsForRepeatZoneGraph(RepeatEvalStorage &eval_storage, lf::Params &zone_params) - : lf::Params(*eval_storage.graph_executor, eval_storage.multi_threading_enabled), - zone_params_{zone_params}, - eval_storage_(eval_storage) - { - } - - int map_input_index(const int index) const - { - return eval_storage_.input_index_map[index]; - } - - int map_output_index(const int index) const - { - return eval_storage_.output_index_map[index]; - } - - void *try_get_input_data_ptr_impl(const int index) const - { - return zone_params_.try_get_input_data_ptr(this->map_input_index(index)); - } - - void *try_get_input_data_ptr_or_request_impl(const int index) - { - return zone_params_.try_get_input_data_ptr_or_request(this->map_input_index(index)); - } - void *get_output_data_ptr_impl(const int index) - { - return zone_params_.get_output_data_ptr(this->map_output_index(index)); - } - void output_set_impl(const int index) - { - return zone_params_.output_set(this->map_output_index(index)); - } - bool output_was_set_impl(const int index) const - { - return zone_params_.output_was_set(this->map_output_index(index)); - } - lf::ValueUsage get_output_usage_impl(const int index) const - { - return zone_params_.get_output_usage(this->map_output_index(index)); - } - void set_input_unused_impl(const int index) - { - return zone_params_.set_input_unused(this->map_input_index(index)); - } - bool try_enable_multi_threading_impl() - { - if (eval_storage_.multi_threading_enabled) { - return true; - } - if (zone_params_.try_enable_multi_threading()) { - eval_storage_.multi_threading_enabled = true; - return true; - } - return false; - } -}; - class LazyFunctionForRepeatZone : public LazyFunction { private: const bNodeTreeZone &zone_; @@ -1649,7 +1584,11 @@ class LazyFunctionForRepeatZone : public LazyFunction { } /* Execute the graph for the repeat zone. */ - ParamsForRepeatZoneGraph eval_graph_params{eval_storage, params}; + lf::RemappedParams eval_graph_params{*eval_storage.graph_executor, + params, + eval_storage.input_index_map, + eval_storage.output_index_map, + eval_storage.multi_threading_enabled}; lf::Context eval_graph_context{ eval_storage.graph_executor_storage, context.user_data, context.local_user_data}; eval_storage.graph_executor->execute(eval_graph_params, eval_graph_context); @@ -1812,8 +1751,9 @@ class LazyFunctionForRepeatZone : public LazyFunction { * zone. The main complexity below stems from the fact that the iterations input is handled * outside of this graph. */ eval_storage.output_index_map.reinitialize(outputs_.size() - 1); + eval_storage.input_index_map.resize(inputs_.size() - 1); + std::iota(eval_storage.input_index_map.begin(), eval_storage.input_index_map.end(), 1); - eval_storage.input_index_map = inputs_.index_range().drop_front(1); Vector lf_graph_inputs = lf_inputs.as_span().drop_front(1); const int iteration_usage_index = zone_info_.indices.outputs.input_usages[0];