Commit: 2a8afc142f72785a5ef27f5d8cc2a7d21799be4b Author: Jacques Lucke Date: Sat Jun 25 17:28:49 2022 +0200 Branches: master https://developer.blender.org/rB2a8afc142f72785a5ef27f5d8cc2a7d21799be4b
BLI: improve check for common virtual array implementations This reduces the amount of code, and improves performance a bit by doing more with less virtual method calls. Differential Revision: https://developer.blender.org/D15293 =================================================================== M source/blender/blenlib/BLI_generic_virtual_array.hh M source/blender/blenlib/BLI_virtual_array.hh M source/blender/blenlib/intern/generic_virtual_array.cc =================================================================== diff --git a/source/blender/blenlib/BLI_generic_virtual_array.hh b/source/blender/blenlib/BLI_generic_virtual_array.hh index 985d914f4a4..b4bd337805f 100644 --- a/source/blender/blenlib/BLI_generic_virtual_array.hh +++ b/source/blender/blenlib/BLI_generic_virtual_array.hh @@ -42,11 +42,7 @@ class GVArrayImpl { virtual void get(int64_t index, void *r_value) const; virtual void get_to_uninitialized(int64_t index, void *r_value) const = 0; - virtual bool is_span() const; - virtual GSpan get_internal_span() const; - - virtual bool is_single() const; - virtual void get_internal_single(void *UNUSED(r_value)) const; + 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; @@ -55,7 +51,6 @@ class GVArrayImpl { virtual void materialize_compressed_to_uninitialized(IndexMask mask, void *dst) const; virtual bool try_assign_VArray(void *varray) const; - virtual bool may_have_ownership() const; }; /* A generic version of #VMutableArrayImpl. */ @@ -141,6 +136,8 @@ class GVArrayCommon { void materialize_compressed(IndexMask mask, void *dst) const; void materialize_compressed_to_uninitialized(IndexMask mask, void *dst) const; + CommonVArrayInfo common_info() const; + /** * Returns true when the virtual array is stored as a span internally. */ @@ -275,7 +272,7 @@ class GVArray_GSpan : public GSpan { }; /* A generic version of VMutableArray_Span. */ -class GVMutableArray_GSpan : public GMutableSpan { +class GVMutableArray_GSpan : public GMutableSpan, NonCopyable, NonMovable { private: GVMutableArray varray_; void *owned_data_ = nullptr; @@ -318,26 +315,6 @@ template<typename T> class GVArrayImpl_For_VArray : public GVArrayImpl { new (r_value) T(varray_[index]); } - bool is_span() const override - { - return varray_.is_span(); - } - - GSpan get_internal_span() const override - { - return GSpan(varray_.get_internal_span()); - } - - bool is_single() const override - { - return varray_.is_single(); - } - - void get_internal_single(void *r_value) const override - { - *(T *)r_value = varray_.get_internal_single(); - } - void materialize(const IndexMask mask, void *dst) const override { varray_.materialize(mask, MutableSpan((T *)dst, mask.min_array_size())); @@ -364,9 +341,9 @@ template<typename T> class GVArrayImpl_For_VArray : public GVArrayImpl { return true; } - bool may_have_ownership() const override + CommonVArrayInfo common_info() const override { - return varray_.may_have_ownership(); + return varray_.common_info(); } }; @@ -390,26 +367,9 @@ template<typename T> class VArrayImpl_For_GVArray : public VArrayImpl<T> { return value; } - bool is_span() const override - { - return varray_.is_span(); - } - - Span<T> get_internal_span() const override + CommonVArrayInfo common_info() const override { - return varray_.get_internal_span().template typed<T>(); - } - - bool is_single() const override - { - return varray_.is_single(); - } - - T get_internal_single() const override - { - T value; - varray_.get_internal_single(&value); - return value; + return varray_.common_info(); } bool try_assign_GVArray(GVArray &varray) const override @@ -418,11 +378,6 @@ template<typename T> class VArrayImpl_For_GVArray : public VArrayImpl<T> { return true; } - bool may_have_ownership() const override - { - return varray_.may_have_ownership(); - } - void materialize(IndexMask mask, MutableSpan<T> r_span) const override { varray_.materialize(mask, r_span.data()); @@ -467,25 +422,9 @@ template<typename T> class GVMutableArrayImpl_For_VMutableArray : public GVMutab new (r_value) T(varray_[index]); } - bool is_span() const override - { - return varray_.is_span(); - } - - GSpan get_internal_span() const override + CommonVArrayInfo common_info() const override { - Span<T> span = varray_.get_internal_span(); - return span; - } - - bool is_single() const override - { - return varray_.is_single(); - } - - void get_internal_single(void *r_value) const override - { - *(T *)r_value = varray_.get_internal_single(); + return varray_.common_info(); } void set_by_copy(const int64_t index, const void *value) override @@ -543,11 +482,6 @@ template<typename T> class GVMutableArrayImpl_For_VMutableArray : public GVMutab *(VMutableArray<T> *)varray = varray_; return true; } - - bool may_have_ownership() const override - { - return varray_.may_have_ownership(); - } }; /* Used to convert an generic mutable virtual array into a typed one. */ @@ -576,26 +510,9 @@ template<typename T> class VMutableArrayImpl_For_GVMutableArray : public VMutabl varray_.set_by_relocate(index, &value); } - bool is_span() const override - { - return varray_.is_span(); - } - - Span<T> get_internal_span() const override - { - return varray_.get_internal_span().template typed<T>(); - } - - bool is_single() const override + CommonVArrayInfo common_info() const override { - return varray_.is_single(); - } - - T get_internal_single() const override - { - T value; - varray_.get_internal_single(&value); - return value; + return varray_.common_info(); } bool try_assign_GVArray(GVArray &varray) const override @@ -610,11 +527,6 @@ template<typename T> class VMutableArrayImpl_For_GVMutableArray : public VMutabl return true; } - bool may_have_ownership() const override - { - return varray_.may_have_ownership(); - } - void materialize(IndexMask mask, MutableSpan<T> r_span) const override { varray_.materialize(mask, r_span.data()); @@ -670,8 +582,7 @@ class GVArrayImpl_For_GSpan : public GVMutableArrayImpl { void set_by_move(int64_t index, void *value) override; void set_by_relocate(int64_t index, void *value) override; - bool is_span() const override; - GSpan get_internal_span() const override; + CommonVArrayInfo common_info() const override; virtual void materialize(const IndexMask mask, void *dst) const override; virtual void materialize_to_uninitialized(const IndexMask mask, void *dst) const override; @@ -686,10 +597,7 @@ class GVArrayImpl_For_GSpan_final final : public GVArrayImpl_For_GSpan { using GVArrayImpl_For_GSpan::GVArrayImpl_For_GSpan; private: - bool may_have_ownership() const override - { - return false; - } + CommonVArrayInfo common_info() const override; }; /** \} */ @@ -715,10 +623,7 @@ 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; - 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; + 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; @@ -730,10 +635,7 @@ class GVArrayImpl_For_SingleValueRef_final final : public GVArrayImpl_For_Single using GVArrayImpl_For_SingleValueRef::GVArrayImpl_For_SingleValueRef; private: - bool may_have_ownership() const override - { - return false; - } + CommonVArrayInfo common_info() const override; }; /** \} */ @@ -859,6 +761,11 @@ inline GVArrayCommon::operator bool() const return impl_ != nullptr; } +inline CommonVArrayInfo GVArrayCommon::common_info() const +{ + return impl_->common_info(); +} + inline int64_t GVArrayCommon::size() const { if (impl_ == nullptr) { @@ -931,25 +838,20 @@ template<typename T> inline GVArray::GVArray(const VArray<T> &varray) if (!varray) { return; } - if (varray.try_assign_GVArray(*this)) { + const CommonVArrayInfo info = varray.common_info(); + if (info.type == CommonVArrayInfo::Type::Single) { + *this = GVArray::ForSingle(CPPType::get<T>(), varray.size(), info.data); return; } - if (varray.is_single()) { - T value = varray.get_internal_single(); - *this = GVArray::ForSingle(CPPType::get<T>(), varray.size(), &value); + /* Need to check for ownership, because otherwise the referenced data can be destructed when + * #this is destructed. */ + if (info.type == CommonVArrayInfo::Type::Span && !info.may_have_ownership) { + *this = GVArray::ForSpan(GSpan(CPPType::get<T>(), info.data, varray.size())); } - /* Need to check this before the span special case, because otherwise we might loose - * ownership to the referenced data when #varray goes out of scope. */ - else if (varray.may_have_ownership()) { - *this = GVArray::For<GVArrayImpl_For_VArray<T>>(varray); - } - else if (varray.is_span()) { - Span<T> data = varray.get_internal_span(); - *this = GVArray::ForSpan(data); - } - else { - *this = GVArray::For<GVArrayImpl_For_VArray<T>>(varray); + if (varray.try_assign_GVArray(*this)) { + return; } + *this = GVArray::For<GVArrayImpl_For_VArray<T>>(varray); } template<typename T> inline VArray<T> GVArray::typed() const @@ -958,22 +860,19 @@ template<typename T> inline VArray<T> GVArray::typed() const return {}; } BLI_assert(impl_->type().is<T>()); + const CommonVArrayInfo info = this->common_info(); + if (info.type == CommonVArrayInfo::Type::Single) { + return VArray<T>::ForSingle(*static_cast<const T *>(info.data), this->size()); + } + /* Need to check for ownership, because otherwise the referenced data can be destructed when + * #this is destructed. */ + if (info.type == CommonVArrayInfo::Type::Span && !info.may_have_ownership) { + return VArray<T>::ForSpan(Span<T>(static_cast<const T *>(info.data), this->size())); + } VArray<T> varray; if (this->try_assign_VArray(varray)) { return varray; } - if (this->is_single()) { - T value; - this->get_internal_single(&value); - return VArray<T>::ForSi @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs