[Bf-blender-cvs] [2a8afc142f7] master: BLI: improve check for common virtual array implementations

Jacques Lucke noreply at git.blender.org
Sat Jun 25 17:29:04 CEST 2022


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. @@



More information about the Bf-blender-cvs mailing list