[Bf-blender-cvs] [40e9cf9df89] functions: initial new attributes block storage

Jacques Lucke noreply at git.blender.org
Mon Sep 9 15:44:54 CEST 2019


Commit: 40e9cf9df8973cf7e255dd9ab3b61244e04db7ea
Author: Jacques Lucke
Date:   Mon Sep 9 15:43:23 2019 +0200
Branches: functions
https://developer.blender.org/rB40e9cf9df8973cf7e255dd9ab3b61244e04db7ea

initial new attributes block storage

===================================================================

A	source/blender/blenkernel/BKE_attributes_block.hpp
A	source/blender/blenkernel/BKE_attributes_block_container.hpp
M	source/blender/blenkernel/BKE_attributes_ref.hpp
M	source/blender/blenkernel/CMakeLists.txt
A	source/blender/blenkernel/intern/attributes_block.cpp
A	source/blender/blenkernel/intern/attributes_block_container.cpp
M	source/blender/blenkernel/intern/attributes_ref.cpp
M	source/blender/blenlib/BLI_map.hpp
M	source/blender/simulations/CMakeLists.txt
M	source/blender/simulations/bparticles/c_wrapper.cpp
M	source/blender/simulations/bparticles/particle_allocator.cpp
M	source/blender/simulations/bparticles/particle_allocator.hpp
D	source/blender/simulations/bparticles/particles_container.cpp
D	source/blender/simulations/bparticles/particles_container.hpp
M	source/blender/simulations/bparticles/particles_state.cpp
M	source/blender/simulations/bparticles/particles_state.hpp
M	source/blender/simulations/bparticles/simulate.cpp

===================================================================

diff --git a/source/blender/blenkernel/BKE_attributes_block.hpp b/source/blender/blenkernel/BKE_attributes_block.hpp
new file mode 100644
index 00000000000..7625603e861
--- /dev/null
+++ b/source/blender/blenkernel/BKE_attributes_block.hpp
@@ -0,0 +1,78 @@
+#pragma once
+
+#include "BKE_attributes_ref.hpp"
+#include "BLI_utility_mixins.hpp"
+
+namespace BKE {
+
+class AttributesBlockContainer;
+
+class AttributesBlock : BLI::NonCopyable, BLI::NonMovable {
+ private:
+  const AttributesInfo *m_attributes_info;
+  Vector<void *> m_buffers;
+  uint m_size;
+  uint m_capacity;
+  AttributesBlockContainer *m_owner;
+
+ public:
+  AttributesBlock(const AttributesInfo *attributes_info,
+                  uint capacity,
+                  AttributesBlockContainer &owner);
+  ~AttributesBlock();
+
+  void update_buffers(const AttributesInfo *new_info, const AttributesInfoDiff &info_diff);
+
+  uint size() const
+  {
+    return m_size;
+  }
+
+  uint capacity() const
+  {
+    return m_capacity;
+  }
+
+  uint remaining_capacity() const
+  {
+    return m_capacity - m_size;
+  }
+
+  IndexRange active_range() const
+  {
+    return IndexRange(m_size);
+  }
+
+  void set_size(uint new_size)
+  {
+    BLI_assert(new_size <= m_capacity);
+    m_size = new_size;
+  }
+
+  AttributesBlockContainer &owner()
+  {
+    return *m_owner;
+  }
+
+  void move(uint old_index, uint new_index);
+
+  static void MoveUntilFull(AttributesBlock &from, AttributesBlock &to);
+  static void Compress(MutableArrayRef<AttributesBlock *> blocks);
+
+  AttributesRef as_ref()
+  {
+    return AttributesRef(*this);
+  }
+
+  AttributesRef as_ref__all()
+  {
+    return AttributesRef(*m_attributes_info, m_buffers, m_capacity);
+  }
+
+  operator AttributesRef()
+  {
+    return AttributesRef(*m_attributes_info, m_buffers, m_size);
+  }
+};
+
+}  // namespace BKE
diff --git a/source/blender/blenkernel/BKE_attributes_block_container.hpp b/source/blender/blenkernel/BKE_attributes_block_container.hpp
new file mode 100644
index 00000000000..abe6a9d02ba
--- /dev/null
+++ b/source/blender/blenkernel/BKE_attributes_block_container.hpp
@@ -0,0 +1,61 @@
+#pragma once
+
+#include <mutex>
+#include <atomic>
+
+#include "BKE_attributes_block.hpp"
+
+namespace BKE {
+
+class AttributesBlockContainer : BLI::NonCopyable, BLI::NonMovable {
+ private:
+  std::unique_ptr<AttributesInfo> m_attributes_info;
+  uint m_block_size;
+  SetVector<AttributesBlock *> m_active_blocks;
+  std::mutex m_blocks_mutex;
+  std::atomic<uint> m_next_id;
+
+ public:
+  AttributesBlockContainer(std::unique_ptr<AttributesInfo> attributes_info, uint block_size);
+  ~AttributesBlockContainer();
+
+  uint count_active() const;
+
+  const AttributesInfo &attributes_info() const
+  {
+    return *m_attributes_info;
+  }
+
+  void update_attributes(std::unique_ptr<AttributesInfo> new_info);
+
+  AttributesBlock *new_block();
+  void release_block(AttributesBlock *block);
+
+  void flatten_attribute(StringRef attribute_name, void *dst) const;
+
+  template<typename T> Vector<T> flatten_attribute(StringRef attribute_name)
+  {
+    BLI_assert(m_attributes_info->type_of(attribute_name) == attribute_type_by_type<T>::value);
+    Vector<T> result(this->count_active());
+    this->flatten_attribute(attribute_name, (void *)result.begin());
+    return result;
+  }
+
+  friend bool operator==(const AttributesBlockContainer &a, const AttributesBlockContainer &b)
+  {
+    return &a == &b;
+  }
+
+  IndexRange new_ids(uint amount)
+  {
+    uint start = m_next_id.fetch_add(amount);
+    return IndexRange(start, amount);
+  }
+
+  ArrayRef<AttributesBlock *> active_blocks()
+  {
+    return m_active_blocks;
+  }
+};
+
+}  // namespace BKE
diff --git a/source/blender/blenkernel/BKE_attributes_ref.hpp b/source/blender/blenkernel/BKE_attributes_ref.hpp
index 229b5726e24..8ab1b238549 100644
--- a/source/blender/blenkernel/BKE_attributes_ref.hpp
+++ b/source/blender/blenkernel/BKE_attributes_ref.hpp
@@ -160,8 +160,8 @@ class AttributesDeclaration {
     return m_names.size();
   }
 
