Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenlib/BLI_generic_virtual_array.hh93
-rw-r--r--source/blender/blenlib/BLI_virtual_array.hh36
-rw-r--r--source/blender/blenlib/intern/generic_virtual_array.cc162
-rw-r--r--source/blender/functions/FN_multi_function_params.hh37
-rw-r--r--source/blender/functions/FN_multi_function_signature.hh25
5 files changed, 216 insertions, 137 deletions
diff --git a/source/blender/blenlib/BLI_generic_virtual_array.hh b/source/blender/blenlib/BLI_generic_virtual_array.hh
index d02760d9178..3fce2947d0d 100644
--- a/source/blender/blenlib/BLI_generic_virtual_array.hh
+++ b/source/blender/blenlib/BLI_generic_virtual_array.hh
@@ -61,7 +61,9 @@ class GVArrayImpl {
/* A generic version of #VMutableArrayImpl. */
class GVMutableArrayImpl : public GVArrayImpl {
public:
- GVMutableArrayImpl(const CPPType &type, int64_t size);
+ GVMutableArrayImpl(const CPPType &type, int64_t size) : GVArrayImpl(type, size)
+ {
+ }
virtual void set_by_copy(int64_t index, const void *value);
virtual void set_by_relocate(int64_t index, void *value);
@@ -105,7 +107,7 @@ class GVArrayCommon {
Storage storage_;
protected:
- GVArrayCommon();
+ GVArrayCommon() = default;
GVArrayCommon(const GVArrayCommon &other);
GVArrayCommon(GVArrayCommon &&other) noexcept;
GVArrayCommon(const GVArrayImpl *impl);
@@ -186,6 +188,10 @@ class GVArray : public GVArrayCommon {
GVArray(const GVArrayImpl *impl);
GVArray(std::shared_ptr<const GVArrayImpl> impl);
+ GVArray(varray_tag::span /* tag */, GSpan span);
+ GVArray(varray_tag::single_ref /* tag */, const CPPType &type, int64_t size, const void *value);
+ GVArray(varray_tag::single /* tag */, const CPPType &type, int64_t size, const void *value);
+
template<typename T> GVArray(const VArray<T> &varray);
template<typename T> VArray<T> typed() const;
@@ -643,10 +649,18 @@ class GVArrayImpl_For_GSpan : public GVMutableArrayImpl {
const int64_t element_size_;
public:
- GVArrayImpl_For_GSpan(const GMutableSpan span);
+ GVArrayImpl_For_GSpan(const GMutableSpan span)
+ : GVMutableArrayImpl(span.type(), span.size()),
+ data_(span.data()),
+ element_size_(span.type().size())
+ {
+ }
protected:
- GVArrayImpl_For_GSpan(const CPPType &type, int64_t size);
+ GVArrayImpl_For_GSpan(const CPPType &type, int64_t size)
+ : GVMutableArrayImpl(type, size), element_size_(type.size())
+ {
+ }
public:
void get(int64_t index, void *r_value) const override;
@@ -667,6 +681,61 @@ class GVArrayImpl_For_GSpan : public GVMutableArrayImpl {
void *dst) const override;
};
+class GVArrayImpl_For_GSpan_final final : public GVArrayImpl_For_GSpan {
+ public:
+ using GVArrayImpl_For_GSpan::GVArrayImpl_For_GSpan;
+
+ private:
+ bool may_have_ownership() const override
+ {
+ return false;
+ }
+};
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name #GVArrayImpl_For_SingleValueRef.
+ * \{ */
+
+class GVArrayImpl_For_SingleValueRef : public GVArrayImpl {
+ protected:
+ const void *value_ = nullptr;
+
+ public:
+ GVArrayImpl_For_SingleValueRef(const CPPType &type, const int64_t size, const void *value)
+ : GVArrayImpl(type, size), value_(value)
+ {
+ }
+
+ protected:
+ GVArrayImpl_For_SingleValueRef(const CPPType &type, const int64_t size) : GVArrayImpl(type, size)
+ {
+ }
+
+ void get(const int64_t index, void *r_value) const override;
+ void get_to_uninitialized(const int64_t index, void *r_value) const override;
+ bool is_span() const override;
+ GSpan get_internal_span() const override;
+ bool is_single() const override;
+ void get_internal_single(void *r_value) const override;
+ void materialize(const IndexMask mask, void *dst) const override;
+ void materialize_to_uninitialized(const IndexMask mask, void *dst) const override;
+ void materialize_compressed(const IndexMask mask, void *dst) const override;
+ void materialize_compressed_to_uninitialized(const IndexMask mask, void *dst) const override;
+};
+
+class GVArrayImpl_For_SingleValueRef_final final : public GVArrayImpl_For_SingleValueRef {
+ public:
+ using GVArrayImpl_For_SingleValueRef::GVArrayImpl_For_SingleValueRef;
+
+ private:
+ bool may_have_ownership() const override
+ {
+ return false;
+ }
+};
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -809,6 +878,22 @@ inline bool GVArrayCommon::is_empty() const
/** \name Inline methods for #GVArray.
* \{ */
+inline GVArray::GVArray(varray_tag::span /* tag */, const GSpan span)
+{
+ /* Use const-cast because the underlying virtual array implementation is shared between const
+ * and non const data. */
+ GMutableSpan mutable_span{span.type(), const_cast<void *>(span.data()), span.size()};
+ this->emplace<GVArrayImpl_For_GSpan_final>(mutable_span);
+}
+
+inline GVArray::GVArray(varray_tag::single_ref /* tag */,
+ const CPPType &type,
+ const int64_t size,
+ const void *value)
+{
+ this->emplace<GVArrayImpl_For_SingleValueRef_final>(type, size, value);
+}
+
namespace detail {
template<typename StorageT> constexpr GVArrayAnyExtraInfo GVArrayAnyExtraInfo::get()
{
diff --git a/source/blender/blenlib/BLI_virtual_array.hh b/source/blender/blenlib/BLI_virtual_array.hh
index 6efd1d6d769..ab4ca185ddb 100644
--- a/source/blender/blenlib/BLI_virtual_array.hh
+++ b/source/blender/blenlib/BLI_virtual_array.hh
@@ -872,6 +872,22 @@ template<typename T> class VArrayCommon {
template<typename T> class VMutableArray;
/**
+ * Various tags to disambiguate constructors of virtual arrays.
+ * Generally it is easier to use `VArray::For*` functions to construct virtual arrays, but
+ * sometimes being able to use the constructor can result in better performance For example, when
+ * constructing the virtual array directly in a vector. Without the constructor one would have to
+ * construct the virtual array first and then move it into the vector.
+ */
+namespace varray_tag {
+struct span {
+};
+struct single_ref {
+};
+struct single {
+};
+} // namespace varray_tag
+
+/**
* A #VArray wraps a virtual array implementation and provides easy access to its elements. It can
* be copied and moved. While it is relatively small, it should still be passed by reference if
* possible (other than e.g. #Span).
@@ -892,6 +908,19 @@ template<typename T> class VArray : public VArrayCommon<T> {
{
}
+ VArray(varray_tag::span /* tag */, Span<T> span)
+ {
+ /* Cast const away, because the virtual array implementation for const and non const spans is
+ * shared. */
+ MutableSpan<T> mutable_span{const_cast<T *>(span.data()), span.size()};
+ this->template emplace<VArrayImpl_For_Span_final<T>>(mutable_span);
+ }
+
+ VArray(varray_tag::single /* tag */, T value, const int64_t size)
+ {
+ this->template emplace<VArrayImpl_For_Single<T>>(std::move(value), size);
+ }
+
/**
* Construct a new virtual array for a custom #VArrayImpl.
*/
@@ -908,7 +937,7 @@ template<typename T> class VArray : public VArrayCommon<T> {
*/
static VArray ForSingle(T value, const int64_t size)
{
- return VArray::For<VArrayImpl_For_Single<T>>(std::move(value), size);
+ return VArray(varray_tag::single{}, std::move(value), size);
}
/**
@@ -917,10 +946,7 @@ template<typename T> class VArray : public VArrayCommon<T> {
*/
static VArray ForSpan(Span<T> values)
{
- /* Cast const away, because the virtual array implementation for const and non const spans is
- * shared. */
- MutableSpan<T> span{const_cast<T *>(values.data()), values.size()};
- return VArray::For<VArrayImpl_For_Span_final<T>>(span);
+ return VArray(varray_tag::span{}, values);
}
/**
diff --git a/source/blender/blenlib/intern/generic_virtual_array.cc b/source/blender/blenlib/intern/generic_virtual_array.cc
index a3a17952a97..a6fbf4bff5b 100644
--- a/source/blender/blenlib/intern/generic_virtual_array.cc
+++ b/source/blender/blenlib/intern/generic_virtual_array.cc
@@ -85,11 +85,6 @@ bool GVArrayImpl::may_have_ownership() const
/** \name #GVMutableArrayImpl
* \{ */
-GVMutableArrayImpl::GVMutableArrayImpl(const CPPType &type, const int64_t size)
- : GVArrayImpl(type, size)
-{
-}
-
void GVMutableArrayImpl::set_by_copy(const int64_t index, const void *value)
{
BUFFER_FOR_CPP_TYPE_VALUE(*type_, buffer);
@@ -141,18 +136,6 @@ bool GVMutableArrayImpl::try_assign_VMutableArray(void *UNUSED(varray)) const
/** \name #GVArrayImpl_For_GSpan
* \{ */
-GVArrayImpl_For_GSpan::GVArrayImpl_For_GSpan(const GMutableSpan span)
- : GVMutableArrayImpl(span.type(), span.size()),
- data_(span.data()),
- element_size_(span.type().size())
-{
-}
-
-GVArrayImpl_For_GSpan::GVArrayImpl_For_GSpan(const CPPType &type, const int64_t size)
- : GVMutableArrayImpl(type, size), element_size_(type.size())
-{
-}
-
void GVArrayImpl_For_GSpan::get(const int64_t index, void *r_value) const
{
type_->copy_assign(POINTER_OFFSET(data_, element_size_ * index), r_value);
@@ -209,17 +192,6 @@ void GVArrayImpl_For_GSpan::materialize_compressed_to_uninitialized(const IndexM
type_->copy_construct_compressed(data_, dst, mask);
}
-class GVArrayImpl_For_GSpan_final final : public GVArrayImpl_For_GSpan {
- public:
- using GVArrayImpl_For_GSpan::GVArrayImpl_For_GSpan;
-
- private:
- bool may_have_ownership() const override
- {
- return false;
- }
-};
-
/** \} */
/* -------------------------------------------------------------------- */
@@ -227,79 +199,56 @@ class GVArrayImpl_For_GSpan_final final : public GVArrayImpl_For_GSpan {
* \{ */
/* Generic virtual array where each element has the same value. The value is not owned. */
-class GVArrayImpl_For_SingleValueRef : public GVArrayImpl {
- protected:
- const void *value_ = nullptr;
- public:
- GVArrayImpl_For_SingleValueRef(const CPPType &type, const int64_t size, const void *value)
- : GVArrayImpl(type, size), value_(value)
- {
- }
-
- protected:
- GVArrayImpl_For_SingleValueRef(const CPPType &type, const int64_t size) : GVArrayImpl(type, size)
- {
- }
-
- void get(const int64_t UNUSED(index), void *r_value) const override
- {
- type_->copy_assign(value_, r_value);
- }
- void get_to_uninitialized(const int64_t UNUSED(index), void *r_value) const override
- {
- type_->copy_construct(value_, r_value);
- }
-
- bool is_span() const override
- {
- return size_ == 1;
- }
- GSpan get_internal_span() const override
- {
- return GSpan{*type_, value_, 1};
- }
-
- bool is_single() const override
- {
- return true;
- }
- void get_internal_single(void *r_value) const override
- {
- type_->copy_assign(value_, r_value);
- }
+void GVArrayImpl_For_SingleValueRef::get(const int64_t UNUSED(index), void *r_value) const
+{
+ type_->copy_assign(value_, r_value);
+}
+void GVArrayImpl_For_SingleValueRef::get_to_uninitialized(const int64_t UNUSED(index),
+ void *r_value) const
+{
+ type_->copy_construct(value_, r_value);
+}
- void materialize(const IndexMask mask, void *dst) const override
- {
- type_->fill_assign_indices(value_, dst, mask);
- }
+bool GVArrayImpl_For_SingleValueRef::is_span() const
+{
+ return size_ == 1;
+}
+GSpan GVArrayImpl_For_SingleValueRef::get_internal_span() const
+{
+ return GSpan{*type_, value_, 1};
+}
- void materialize_to_uninitialized(const IndexMask mask, void *dst) const override
- {
- type_->fill_construct_indices(value_, dst, mask);
- }
+bool GVArrayImpl_For_SingleValueRef::is_single() const
+{
+ return true;
+}
+void GVArrayImpl_For_SingleValueRef::get_internal_single(void *r_value) const
+{
+ type_->copy_assign(value_, r_value);
+}
- void materialize_compressed(const IndexMask mask, void *dst) const override
- {
- type_->fill_assign_n(value_, dst, mask.size());
- }
+void GVArrayImpl_For_SingleValueRef::materialize(const IndexMask mask, void *dst) const
+{
+ type_->fill_assign_indices(value_, dst, mask);
+}
- void materialize_compressed_to_uninitialized(const IndexMask mask, void *dst) const override
- {
- type_->fill_construct_n(value_, dst, mask.size());
- }
-};
+void GVArrayImpl_For_SingleValueRef::materialize_to_uninitialized(const IndexMask mask,
+ void *dst) const
+{
+ type_->fill_construct_indices(value_, dst, mask);
+}
-class GVArrayImpl_For_SingleValueRef_final final : public GVArrayImpl_For_SingleValueRef {
- public:
- using GVArrayImpl_For_SingleValueRef::GVArrayImpl_For_SingleValueRef;
+void GVArrayImpl_For_SingleValueRef::materialize_compressed(const IndexMask mask, void *dst) const
+{
+ type_->fill_assign_n(value_, dst, mask.size());
+}
- private:
- bool may_have_ownership() const override
- {
- return false;
- }
-};
+void GVArrayImpl_For_SingleValueRef::materialize_compressed_to_uninitialized(const IndexMask mask,
+ void *dst) const
+{
+ type_->fill_construct_n(value_, dst, mask.size());
+}
/** \} */
@@ -529,8 +478,6 @@ class GVArrayImpl_For_SlicedGVArray : public GVArrayImpl {
/** \name #GVArrayCommon
* \{ */
-GVArrayCommon::GVArrayCommon() = default;
-
GVArrayCommon::GVArrayCommon(const GVArrayCommon &other) : storage_(other.storage_)
{
impl_ = this->impl_from_storage();
@@ -672,17 +619,27 @@ GVArray::GVArray(std::shared_ptr<const GVArrayImpl> impl) : GVArrayCommon(std::m
{
}
-GVArray GVArray::ForSingle(const CPPType &type, const int64_t size, const void *value)
+GVArray::GVArray(varray_tag::single /* tag */,
+ const CPPType &type,
+ int64_t size,
+ const void *value)
{
if (type.is_trivial() && type.size() <= 16 && type.alignment() <= 8) {
- return GVArray::For<GVArrayImpl_For_SmallTrivialSingleValue<16>>(type, size, value);
+ this->emplace<GVArrayImpl_For_SmallTrivialSingleValue<16>>(type, size, value);
}
- return GVArray::For<GVArrayImpl_For_SingleValue>(type, size, value);
+ else {
+ this->emplace<GVArrayImpl_For_SingleValue>(type, size, value);
+ }
+}
+
+GVArray GVArray::ForSingle(const CPPType &type, const int64_t size, const void *value)
+{
+ return GVArray(varray_tag::single{}, type, size, value);
}
GVArray GVArray::ForSingleRef(const CPPType &type, const int64_t size, const void *value)
{
- return GVArray::For<GVArrayImpl_For_SingleValueRef_final>(type, size, value);
+ return GVArray(varray_tag::single_ref{}, type, size, value);
}
GVArray GVArray::ForSingleDefault(const CPPType &type, const int64_t size)
@@ -692,10 +649,7 @@ GVArray GVArray::ForSingleDefault(const CPPType &type, const int64_t size)
GVArray GVArray::ForSpan(GSpan span)
{
- /* Use const-cast because the underlying virtual array implementation is shared between const
- * and non const data. */
- GMutableSpan mutable_span{span.type(), const_cast<void *>(span.data()), span.size()};
- return GVArray::For<GVArrayImpl_For_GSpan_final>(mutable_span);
+ return GVArray(varray_tag::span{}, span);
}
class GVArrayImpl_For_GArray : public GVArrayImpl_For_GSpan {
diff --git a/source/blender/functions/FN_multi_function_params.hh b/source/blender/functions/FN_multi_function_params.hh
index 9d09378ab63..16a33c9cda7 100644
--- a/source/blender/functions/FN_multi_function_params.hh
+++ b/source/blender/functions/FN_multi_function_params.hh
@@ -41,6 +41,10 @@ class MFParamsBuilder {
MFParamsBuilder(const MFSignature &signature, const IndexMask mask)
: signature_(&signature), mask_(mask), min_array_size_(mask.min_array_size())
{
+ virtual_arrays_.reserve(signature.virtual_array_num);
+ mutable_spans_.reserve(signature.span_num);
+ virtual_vector_arrays_.reserve(signature.virtual_vector_array_num);
+ vector_arrays_.reserve(signature.vector_array_num);
}
public:
@@ -53,28 +57,33 @@ class MFParamsBuilder {
template<typename T> void add_readonly_single_input_value(T value, StringRef expected_name = "")
{
- this->add_readonly_single_input(VArray<T>::ForSingle(std::move(value), min_array_size_),
- expected_name);
+ this->assert_current_param_type(MFParamType::ForSingleInput(CPPType::get<T>()), expected_name);
+ virtual_arrays_.append_unchecked_as(
+ varray_tag::single{}, CPPType::get<T>(), min_array_size_, &value);
}
template<typename T> void add_readonly_single_input(const T *value, StringRef expected_name = "")
{
- this->add_readonly_single_input(
- GVArray::ForSingleRef(CPPType::get<T>(), min_array_size_, value), expected_name);
+ this->assert_current_param_type(MFParamType::ForSingleInput(CPPType::get<T>()), expected_name);
+ virtual_arrays_.append_unchecked_as(
+ varray_tag::single_ref{}, CPPType::get<T>(), min_array_size_, value);
}
void add_readonly_single_input(const GSpan span, StringRef expected_name = "")
{
- this->add_readonly_single_input(GVArray::ForSpan(span), expected_name);
+ this->assert_current_param_type(MFParamType::ForSingleInput(span.type()), expected_name);
+ BLI_assert(span.size() >= min_array_size_);
+ virtual_arrays_.append_unchecked_as(varray_tag::span{}, span);
}
void add_readonly_single_input(GPointer value, StringRef expected_name = "")
{
- this->add_readonly_single_input(
- GVArray::ForSingleRef(*value.type(), min_array_size_, value.get()), expected_name);
+ this->assert_current_param_type(MFParamType::ForSingleInput(*value.type()), expected_name);
+ virtual_arrays_.append_unchecked_as(
+ varray_tag::single_ref{}, *value.type(), min_array_size_, value.get());
}
void add_readonly_single_input(GVArray varray, StringRef expected_name = "")
{
this->assert_current_param_type(MFParamType::ForSingleInput(varray.type()), expected_name);
BLI_assert(varray.size() >= min_array_size_);
- virtual_arrays_.append(varray);
+ virtual_arrays_.append_unchecked_as(std::move(varray));
}
void add_readonly_vector_input(const GVectorArray &vector_array, StringRef expected_name = "")
@@ -92,7 +101,7 @@ class MFParamsBuilder {
{
this->assert_current_param_type(MFParamType::ForVectorInput(ref.type()), expected_name);
BLI_assert(ref.size() >= min_array_size_);
- virtual_vector_arrays_.append(&ref);
+ virtual_vector_arrays_.append_unchecked(&ref);
}
template<typename T> void add_uninitialized_single_output(T *value, StringRef expected_name = "")
@@ -104,7 +113,7 @@ class MFParamsBuilder {
{
this->assert_current_param_type(MFParamType::ForSingleOutput(ref.type()), expected_name);
BLI_assert(ref.size() >= min_array_size_);
- mutable_spans_.append(ref);
+ mutable_spans_.append_unchecked(ref);
}
void add_ignored_single_output(StringRef expected_name = "")
{
@@ -115,7 +124,7 @@ class MFParamsBuilder {
const CPPType &type = param_type.data_type().single_type();
/* An empty span indicates that this is ignored. */
const GMutableSpan dummy_span{type};
- mutable_spans_.append(dummy_span);
+ mutable_spans_.append_unchecked(dummy_span);
}
void add_vector_output(GVectorArray &vector_array, StringRef expected_name = "")
@@ -123,14 +132,14 @@ class MFParamsBuilder {
this->assert_current_param_type(MFParamType::ForVectorOutput(vector_array.type()),
expected_name);
BLI_assert(vector_array.size() >= min_array_size_);
- vector_arrays_.append(&vector_array);
+ vector_arrays_.append_unchecked(&vector_array);
}
void add_single_mutable(GMutableSpan ref, StringRef expected_name = "")
{
this->assert_current_param_type(MFParamType::ForMutableSingle(ref.type()), expected_name);
BLI_assert(ref.size() >= min_array_size_);
- mutable_spans_.append(ref);
+ mutable_spans_.append_unchecked(ref);
}
void add_vector_mutable(GVectorArray &vector_array, StringRef expected_name = "")
@@ -138,7 +147,7 @@ class MFParamsBuilder {
this->assert_current_param_type(MFParamType::ForMutableVector(vector_array.type()),
expected_name);
BLI_assert(vector_array.size() >= min_array_size_);
- vector_arrays_.append(&vector_array);
+ vector_arrays_.append_unchecked(&vector_array);
}
GMutableSpan computed_array(int param_index)
diff --git a/source/blender/functions/FN_multi_function_signature.hh b/source/blender/functions/FN_multi_function_signature.hh
index 62c491609a4..6181555dbd1 100644
--- a/source/blender/functions/FN_multi_function_signature.hh
+++ b/source/blender/functions/FN_multi_function_signature.hh
@@ -29,6 +29,15 @@ struct MFSignature {
Vector<int> param_data_indices;
bool depends_on_context = false;
+ /**
+ * Number of elements of each of these types that has to be passed into the multi-function as an
+ * input or output.
+ */
+ int span_num = 0;
+ int virtual_array_num = 0;
+ int virtual_vector_array_num = 0;
+ int vector_array_num = 0;
+
int data_index(int param_index) const
{
return param_data_indices[param_index];
@@ -38,10 +47,6 @@ struct MFSignature {
class MFSignatureBuilder {
private:
MFSignature signature_;
- int span_count_ = 0;
- int virtual_array_count_ = 0;
- int virtual_vector_array_count_ = 0;
- int vector_array_count_ = 0;
public:
MFSignatureBuilder(const char *function_name)
@@ -79,10 +84,10 @@ class MFSignatureBuilder {
switch (data_type.category()) {
case MFDataType::Single:
- signature_.param_data_indices.append(virtual_array_count_++);
+ signature_.param_data_indices.append(signature_.virtual_array_num++);
break;
case MFDataType::Vector:
- signature_.param_data_indices.append(virtual_vector_array_count_++);
+ signature_.param_data_indices.append(signature_.virtual_vector_array_num++);
break;
}
}
@@ -112,10 +117,10 @@ class MFSignatureBuilder {
switch (data_type.category()) {
case MFDataType::Single:
- signature_.param_data_indices.append(span_count_++);
+ signature_.param_data_indices.append(signature_.span_num++);
break;
case MFDataType::Vector:
- signature_.param_data_indices.append(vector_array_count_++);
+ signature_.param_data_indices.append(signature_.vector_array_num++);
break;
}
}
@@ -145,10 +150,10 @@ class MFSignatureBuilder {
switch (data_type.category()) {
case MFDataType::Single:
- signature_.param_data_indices.append(span_count_++);
+ signature_.param_data_indices.append(signature_.span_num++);
break;
case MFDataType::Vector:
- signature_.param_data_indices.append(vector_array_count_++);
+ signature_.param_data_indices.append(signature_.vector_array_num++);
break;
}
}