diff options
author | Jacques Lucke <jacques@blender.org> | 2021-11-23 16:47:25 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2021-11-23 16:49:26 +0300 |
commit | 47276b84701727c2f187c77f1ec502b4ca4963bd (patch) | |
tree | ac6e6fced7908dbaa984cfe686b2e3a080b99fc7 /source/blender/nodes/NOD_geometry_exec.hh | |
parent | 0bedd5d14f6d61a6a4a96cc7f88484b0dc46f752 (diff) |
Geometry Nodes: reduce overhead when processing single values
Currently the geometry nodes evaluator always stores a field for every
type that supports it, even if it is just a single value. This results in a lot
of overhead when there are many sockets that just contain a single
value, which is often the case.
This introduces a new `ValueOrField<T>` type that is used by the geometry
nodes evaluator. Now a field will only be created when it is actually
necessary. See D13307 for more details. In extrem cases this can speed
up the evaluation 2-3x (those cases are probably never hit in practice
though, but it's good to get rid of unnecessary overhead nevertheless).
Differential Revision: https://developer.blender.org/D13307
Diffstat (limited to 'source/blender/nodes/NOD_geometry_exec.hh')
-rw-r--r-- | source/blender/nodes/NOD_geometry_exec.hh | 43 |
1 files changed, 29 insertions, 14 deletions
diff --git a/source/blender/nodes/NOD_geometry_exec.hh b/source/blender/nodes/NOD_geometry_exec.hh index 700f32ee414..6b6e8a89240 100644 --- a/source/blender/nodes/NOD_geometry_exec.hh +++ b/source/blender/nodes/NOD_geometry_exec.hh @@ -59,6 +59,7 @@ using fn::GVArray; using fn::GVArray_GSpan; using fn::GVMutableArray; using fn::GVMutableArray_GSpan; +using fn::ValueOrField; using geometry_nodes_eval_log::NodeWarningType; /** @@ -129,7 +130,7 @@ class GeoNodeExecParams { } template<typename T> - static inline constexpr bool is_stored_as_field_v = std::is_same_v<T, float> || + static inline constexpr bool is_field_base_type_v = std::is_same_v<T, float> || std::is_same_v<T, int> || std::is_same_v<T, bool> || std::is_same_v<T, ColorGeometry4f> || @@ -157,9 +158,15 @@ class GeoNodeExecParams { */ template<typename T> T extract_input(StringRef identifier) { - if constexpr (is_stored_as_field_v<T>) { - Field<T> field = this->extract_input<Field<T>>(identifier); - return fn::evaluate_constant_field(field); + if constexpr (is_field_base_type_v<T>) { + ValueOrField<T> value_or_field = this->extract_input<ValueOrField<T>>(identifier); + return value_or_field.as_value(); + } + else if constexpr (fn::is_field_v<T>) { + using BaseType = typename T::base_type; + ValueOrField<BaseType> value_or_field = this->extract_input<ValueOrField<BaseType>>( + identifier); + return value_or_field.as_field(); } else { #ifdef DEBUG @@ -186,9 +193,9 @@ class GeoNodeExecParams { Vector<GMutablePointer> gvalues = provider_->extract_multi_input(identifier); Vector<T> values; for (GMutablePointer gvalue : gvalues) { - if constexpr (is_stored_as_field_v<T>) { - const Field<T> field = gvalue.relocate_out<Field<T>>(); - values.append(fn::evaluate_constant_field(field)); + if constexpr (is_field_base_type_v<T>) { + const ValueOrField<T> value_or_field = gvalue.relocate_out<ValueOrField<T>>(); + values.append(value_or_field.as_value()); } else { values.append(gvalue.relocate_out<T>()); @@ -200,11 +207,16 @@ class GeoNodeExecParams { /** * Get the input value for the input socket with the given identifier. */ - template<typename T> const T get_input(StringRef identifier) const + template<typename T> T get_input(StringRef identifier) const { - if constexpr (is_stored_as_field_v<T>) { - const Field<T> &field = this->get_input<Field<T>>(identifier); - return fn::evaluate_constant_field(field); + if constexpr (is_field_base_type_v<T>) { + ValueOrField<T> value_or_field = this->get_input<ValueOrField<T>>(identifier); + return value_or_field.as_value(); + } + else if constexpr (fn::is_field_v<T>) { + using BaseType = typename T::base_type; + ValueOrField<BaseType> value_or_field = this->get_input<ValueOrField<BaseType>>(identifier); + return value_or_field.as_field(); } else { #ifdef DEBUG @@ -226,9 +238,12 @@ class GeoNodeExecParams { template<typename T> void set_output(StringRef identifier, T &&value) { using StoredT = std::decay_t<T>; - if constexpr (is_stored_as_field_v<StoredT>) { - this->set_output<Field<StoredT>>(identifier, - fn::make_constant_field<StoredT>(std::forward<T>(value))); + if constexpr (is_field_base_type_v<StoredT>) { + this->set_output(identifier, ValueOrField<StoredT>(std::forward<T>(value))); + } + else if constexpr (fn::is_field_v<StoredT>) { + using BaseType = typename StoredT::base_type; + this->set_output(identifier, ValueOrField<BaseType>(std::forward<T>(value))); } else { const CPPType &type = CPPType::get<StoredT>(); |