diff options
Diffstat (limited to 'source/blender/functions')
7 files changed, 70 insertions, 15 deletions
diff --git a/source/blender/functions/FN_multi_function.hh b/source/blender/functions/FN_multi_function.hh index 77ab2749377..eaddcee7964 100644 --- a/source/blender/functions/FN_multi_function.hh +++ b/source/blender/functions/FN_multi_function.hh @@ -98,6 +98,11 @@ class MultiFunction { return signature_.function_name; } + bool depends_on_context() const + { + return signature_.depends_on_context; + } + const MFSignature &signature() const { return signature_; diff --git a/source/blender/functions/FN_multi_function_context.hh b/source/blender/functions/FN_multi_function_context.hh index 3a448cc2c6e..8492fd86742 100644 --- a/source/blender/functions/FN_multi_function_context.hh +++ b/source/blender/functions/FN_multi_function_context.hh @@ -29,15 +29,39 @@ #include "BLI_utildefines.h" +#include "BLI_map.hh" + namespace blender::fn { +class MFContext; + class MFContextBuilder { + private: + Map<std::string, const void *> global_contexts_; + + friend MFContext; + + public: + template<typename T> void add_global_context(std::string name, const T *context) + { + global_contexts_.add_new(std::move(name), (const void *)context); + } }; class MFContext { + private: + MFContextBuilder &builder_; + public: - MFContext(MFContextBuilder &UNUSED(builder)) + MFContext(MFContextBuilder &builder) : builder_(builder) + { + } + + template<typename T> const T *get_global_context(StringRef name) const { + const void *context = builder_.global_contexts_.lookup_default_as(name, nullptr); + /* TODO: Implement type checking. */ + return (const T *)context; } }; diff --git a/source/blender/functions/FN_multi_function_network.hh b/source/blender/functions/FN_multi_function_network.hh index f6d6c7417e7..20f8fb2ee43 100644 --- a/source/blender/functions/FN_multi_function_network.hh +++ b/source/blender/functions/FN_multi_function_network.hh @@ -95,7 +95,7 @@ class MFNode : NonCopyable, NonMovable { Span<MFOutputSocket *> outputs(); Span<const MFOutputSocket *> outputs() const; - bool all_inputs_have_origin() const; + bool has_unlinked_inputs() const; private: void destruct_sockets(); @@ -341,14 +341,14 @@ inline Span<const MFOutputSocket *> MFNode::outputs() const return outputs_; } -inline bool MFNode::all_inputs_have_origin() const +inline bool MFNode::has_unlinked_inputs() const { for (const MFInputSocket *socket : inputs_) { if (socket->origin() == nullptr) { - return false; + return true; } } - return true; + return false; } /* -------------------------------------------------------------------- diff --git a/source/blender/functions/FN_multi_function_params.hh b/source/blender/functions/FN_multi_function_params.hh index 9cce8bb7401..93d7b47af83 100644 --- a/source/blender/functions/FN_multi_function_params.hh +++ b/source/blender/functions/FN_multi_function_params.hh @@ -68,6 +68,10 @@ class MFParamsBuilder { virtual_array_spans_.append(ref); } + template<typename T> void add_uninitialized_single_output(T *value) + { + this->add_uninitialized_single_output(GMutableSpan(CPPType::get<T>(), value, 1)); + } void add_uninitialized_single_output(GMutableSpan ref) { this->assert_current_param_type(MFParamType::ForSingleOutput(ref.type())); diff --git a/source/blender/functions/FN_multi_function_signature.hh b/source/blender/functions/FN_multi_function_signature.hh index af5f61fe2ee..26df7c98e4a 100644 --- a/source/blender/functions/FN_multi_function_signature.hh +++ b/source/blender/functions/FN_multi_function_signature.hh @@ -36,6 +36,7 @@ struct MFSignature { RawVector<std::string> param_names; RawVector<MFParamType> param_types; RawVector<int> param_data_indices; + bool depends_on_context = false; int data_index(int param_index) const { @@ -157,6 +158,15 @@ class MFSignatureBuilder { break; } } + + /* Context */ + + /** This indicates that the function accesses the context. This disables optimizations that + * depend on the fact that the function always performes the same operation. */ + void depends_on_context() + { + data_.depends_on_context = true; + } }; } // namespace blender::fn diff --git a/source/blender/functions/intern/multi_function_network_evaluation.cc b/source/blender/functions/intern/multi_function_network_evaluation.cc index a7e1a2f42af..58577e31c42 100644 --- a/source/blender/functions/intern/multi_function_network_evaluation.cc +++ b/source/blender/functions/intern/multi_function_network_evaluation.cc @@ -230,7 +230,7 @@ BLI_NOINLINE void MFNetworkEvaluator::evaluate_network_to_compute_outputs( } BLI_assert(node.is_function()); - BLI_assert(node.all_inputs_have_origin()); + BLI_assert(!node.has_unlinked_inputs()); const MFFunctionNode &function_node = node.as_function(); bool all_origins_are_computed = true; diff --git a/source/blender/functions/intern/multi_function_network_optimization.cc b/source/blender/functions/intern/multi_function_network_optimization.cc index e76b2f51a15..f1e047f01a1 100644 --- a/source/blender/functions/intern/multi_function_network_optimization.cc +++ b/source/blender/functions/intern/multi_function_network_optimization.cc @@ -142,13 +142,24 @@ void dead_node_removal(MFNetwork &network) * * \{ */ +static bool function_node_can_be_constant(MFFunctionNode *node) +{ + if (node->has_unlinked_inputs()) { + return false; + } + if (node->function().depends_on_context()) { + return false; + } + return true; +} + static Vector<MFNode *> find_non_constant_nodes(MFNetwork &network) { Vector<MFNode *> non_constant_nodes; non_constant_nodes.extend(network.dummy_nodes()); for (MFFunctionNode *node : network.function_nodes()) { - if (!node->all_inputs_have_origin()) { + if (!function_node_can_be_constant(node)) { non_constant_nodes.append(node); } } @@ -319,17 +330,18 @@ void constant_folding(MFNetwork &network, ResourceCollector &resources) static uint64_t compute_node_hash(MFFunctionNode &node, RNG *rng, Span<uint64_t> node_hashes) { + if (node.function().depends_on_context()) { + return BLI_rng_get_uint(rng); + } + if (node.has_unlinked_inputs()) { + return BLI_rng_get_uint(rng); + } + uint64_t combined_inputs_hash = 394659347u; for (MFInputSocket *input_socket : node.inputs()) { MFOutputSocket *origin_socket = input_socket->origin(); - uint64_t input_hash; - if (origin_socket == nullptr) { - input_hash = BLI_rng_get_uint(rng); - } - else { - input_hash = BLI_ghashutil_combine_hash(node_hashes[origin_socket->node().id()], - origin_socket->index()); - } + uint64_t input_hash = BLI_ghashutil_combine_hash(node_hashes[origin_socket->node().id()], + origin_socket->index()); combined_inputs_hash = BLI_ghashutil_combine_hash(combined_inputs_hash, input_hash); } |