-  void join(AttributesDeclaration &other);
-  void join(AttributesInfo &other);
+  void join(const AttributesDeclaration &other);
+  void join(const AttributesInfo &other);
 };
 
 /**
@@ -291,27 +291,47 @@ class AttributesInfo {
   }
 };
 
+class AttributesInfoDiff {
+ private:
+  const AttributesInfo *m_old_info;
+  const AttributesInfo *m_new_info;
+  Vector<int> m_old_to_new_mapping;
+  Vector<int> m_new_to_old_mapping;
+
+ public:
+  AttributesInfoDiff(const AttributesInfo &old_info, const AttributesInfo &new_info);
+
+  void update(uint capacity,
+              ArrayRef<void *> old_buffers,
+              MutableArrayRef<void *> new_buffers) const;
+};
+
 /**
  * The main class used to interact with attributes. It only references a set of arrays, so it can
  * be passed by value.
  */
 class AttributesRef {
  private:
-  AttributesInfo *m_info;
+  const AttributesInfo *m_info;
   ArrayRef<void *> m_buffers;
   IndexRange m_range;
 
  public:
-  AttributesRef(AttributesInfo &info, ArrayRef<void *> buffers, uint size)
+  AttributesRef(const AttributesInfo &info, ArrayRef<void *> buffers, uint size)
       : AttributesRef(info, buffers, IndexRange(size))
   {
   }
 
-  AttributesRef(AttributesInfo &info, ArrayRef<void *> buffers, IndexRange range)
+  AttributesRef(const AttributesInfo &info, ArrayRef<void *> buffers, IndexRange range)
       : m_info(&info), m_buffers(buffers), m_range(range)
   {
   }
 
+  ArrayRef<void *> buffers()
+  {
+    return m_buffers;
+  }
+
   /**
    * Get the number of referenced elements.
    */
@@ -323,7 +343,7 @@ class AttributesRef {
   /**
    * Get information about the referenced attributes.
    */
-  AttributesInfo &info()
+  const AttributesInfo &info()
   {
     return *m_info;
   }
@@ -415,6 +435,11 @@ class AttributesRef {
     return AttributesRef(*m_info, m_buffers, m_range.slice(start, size));
   }
 
+  AttributesRef slice(IndexRange range) const
+  {
+    return AttributesRef(*m_info, m_buffers, m_range.slice(range.start(), range.size()));
+  }
+
   /**
    * Create a new slice containing only the first n elements.
    */
@@ -426,13 +451,13 @@ class AttributesRef {
 
 class AttributesRefGroup {
  private:
-  AttributesInfo *m_attributes_info;
+  const AttributesInfo *m_attributes_info;
   Vector<ArrayRef<void *>> m_buffers;
   Vector<IndexRange> m_ranges;
   uint m_size;
 
  public:
-  AttributesRefGroup(AttributesInfo &attributes_info,
+  AttributesRefGroup(const AttributesInfo &attributes_info,
                      Vector<ArrayRef<void *>> buffers,
                      Vector<IndexRange> ranges);
 
@@ -474,7 +499,7 @@ class AttributesRefGroup {
     this->fill<T>(index, value);
   }
 
-  AttributesInfo &attributes_info()
+  const AttributesInfo &attributes_info()
   {
     return *m_attributes_info;
   }
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index d40cf457608..d63231978e4 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -73,6 +73,8 @@ set(SRC
   intern/appdir.c
   intern/armature.c
   intern/armature_update.c
+  intern/attributes_block_container.cpp
+  intern/attributes_block.cpp
   intern/attributes_ref.cpp
   intern/autoexec.c
   intern/blender.c
@@ -235,6 +237,8 @@ set(SRC
   BKE_animsys.h
   BKE_appdir.h
   BKE_armature.h
+  BKE_attributes_block_container.hpp
+  BKE_attributes_block.hpp
   BKE_attributes_ref.hpp
   BKE_autoexec.h
   BKE_blender.h
diff --git a/source/blender/blenkernel/intern/attributes_block.cpp b/source/blender/blenkernel/intern/attributes_block.cpp
new file mode 100644
index 00000000000..614c30de4e9
--- /dev/null
+++ b/source/blender/blenkernel/intern/attributes_block.cpp
@@ -0,0 +1,102 @@
+#include "BKE_attributes_block.hpp"
+
+namespace BKE {
+
+AttributesBlock::AttributesBlock(const AttributesInfo *attributes_info,
+                                 uint capacity,
+                                 AttributesBlockContainer &owner)
+    : m_attributes_info(attributes_info), m_size(0), m_capacity(capacity), m_owner(&owner)
+{
+  BLI_assert(attributes_info != nullptr);
+  m_buffers.reserve(attributes_info->size());
+
+  for (AttributeType type : m_attributes_info->types()) {
+    uint byte_size = capacity * size_of_attribute_type(type);
+    void *ptr = MEM_mallocN_aligned(byte_size, 64, __func__);
+    m_buffers.append(ptr);
+  }
+}
+
+AttributesBlock::~AttributesBlock()
+{
+  for (void *ptr : m_buffers) {
+    MEM_freeN(ptr);
+  }
+}
+
+void AttributesBlock::move(uint old_index, uint new_index)
+{
+  AttributesRef attributes = *this;
+
+  for (uint attribute_index : attributes.info().attribute_indices()) {
+    void *ptr = attributes.get_ptr(attribute_index);
+    uint size = attributes.attribute_size(attribute_index);
+    void *src = POINTER_OFFSET(ptr, old_index * size);
+    void *dst = POINTER_OFFSET(ptr, new_index * size);
+    memcpy(dst, src, size);
+  }
+}
+
+void AttributesBlock::MoveUntilFull(AttributesBlock &from, AttributesBlock &to)
+{
+  BLI_assert(to.m_attributes_info == from.m_attributes_info);
+  uint move_amount = std::min(from.size(), to.remaining_capacity());
+
+  if (move_amount == 0) {
+    return;
+  }
+
+  uint src_start = from.m_size - move_amount;
+  uint dst_start = to.m_size;
+
+  const AttributesInfo &info = *from.m_attributes_info;
+
+  for (uint i = 0; i < info.size(); i++) {
+    void *from_buffer = from.m_buffers[i];
+    void *to_buffer = to.m_buffers[i];
+    AttributeType type = info.type_of(i);
+    uint size = size_of_attribute_type(type);
+    memcpy((char *)to_buffer + size * dst_start,
+           (char *)from_buffer + size * src_start,
+           size * move_amount);
+  }
+
+  from.m_size -= move_amount;
+  to.m_size += move_amount;
+}
+
+void AttributesBlock::Compress(MutableArrayRef<AttributesBlock *> blocks)
+{
+  std::sort(blocks.begin(), blocks.end(), [](AttributesBlock *a, AttributesBlock *b) {
+    return a->size() < b->size();
+  });
+
+  uint last_non_full = blocks.size() - 1;
+
+  for (uint i = 0; i < blocks.size(); i++) {
+    while (i < last_non_full) {
+      AttributesBlock &block = *blocks[last_non_full];
+      if (bloc

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list