diff --git a/source/blender/blenkernel/intern/deform.cc b/source/blender/blenkernel/intern/deform.cc index 144e924cd2d..898c18c40e8 100644 --- a/source/blender/blenkernel/intern/deform.cc +++ b/source/blender/blenkernel/intern/deform.cc @@ -1700,7 +1700,9 @@ class VArrayImpl_For_VertexWeights final : public VMutableArrayImpl { }); } - void materialize(const IndexMask &mask, float *dst) const override + void materialize(const IndexMask &mask, + float *dst, + const bool /*dst_is_uninitialized*/) const override { if (dverts_ == nullptr) { mask.foreach_index([&](const int i) { dst[i] = 0.0f; }); @@ -1717,11 +1719,6 @@ class VArrayImpl_For_VertexWeights final : public VMutableArrayImpl { }); } - void materialize_to_uninitialized(const IndexMask &mask, float *dst) const override - { - this->materialize(mask, dst); - } - private: MDeformWeight *find_weight_at_index(const int64_t index) { diff --git a/source/blender/blenkernel/intern/type_conversions.cc b/source/blender/blenkernel/intern/type_conversions.cc index f51c8230c7b..c8861c032b8 100644 --- a/source/blender/blenkernel/intern/type_conversions.cc +++ b/source/blender/blenkernel/intern/type_conversions.cc @@ -751,14 +751,13 @@ class GVArray_For_ConvertedGVArray : public GVArrayImpl { from_type_.destruct(buffer); } - void materialize(const IndexMask &mask, void *dst) const override - { - type_->destruct_n(dst, mask.min_array_size()); - this->materialize_to_uninitialized(mask, dst); - } - - void materialize_to_uninitialized(const IndexMask &mask, void *dst) const override + void materialize(const IndexMask &mask, + void *dst, + const bool dst_is_uninitialized) const override { + if (!dst_is_uninitialized) { + type_->destruct_n(dst, mask.min_array_size()); + } call_convert_to_uninitialized_fn(varray_, *old_to_new_conversions_.multi_function, mask, @@ -809,14 +808,13 @@ class GVMutableArray_For_ConvertedGVMutableArray : public GVMutableArrayImpl { varray_.set_by_relocate(index, buffer); } - void materialize(const IndexMask &mask, void *dst) const override - { - type_->destruct_n(dst, mask.min_array_size()); - this->materialize_to_uninitialized(mask, dst); - } - - void materialize_to_uninitialized(const IndexMask &mask, void *dst) const override + void materialize(const IndexMask &mask, + void *dst, + const bool dst_is_uninitialized) const override { + if (!dst_is_uninitialized) { + type_->destruct_n(dst, mask.min_array_size()); + } call_convert_to_uninitialized_fn(varray_, *old_to_new_conversions_.multi_function, mask, diff --git a/source/blender/blenlib/BLI_generic_virtual_array.hh b/source/blender/blenlib/BLI_generic_virtual_array.hh index 3cf0dcb9b4f..568aa93164c 100644 --- a/source/blender/blenlib/BLI_generic_virtual_array.hh +++ b/source/blender/blenlib/BLI_generic_virtual_array.hh @@ -45,11 +45,10 @@ class GVArrayImpl { virtual CommonVArrayInfo common_info() const; - virtual void materialize(const IndexMask &mask, void *dst) const; - virtual void materialize_to_uninitialized(const IndexMask &mask, void *dst) const; - - virtual void materialize_compressed(const IndexMask &mask, void *dst) const; - virtual void materialize_compressed_to_uninitialized(const IndexMask &mask, void *dst) const; + virtual void materialize(const IndexMask &mask, void *dst, bool dst_is_uninitialized) const; + virtual void materialize_compressed(const IndexMask &mask, + void *dst, + bool dst_is_uninitialized) const; virtual bool try_assign_VArray(void *varray) const; }; @@ -323,26 +322,19 @@ template class GVArrayImpl_For_VArray : public GVArrayImpl { new (r_value) T(varray_[index]); } - void materialize(const IndexMask &mask, void *dst) const override + void materialize(const IndexMask &mask, + void *dst, + const bool dst_is_uninitialized) const override { - varray_.materialize(mask, MutableSpan(static_cast(dst), mask.min_array_size())); + varray_.get_implementation()->materialize(mask, static_cast(dst), dst_is_uninitialized); } - void materialize_to_uninitialized(const IndexMask &mask, void *dst) const override + void materialize_compressed(const IndexMask &mask, + void *dst, + const bool dst_is_uninitialized) const override { - varray_.materialize_to_uninitialized( - mask, MutableSpan(static_cast(dst), mask.min_array_size())); - } - - void materialize_compressed(const IndexMask &mask, void *dst) const override - { - varray_.materialize_compressed(mask, MutableSpan(static_cast(dst), mask.size())); - } - - void materialize_compressed_to_uninitialized(const IndexMask &mask, void *dst) const override - { - varray_.materialize_compressed_to_uninitialized( - mask, MutableSpan(static_cast(dst), mask.size())); + varray_.get_implementation()->materialize_compressed( + mask, static_cast(dst), dst_is_uninitialized); } bool try_assign_VArray(void *varray) const override @@ -388,24 +380,16 @@ template class VArrayImpl_For_GVArray : public VArrayImpl { return true; } - void materialize(const IndexMask &mask, T *dst) const override + void materialize(const IndexMask &mask, T *dst, const bool dst_is_uninitialized) const override { - varray_.materialize(mask, dst); + varray_.get_implementation()->materialize(mask, dst, dst_is_uninitialized); } - void materialize_to_uninitialized(const IndexMask &mask, T *dst) const override + void materialize_compressed(const IndexMask &mask, + T *dst, + const bool dst_is_uninitialized) const override { - varray_.materialize_to_uninitialized(mask, dst); - } - - void materialize_compressed(const IndexMask &mask, T *dst) const override - { - varray_.materialize_compressed(mask, dst); - } - - void materialize_compressed_to_uninitialized(const IndexMask &mask, T *dst) const override - { - varray_.materialize_compressed_to_uninitialized(mask, dst); + varray_.get_implementation()->materialize_compressed(mask, dst, dst_is_uninitialized); } }; @@ -460,26 +444,19 @@ template class GVMutableArrayImpl_For_VMutableArray : public GVMutab varray_.set_all(Span(static_cast(src), size_)); } - void materialize(const IndexMask &mask, void *dst) const override + void materialize(const IndexMask &mask, + void *dst, + const bool dst_is_uninitialized) const override { - varray_.materialize(mask, MutableSpan(static_cast(dst), mask.min_array_size())); + varray_.get_implementation()->materialize(mask, static_cast(dst), dst_is_uninitialized); } - void materialize_to_uninitialized(const IndexMask &mask, void *dst) const override + void materialize_compressed(const IndexMask &mask, + void *dst, + const bool dst_is_uninitialized) const override { - varray_.materialize_to_uninitialized( - mask, MutableSpan(static_cast(dst), mask.min_array_size())); - } - - void materialize_compressed(const IndexMask &mask, void *dst) const override - { - varray_.materialize_compressed(mask, MutableSpan(static_cast(dst), mask.size())); - } - - void materialize_compressed_to_uninitialized(const IndexMask &mask, void *dst) const override - { - varray_.materialize_compressed_to_uninitialized( - mask, MutableSpan(static_cast(dst), mask.size())); + varray_.get_implementation()->materialize_compressed( + mask, static_cast(dst), dst_is_uninitialized); } bool try_assign_VArray(void *varray) const override @@ -538,24 +515,16 @@ template class VMutableArrayImpl_For_GVMutableArray : public VMutabl return true; } - void materialize(const IndexMask &mask, T *dst) const override + void materialize(const IndexMask &mask, T *dst, const bool dst_is_uninitialized) const override { - varray_.materialize(mask, dst); + varray_.get_implementation()->materialize(mask, dst, dst_is_uninitialized); } - void materialize_to_uninitialized(const IndexMask &mask, T *dst) const override + void materialize_compressed(const IndexMask &mask, + T *dst, + const bool dst_is_uninitialized) const override { - varray_.materialize_to_uninitialized(mask, dst); - } - - void materialize_compressed(const IndexMask &mask, T *dst) const override - { - varray_.materialize_compressed(mask, dst); - } - - void materialize_compressed_to_uninitialized(const IndexMask &mask, T *dst) const override - { - varray_.materialize_compressed_to_uninitialized(mask, dst); + varray_.get_implementation()->materialize_compressed(mask, dst, dst_is_uninitialized); } }; @@ -594,11 +563,11 @@ class GVArrayImpl_For_GSpan : public GVMutableArrayImpl { CommonVArrayInfo common_info() const override; - void materialize(const IndexMask &mask, void *dst) const override; - void materialize_to_uninitialized(const IndexMask &mask, void *dst) const override; + void materialize(const IndexMask &mask, void *dst, bool dst_is_uninitialized) const override; - void materialize_compressed(const IndexMask &mask, void *dst) const override; - void materialize_compressed_to_uninitialized(const IndexMask &mask, void *dst) const override; + void materialize_compressed(const IndexMask &mask, + void *dst, + bool dst_is_uninitialized) const override; }; class GVArrayImpl_For_GSpan_final final : public GVArrayImpl_For_GSpan { @@ -635,10 +604,10 @@ class GVArrayImpl_For_SingleValueRef : public GVArrayImpl { void get(const int64_t index, void *r_value) const override; void get_to_uninitialized(const int64_t index, void *r_value) const override; CommonVArrayInfo common_info() 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; + void materialize(const IndexMask &mask, void *dst, bool dst_is_uninitialized) const override; + void materialize_compressed(const IndexMask &mask, + void *dst, + bool dst_is_uninitialized) const override; }; class GVArrayImpl_For_SingleValueRef_final final : public GVArrayImpl_For_SingleValueRef { diff --git a/source/blender/blenlib/BLI_virtual_array.hh b/source/blender/blenlib/BLI_virtual_array.hh index 9baa671aa83..5544db55aea 100644 --- a/source/blender/blenlib/BLI_virtual_array.hh +++ b/source/blender/blenlib/BLI_virtual_array.hh @@ -109,17 +109,19 @@ template class VArrayImpl { * Copy values from the virtual array into the provided span. The index of the value in the * virtual array is the same as the index in the span. */ - virtual void materialize(const IndexMask &mask, T *dst) const + virtual void materialize(const IndexMask &mask, T *dst, const bool dst_is_uninitialized) const { - mask.foreach_index([&](const int64_t i) { dst[i] = this->get(i); }); - } - - /** - * Same as #materialize but #r_span is expected to be uninitialized. - */ - virtual void materialize_to_uninitialized(const IndexMask &mask, T *dst) const - { - mask.foreach_index([&](const int64_t i) { new (dst + i) T(this->get(i)); }); + if constexpr (std::is_trivially_copyable_v) { + mask.foreach_index([&](const int64_t i) { dst[i] = this->get(i); }); + } + else { + if (dst_is_uninitialized) { + mask.foreach_index([&](const int64_t i) { new (dst + i) T(this->get(i)); }); + } + else { + mask.foreach_index([&](const int64_t i) { dst[i] = this->get(i); }); + } + } } /** @@ -127,18 +129,22 @@ template class VArrayImpl { * in virtual array is not the same as the index in the output span. Instead, the span is filled * without gaps. */ - virtual void materialize_compressed(const IndexMask &mask, T *dst) const + virtual void materialize_compressed(const IndexMask &mask, + T *dst, + const bool dst_is_uninitialized) const { - mask.foreach_index([&](const int64_t i, const int64_t pos) { dst[pos] = this->get(i); }); - } - - /** - * Same as #materialize_compressed but #r_span is expected to be uninitialized. - */ - virtual void materialize_compressed_to_uninitialized(const IndexMask &mask, T *dst) const - { - mask.foreach_index( - [&](const int64_t i, const int64_t pos) { new (dst + pos) T(this->get(i)); }); + if constexpr (std::is_trivially_copyable_v) { + mask.foreach_index([&](const int64_t i, const int64_t pos) { dst[pos] = this->get(i); }); + } + else { + if (dst_is_uninitialized) { + mask.foreach_index( + [&](const int64_t i, const int64_t pos) { new (dst + pos) T(this->get(i)); }); + } + else { + mask.foreach_index([&](const int64_t i, const int64_t pos) { dst[pos] = this->get(i); }); + } + } } /** @@ -222,26 +228,39 @@ template class VArrayImpl_For_Span : public VMutableArrayImpl { return CommonVArrayInfo(CommonVArrayInfo::Type::Span, true, data_); } - void materialize(const IndexMask &mask, T *dst) const override + void materialize(const IndexMask &mask, T *dst, const bool dst_is_uninitialized) const override { - mask.foreach_index_optimized([&](const int64_t i) { dst[i] = data_[i]; }); + if constexpr (std::is_trivially_copyable_v) { + mask.foreach_index_optimized([&](const int64_t i) { dst[i] = data_[i]; }); + } + else { + if (dst_is_uninitialized) { + mask.foreach_index_optimized([&](const int64_t i) { new (dst + i) T(data_[i]); }); + } + else { + mask.foreach_index_optimized([&](const int64_t i) { dst[i] = data_[i]; }); + } + } } - void materialize_to_uninitialized(const IndexMask &mask, T *dst) const override + void materialize_compressed(const IndexMask &mask, + T *dst, + const bool dst_is_uninitialized) const override { - mask.foreach_index_optimized([&](const int64_t i) { new (dst + i) T(data_[i]); }); - } - - void materialize_compressed(const IndexMask &mask, T *dst) const override - { - mask.foreach_index_optimized( - [&](const int64_t i, const int64_t pos) { dst[pos] = data_[i]; }); - } - - void materialize_compressed_to_uninitialized(const IndexMask &mask, T *dst) const override - { - mask.foreach_index_optimized( - [&](const int64_t i, const int64_t pos) { new (dst + pos) T(data_[i]); }); + if constexpr (std::is_trivially_copyable_v) { + mask.foreach_index_optimized( + [&](const int64_t i, const int64_t pos) { dst[pos] = data_[i]; }); + } + else { + if (dst_is_uninitialized) { + mask.foreach_index_optimized( + [&](const int64_t i, const int64_t pos) { new (dst + pos) T(data_[i]); }); + } + else { + mask.foreach_index_optimized( + [&](const int64_t i, const int64_t pos) { dst[pos] = data_[i]; }); + } + } } }; @@ -314,24 +333,36 @@ template class VArrayImpl_For_Single final : public VArrayImpl { return CommonVArrayInfo(CommonVArrayInfo::Type::Single, true, &value_); } - void materialize(const IndexMask &mask, T *dst) const override + void materialize(const IndexMask &mask, T *dst, const bool dst_is_uninitialized) const override { - mask.foreach_index([&](const int64_t i) { dst[i] = value_; }); + if constexpr (std::is_trivially_copyable_v) { + mask.foreach_index([&](const int64_t i) { dst[i] = value_; }); + } + else { + if (dst_is_uninitialized) { + mask.foreach_index([&](const int64_t i) { new (dst + i) T(value_); }); + } + else { + mask.foreach_index([&](const int64_t i) { dst[i] = value_; }); + } + } } - void materialize_to_uninitialized(const IndexMask &mask, T *dst) const override + void materialize_compressed(const IndexMask &mask, + T *dst, + const bool dst_is_uninitialized) const override { - mask.foreach_index([&](const int64_t i) { new (dst + i) T(value_); }); - } - - void materialize_compressed(const IndexMask &mask, T *dst) const override - { - initialized_fill_n(dst, mask.size(), value_); - } - - void materialize_compressed_to_uninitialized(const IndexMask &mask, T *dst) const override - { - uninitialized_fill_n(dst, mask.size(), value_); + if constexpr (std::is_trivially_copyable_v) { + initialized_fill_n(dst, mask.size(), value_); + } + else { + if (dst_is_uninitialized) { + uninitialized_fill_n(dst, mask.size(), value_); + } + else { + initialized_fill_n(dst, mask.size(), value_); + } + } } }; @@ -358,25 +389,37 @@ template class VArrayImpl_For_Func final : public return get_func_(index); } - void materialize(const IndexMask &mask, T *dst) const override + void materialize(const IndexMask &mask, T *dst, const bool dst_is_uninitialized) const override { - mask.foreach_index([&](const int64_t i) { dst[i] = get_func_(i); }); + if constexpr (std::is_trivially_copyable_v) { + mask.foreach_index([&](const int64_t i) { dst[i] = get_func_(i); }); + } + else { + if (dst_is_uninitialized) { + mask.foreach_index([&](const int64_t i) { new (dst + i) T(get_func_(i)); }); + } + else { + mask.foreach_index([&](const int64_t i) { dst[i] = get_func_(i); }); + } + } } - void materialize_to_uninitialized(const IndexMask &mask, T *dst) const override + void materialize_compressed(const IndexMask &mask, + T *dst, + const bool dst_is_uninitialized) const override { - mask.foreach_index([&](const int64_t i) { new (dst + i) T(get_func_(i)); }); - } - - void materialize_compressed(const IndexMask &mask, T *dst) const override - { - mask.foreach_index([&](const int64_t i, const int64_t pos) { dst[pos] = get_func_(i); }); - } - - void materialize_compressed_to_uninitialized(const IndexMask &mask, T *dst) const override - { - mask.foreach_index( - [&](const int64_t i, const int64_t pos) { new (dst + pos) T(get_func_(i)); }); + if constexpr (std::is_trivially_copyable_v) { + mask.foreach_index([&](const int64_t i, const int64_t pos) { dst[pos] = get_func_(i); }); + } + else { + if (dst_is_uninitialized) { + mask.foreach_index( + [&](const int64_t i, const int64_t pos) { new (dst + pos) T(get_func_(i)); }); + } + else { + mask.foreach_index([&](const int64_t i, const int64_t pos) { dst[pos] = get_func_(i); }); + } + } } }; @@ -414,27 +457,43 @@ class VArrayImpl_For_DerivedSpan final : public VMutableArrayImpl { SetFunc(data_[index], std::move(value)); } - void materialize(const IndexMask &mask, ElemT *dst) const override + void materialize(const IndexMask &mask, + ElemT *dst, + const bool dst_is_uninitialized) const override { - mask.foreach_index_optimized([&](const int64_t i) { dst[i] = GetFunc(data_[i]); }); + if constexpr (std::is_trivially_copyable_v) { + mask.foreach_index_optimized([&](const int64_t i) { dst[i] = GetFunc(data_[i]); }); + } + else { + if (dst_is_uninitialized) { + mask.foreach_index_optimized( + [&](const int64_t i) { new (dst + i) ElemT(GetFunc(data_[i])); }); + } + else { + mask.foreach_index_optimized( + [&](const int64_t i) { dst[i] = GetFunc(data_[i]); }); + } + } } - void materialize_to_uninitialized(const IndexMask &mask, ElemT *dst) const override + void materialize_compressed(const IndexMask &mask, + ElemT *dst, + const bool dst_is_uninitialized) const override { - mask.foreach_index_optimized( - [&](const int64_t i) { new (dst + i) ElemT(GetFunc(data_[i])); }); - } - - void materialize_compressed(const IndexMask &mask, ElemT *dst) const override - { - mask.foreach_index_optimized( - [&](const int64_t i, const int64_t pos) { dst[pos] = GetFunc(data_[i]); }); - } - - void materialize_compressed_to_uninitialized(const IndexMask &mask, ElemT *dst) const override - { - mask.foreach_index_optimized( - [&](const int64_t i, const int64_t pos) { new (dst + pos) ElemT(GetFunc(data_[i])); }); + if constexpr (std::is_trivially_copyable_v) { + mask.foreach_index_optimized( + [&](const int64_t i, const int64_t pos) { dst[pos] = GetFunc(data_[i]); }); + } + else { + if (dst_is_uninitialized) { + mask.foreach_index_optimized( + [&](const int64_t i, const int64_t pos) { new (dst + pos) ElemT(GetFunc(data_[i])); }); + } + else { + mask.foreach_index_optimized( + [&](const int64_t i, const int64_t pos) { dst[pos] = GetFunc(data_[i]); }); + } + } } }; @@ -738,7 +797,7 @@ template class VArrayCommon { void materialize(const IndexMask &mask, MutableSpan r_span) const { BLI_assert(mask.min_array_size() <= this->size()); - impl_->materialize(mask, r_span.data()); + impl_->materialize(mask, r_span.data(), false); } void materialize_to_uninitialized(MutableSpan r_span) const @@ -749,18 +808,18 @@ template class VArrayCommon { void materialize_to_uninitialized(const IndexMask &mask, MutableSpan r_span) const { BLI_assert(mask.min_array_size() <= this->size()); - impl_->materialize_to_uninitialized(mask, r_span.data()); + impl_->materialize(mask, r_span.data(), true); } /** Copy some elements of the virtual array into a span. */ void materialize_compressed(const IndexMask &mask, MutableSpan r_span) const { - impl_->materialize_compressed(mask, r_span.data()); + impl_->materialize_compressed(mask, r_span.data(), false); } void materialize_compressed_to_uninitialized(const IndexMask &mask, MutableSpan r_span) const { - impl_->materialize_compressed_to_uninitialized(mask, r_span.data()); + impl_->materialize_compressed(mask, r_span.data(), true); } /** See #GVArrayImpl::try_assign_GVArray. */ diff --git a/source/blender/blenlib/intern/generic_virtual_array.cc b/source/blender/blenlib/intern/generic_virtual_array.cc index f55a929298a..2711c829b6b 100644 --- a/source/blender/blenlib/intern/generic_virtual_array.cc +++ b/source/blender/blenlib/intern/generic_virtual_array.cc @@ -16,36 +16,40 @@ namespace blender { /** \name #GVArrayImpl * \{ */ -void GVArrayImpl::materialize(const IndexMask &mask, void *dst) const +void GVArrayImpl::materialize(const IndexMask &mask, + void *dst, + const bool dst_is_uninitialized) const { - mask.foreach_index_optimized([&](const int64_t i) { - void *elem_dst = POINTER_OFFSET(dst, type_->size * i); - this->get(i, elem_dst); - }); + if (dst_is_uninitialized) { + mask.foreach_index_optimized([&](const int64_t i) { + void *elem_dst = POINTER_OFFSET(dst, type_->size * i); + this->get_to_uninitialized(i, elem_dst); + }); + } + else { + mask.foreach_index_optimized([&](const int64_t i) { + void *elem_dst = POINTER_OFFSET(dst, type_->size * i); + this->get(i, elem_dst); + }); + } } -void GVArrayImpl::materialize_to_uninitialized(const IndexMask &mask, void *dst) const +void GVArrayImpl::materialize_compressed(const IndexMask &mask, + void *dst, + const bool dst_is_uninitialized) const { - mask.foreach_index_optimized([&](const int64_t i) { - void *elem_dst = POINTER_OFFSET(dst, type_->size * i); - this->get_to_uninitialized(i, elem_dst); - }); -} - -void GVArrayImpl::materialize_compressed(const IndexMask &mask, void *dst) const -{ - mask.foreach_index_optimized([&](const int64_t i, const int64_t pos) { - void *elem_dst = POINTER_OFFSET(dst, type_->size * pos); - this->get(i, elem_dst); - }); -} - -void GVArrayImpl::materialize_compressed_to_uninitialized(const IndexMask &mask, void *dst) const -{ - mask.foreach_index_optimized([&](const int64_t i, const int64_t pos) { - void *elem_dst = POINTER_OFFSET(dst, type_->size * pos); - this->get_to_uninitialized(i, elem_dst); - }); + if (dst_is_uninitialized) { + mask.foreach_index_optimized([&](const int64_t i, const int64_t pos) { + void *elem_dst = POINTER_OFFSET(dst, type_->size * pos); + this->get_to_uninitialized(i, elem_dst); + }); + } + else { + mask.foreach_index_optimized([&](const int64_t i, const int64_t pos) { + void *elem_dst = POINTER_OFFSET(dst, type_->size * pos); + this->get(i, elem_dst); + }); + } } void GVArrayImpl::get(const int64_t index, void *r_value) const @@ -151,25 +155,28 @@ CommonVArrayInfo GVArrayImpl_For_GSpan::common_info() const return CommonVArrayInfo{CommonVArrayInfo::Type::Span, true, data_}; } -void GVArrayImpl_For_GSpan::materialize(const IndexMask &mask, void *dst) const +void GVArrayImpl_For_GSpan::materialize(const IndexMask &mask, + void *dst, + const bool dst_is_uninitialized) const { - type_->copy_assign_indices(data_, dst, mask); + if (dst_is_uninitialized) { + type_->copy_construct_indices(data_, dst, mask); + } + else { + type_->copy_assign_indices(data_, dst, mask); + } } -void GVArrayImpl_For_GSpan::materialize_to_uninitialized(const IndexMask &mask, void *dst) const +void GVArrayImpl_For_GSpan::materialize_compressed(const IndexMask &mask, + void *dst, + const bool dst_is_uninitialized) const { - type_->copy_construct_indices(data_, dst, mask); -} - -void GVArrayImpl_For_GSpan::materialize_compressed(const IndexMask &mask, void *dst) const -{ - type_->copy_assign_compressed(data_, dst, mask); -} - -void GVArrayImpl_For_GSpan::materialize_compressed_to_uninitialized(const IndexMask &mask, - void *dst) const -{ - type_->copy_construct_compressed(data_, dst, mask); + if (dst_is_uninitialized) { + type_->copy_construct_compressed(data_, dst, mask); + } + else { + type_->copy_assign_compressed(data_, dst, mask); + } } /** \} */ @@ -195,26 +202,28 @@ CommonVArrayInfo GVArrayImpl_For_SingleValueRef::common_info() const return CommonVArrayInfo{CommonVArrayInfo::Type::Single, true, value_}; } -void GVArrayImpl_For_SingleValueRef::materialize(const IndexMask &mask, void *dst) const +void GVArrayImpl_For_SingleValueRef::materialize(const IndexMask &mask, + void *dst, + const bool dst_is_uninitialized) const { - type_->fill_assign_indices(value_, dst, mask); + if (dst_is_uninitialized) { + type_->fill_construct_indices(value_, dst, mask); + } + else { + type_->fill_assign_indices(value_, dst, mask); + } } -void GVArrayImpl_For_SingleValueRef::materialize_to_uninitialized(const IndexMask &mask, - void *dst) const +void GVArrayImpl_For_SingleValueRef::materialize_compressed(const IndexMask &mask, + void *dst, + const bool dst_is_uninitialized) const { - type_->fill_construct_indices(value_, dst, mask); -} - -void GVArrayImpl_For_SingleValueRef::materialize_compressed(const IndexMask &mask, void *dst) const -{ - type_->fill_assign_n(value_, dst, mask.size()); -} - -void GVArrayImpl_For_SingleValueRef::materialize_compressed_to_uninitialized(const IndexMask &mask, - void *dst) const -{ - type_->fill_construct_n(value_, dst, mask.size()); + if (dst_is_uninitialized) { + type_->fill_construct_n(value_, dst, mask.size()); + } + else { + type_->fill_assign_n(value_, dst, mask.size()); + } } /** \} */ @@ -278,19 +287,16 @@ template class GVArrayImpl_For_SmallTrivialSingleValue : public memcpy(r_value, &buffer_, type_->size); } - void materialize(const IndexMask &mask, void *dst) const final - { - this->materialize_to_uninitialized(mask, dst); - } - void materialize_to_uninitialized(const IndexMask &mask, void *dst) const final + void materialize(const IndexMask &mask, + void *dst, + const bool /*dst_is_uninitialized*/) const final { type_->fill_construct_indices(buffer_, dst, mask); } - void materialize_compressed(const IndexMask &mask, void *dst) const final - { - this->materialize_compressed_to_uninitialized(mask, dst); - } - void materialize_compressed_to_uninitialized(const IndexMask &mask, void *dst) const final + + void materialize_compressed(const IndexMask &mask, + void *dst, + const bool /*dst_is_uninitialized*/) const final { type_->fill_construct_n(buffer_, dst, mask.size()); } @@ -515,31 +521,21 @@ class GVArrayImpl_For_SlicedGVArray : public GVArrayImpl { return {}; } - void materialize(const IndexMask &mask, void *dst) const final + void materialize(const IndexMask &mask, void *dst, const bool dst_is_uninitialized) const final { IndexMaskMemory memory; const IndexMask shifted_mask = mask.shift(offset_, memory); void *shifted_dst = POINTER_OFFSET(dst, -offset_ * type_->size); - varray_.materialize(shifted_mask, shifted_dst); + varray_.get_implementation()->materialize(shifted_mask, shifted_dst, dst_is_uninitialized); } - void materialize_to_uninitialized(const IndexMask &mask, void *dst) const final + + void materialize_compressed(const IndexMask &mask, + void *dst, + const bool dst_is_uninitialized) const final { IndexMaskMemory memory; const IndexMask shifted_mask = mask.shift(offset_, memory); - void *shifted_dst = POINTER_OFFSET(dst, -offset_ * type_->size); - varray_.materialize_to_uninitialized(shifted_mask, shifted_dst); - } - void materialize_compressed(const IndexMask &mask, void *dst) const final - { - IndexMaskMemory memory; - const IndexMask shifted_mask = mask.shift(offset_, memory); - varray_.materialize_compressed(shifted_mask, dst); - } - void materialize_compressed_to_uninitialized(const IndexMask &mask, void *dst) const override - { - IndexMaskMemory memory; - const IndexMask shifted_mask = mask.shift(offset_, memory); - varray_.materialize_compressed_to_uninitialized(shifted_mask, dst); + varray_.get_implementation()->materialize_compressed(shifted_mask, dst, dst_is_uninitialized); } }; @@ -582,7 +578,7 @@ void GVArrayCommon::materialize(void *dst) const void GVArrayCommon::materialize(const IndexMask &mask, void *dst) const { - impl_->materialize(mask, dst); + impl_->materialize(mask, dst, false); } void GVArrayCommon::materialize_to_uninitialized(void *dst) const @@ -593,17 +589,17 @@ void GVArrayCommon::materialize_to_uninitialized(void *dst) const void GVArrayCommon::materialize_to_uninitialized(const IndexMask &mask, void *dst) const { BLI_assert(mask.min_array_size() <= impl_->size()); - impl_->materialize_to_uninitialized(mask, dst); + impl_->materialize(mask, dst, true); } void GVArrayCommon::materialize_compressed(const IndexMask &mask, void *dst) const { - impl_->materialize_compressed(mask, dst); + impl_->materialize_compressed(mask, dst, false); } void GVArrayCommon::materialize_compressed_to_uninitialized(const IndexMask &mask, void *dst) const { - impl_->materialize_compressed_to_uninitialized(mask, dst); + impl_->materialize_compressed(mask, dst, true); } void GVArrayCommon::copy_from(const GVArrayCommon &other) diff --git a/source/blender/functions/FN_multi_function_builder.hh b/source/blender/functions/FN_multi_function_builder.hh index fdad301aae6..b56af63b1f4 100644 --- a/source/blender/functions/FN_multi_function_builder.hh +++ b/source/blender/functions/FN_multi_function_builder.hh @@ -301,7 +301,7 @@ inline void execute_materialized(TypeSequence /*param_tags*/, } /* As a fallback, do a virtual function call to retrieve all elements in the current * chunk. The elements are stored in a temporary buffer reused for every chunk. */ - varray_impl.materialize_compressed_to_uninitialized(*current_segment_mask, tmp_buffer); + varray_impl.materialize_compressed(*current_segment_mask, tmp_buffer, true); /* Remember that this parameter has been materialized, so that the values are * destructed properly when the chunk is done. */ arg_info.mode = MaterializeArgMode::Materialized;