Geometry Nodes: avoid creating a lazy function many times

It's better to use some statically allocated functions instead
of dynamically allocating them all the time.
This commit is contained in:
Jacques Lucke 2023-01-28 15:28:55 +01:00
parent b2534fb866
commit 90253ad2e7
Notes: blender-bot 2023-02-14 06:00:46 +01:00
Referenced by commit e497da5fda, Fix: off by one error in previous commit
1 changed files with 32 additions and 6 deletions

View File

@ -1078,6 +1078,33 @@ class LazyFunctionForAnonymousAttributeSetJoin : public lf::LazyFunction {
{
return 2 * i + 1;
}
/**
* Cache for functions small amounts to avoid to avoid building them many times.
*/
static const LazyFunctionForAnonymousAttributeSetJoin &get_cached(
const int amount, Vector<std::unique_ptr<LazyFunction>> &r_functions)
{
constexpr int cache_amount = 16;
static std::array<LazyFunctionForAnonymousAttributeSetJoin, cache_amount> cached_functions =
get_cache(std::make_index_sequence<cache_amount>{});
if (amount <= cached_functions.size()) {
return cached_functions[amount];
}
auto fn = std::make_unique<LazyFunctionForAnonymousAttributeSetJoin>(amount);
const auto &fn_ref = *fn;
r_functions.append(std::move(fn));
return fn_ref;
}
private:
template<size_t... I>
static std::array<LazyFunctionForAnonymousAttributeSetJoin, sizeof...(I)> get_cache(
std::index_sequence<I...> /*indices*/)
{
return {LazyFunctionForAnonymousAttributeSetJoin(I)...};
}
};
enum class AttributeReferenceKeyType {
@ -2529,18 +2556,17 @@ struct GeometryNodesLazyFunctionGraphBuilder {
key.extend(used_sockets);
std::sort(key.begin(), key.end());
return cache.lookup_or_add_cb(key, [&]() {
auto lazy_function = std::make_unique<LazyFunctionForAnonymousAttributeSetJoin>(
attribute_set_sockets.size());
lf::Node &lf_node = lf_graph_->add_function(*lazy_function);
const auto &lazy_function = LazyFunctionForAnonymousAttributeSetJoin::get_cached(
attribute_set_sockets.size(), lf_graph_info_->functions);
lf::Node &lf_node = lf_graph_->add_function(lazy_function);
for (const int i : attribute_set_sockets.index_range()) {
lf::InputSocket &lf_use_input = lf_node.input(lazy_function->get_use_input(i));
lf::InputSocket &lf_use_input = lf_node.input(lazy_function.get_use_input(i));
socket_usage_inputs_.add(&lf_use_input);
lf::InputSocket &lf_attributes_input = lf_node.input(
lazy_function->get_attribute_set_input(i));
lazy_function.get_attribute_set_input(i));
lf_graph_->add_link(*used_sockets[i], lf_use_input);
lf_graph_->add_link(*attribute_set_sockets[i], lf_attributes_input);
}
lf_graph_info_->functions.append(std::move(lazy_function));
return &lf_node.output(0);
});
}