[Bf-blender-cvs] [5a6da2c1b1d] functions-experimental-refactor: update attribute blocks

Jacques Lucke noreply at git.blender.org
Sat Nov 2 21:33:05 CET 2019


Commit: 5a6da2c1b1db87a0576974b820c8acc87a6fef68
Author: Jacques Lucke
Date:   Sat Nov 2 21:31:56 2019 +0100
Branches: functions-experimental-refactor
https://developer.blender.org/rB5a6da2c1b1db87a0576974b820c8acc87a6fef68

update attribute blocks

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

M	source/blender/functions2/FN_attributes_block_container.h
M	source/blender/functions2/FN_attributes_ref.h
M	source/blender/functions2/FN_generic_array_ref.h
M	source/blender/functions2/intern/attributes_block_container.cc
M	source/blender/functions2/intern/attributes_ref.cc

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

diff --git a/source/blender/functions2/FN_attributes_block_container.h b/source/blender/functions2/FN_attributes_block_container.h
index 1f350277317..99ce7e7b298 100644
--- a/source/blender/functions2/FN_attributes_block_container.h
+++ b/source/blender/functions2/FN_attributes_block_container.h
@@ -11,18 +11,18 @@ class AttributesBlock;
 
 class AttributesBlockContainer : BLI::NonCopyable, BLI::NonMovable {
  private:
-  AttributesInfo m_attributes_info;
+  AttributesInfo m_info;
   uint m_block_size;
   VectorSet<AttributesBlock *> m_active_blocks;
   std::mutex m_blocks_mutex;
 
  public:
-  AttributesBlockContainer(AttributesInfo attributes_info, uint block_size);
+  AttributesBlockContainer(AttributesInfo info, uint block_size);
   ~AttributesBlockContainer();
 
   const AttributesInfo &info() const
   {
-    return m_attributes_info;
+    return m_info;
   }
 
   uint block_size() const
@@ -30,6 +30,8 @@ class AttributesBlockContainer : BLI::NonCopyable, BLI::NonMovable {
     return m_block_size;
   }
 
+  void update_attributes(AttributesInfo new_info, const AttributesDefaults &defaults);
+
   AttributesBlock &new_block();
   void release_block(AttributesBlock &block);
 };
@@ -40,6 +42,8 @@ class AttributesBlock : BLI::NonCopyable, BLI::NonMovable {
   Vector<void *> m_buffers;
   uint m_used_size;
 
+  friend AttributesBlockContainer;
+
  public:
   AttributesBlock(AttributesBlockContainer &owner);
   ~AttributesBlock();
diff --git a/source/blender/functions2/FN_attributes_ref.h b/source/blender/functions2/FN_attributes_ref.h
index 8bc60026def..1fb6c03ffe9 100644
--- a/source/blender/functions2/FN_attributes_ref.h
+++ b/source/blender/functions2/FN_attributes_ref.h
@@ -2,16 +2,21 @@
 #define __FN_ATTRIBUTES_REF_H__
 
 #include "FN_cpp_type.h"
+#include "FN_generic_array_ref.h"
 
+#include "BLI_array_cxx.h"
 #include "BLI_vector.h"
 #include "BLI_vector_set.h"
 #include "BLI_string_map.h"
 #include "BLI_optional.h"
+#include "BLI_monotonic_allocator.h"
 
 namespace FN {
 
+using BLI::Array;
 using BLI::ArrayRef;
 using BLI::IndexRange;
+using BLI::MonotonicAllocator;
 using BLI::MutableArrayRef;
 using BLI::Optional;
 using BLI::StringMap;
@@ -318,6 +323,70 @@ class AttributesRefGroup {
   }
 };
 
+class AttributesDefaults : BLI::NonCopyable, BLI::NonMovable {
+ private:
+  StringMap<uint> m_index_by_name;
+  Vector<const CPPType *> m_type_by_index;
+  MonotonicAllocator<> m_allocator;
+  Vector<void *> m_values;
+
+ public:
+  template<typename T> void add(StringRef name, T value)
+  {
+    if (m_index_by_name.contains(name)) {
+      /* TODO: Check if different handling of this case works better. */
+      BLI_assert(false);
+    }
+    else {
+      uint index = m_type_by_index.size();
+      m_index_by_name.add_new(name, index);
+      const CPPType &type = GET_TYPE<T>();
+      m_type_by_index.append(&type);
+      void *value_buffer = m_allocator.allocate_aligned(type.size(), type.alignment());
+      new (value_buffer) T(std::move(value));
+      m_values.append(value_buffer);
+    }
+  }
+
+  const void *get(StringRef name, const CPPType &expected_type) const
+  {
+    uint index = m_index_by_name.lookup(name);
+    BLI_assert(*m_type_by_index[index] == expected_type);
+    UNUSED_VARS_NDEBUG(expected_type);
+    return m_values[index];
+  }
+
+  template<typename T> const T &get(StringRef name) const
+  {
+    const void *value = this->get(name, GET_TYPE<T>());
+    return *(const T *)value;
+  }
+};
+
+class AttributesInfoDiff {
+ private:
+  const AttributesInfo *m_old_info;
+  const AttributesInfo *m_new_info;
+  Array<int> m_old_to_new_mapping;
+  Array<int> m_new_to_old_mapping;
+  Array<const void *> m_default_buffers;
+
+ public:
+  AttributesInfoDiff(const AttributesInfo &old_info,
+                     const AttributesInfo &new_info,
+                     const AttributesDefaults &defaults);
+
+  void update(uint capacity,
+              uint used_size,
+              ArrayRef<void *> old_buffers,
+              MutableArrayRef<void *> new_buffers) const;
+
+  uint new_buffer_amount() const
+  {
+    return m_new_info->size();
+  }
+};
+
 }  // namespace FN
 
 #endif /* __FN_ATTRIBUTES_REF_H__ */
diff --git a/source/blender/functions2/FN_generic_array_ref.h b/source/blender/functions2/FN_generic_array_ref.h
index 8943cd67598..418f80cff3d 100644
--- a/source/blender/functions2/FN_generic_array_ref.h
+++ b/source/blender/functions2/FN_generic_array_ref.h
@@ -120,6 +120,13 @@ class GenericMutableArrayRef {
     return m_size;
   }
 
+  void fill__uninitialized(const void *value)
+  {
+    for (uint i = 0; i < m_size; i++) {
+      m_type->copy_to_uninitialized(value, (*this)[i]);
+    }
+  }
+
   void copy_in__uninitialized(uint index, const void *src)
   {
     BLI_assert(index < m_size);
diff --git a/source/blender/functions2/intern/attributes_block_container.cc b/source/blender/functions2/intern/attributes_block_container.cc
index 9450ff74fa0..d083ed4c925 100644
--- a/source/blender/functions2/intern/attributes_block_container.cc
+++ b/source/blender/functions2/intern/attributes_block_container.cc
@@ -2,8 +2,8 @@
 
 namespace FN {
 
-AttributesBlockContainer::AttributesBlockContainer(AttributesInfo attributes_info, uint block_size)
-    : m_attributes_info(std::move(attributes_info)), m_block_size(block_size)
+AttributesBlockContainer::AttributesBlockContainer(AttributesInfo info, uint block_size)
+    : m_info(std::move(info)), m_block_size(block_size)
 {
 }
 
@@ -14,6 +14,19 @@ AttributesBlockContainer::~AttributesBlockContainer()
   }
 }
 
+void AttributesBlockContainer::update_attributes(AttributesInfo new_info,
+                                                 const AttributesDefaults &defaults)
+{
+  AttributesInfoDiff diff{m_info, new_info, defaults};
+  for (AttributesBlock *block : m_active_blocks) {
+    Vector<void *> new_buffers{diff.new_buffer_amount()};
+    diff.update(m_block_size, block->m_used_size, block->m_buffers, new_buffers);
+    block->m_buffers = std::move(new_buffers);
+  }
+
+  m_info = std::move(new_info);
+}
+
 AttributesBlock &AttributesBlockContainer::new_block()
 {
   AttributesBlock *block = new AttributesBlock(*this);
diff --git a/source/blender/functions2/intern/attributes_ref.cc b/source/blender/functions2/intern/attributes_ref.cc
index 2ac2a36a90c..87182abf857 100644
--- a/source/blender/functions2/intern/attributes_ref.cc
+++ b/source/blender/functions2/intern/attributes_ref.cc
@@ -36,4 +36,70 @@ AttributesRefGroup::AttributesRefGroup(const AttributesInfo &info,
   }
 }
 
+static Array<int> map_attribute_indices(const AttributesInfo &from_info,
+                                        const AttributesInfo &to_info)
+{
+  Array<int> mapping = Array<int>(from_info.size());
+
+  for (uint from_index : from_info.indices()) {
+    StringRef name = from_info.name_of(from_index);
+    const CPPType &type = from_info.type_of(from_index);
+
+    int to_index = to_info.index_of_try(name, type);
+    mapping[from_index] = to_index;
+  }
+
+  return mapping;
+}
+
+AttributesInfoDiff::AttributesInfoDiff(const AttributesInfo &old_info,
+                                       const AttributesInfo &new_info,
+                                       const AttributesDefaults &defaults)
+    : m_old_info(&old_info), m_new_info(&new_info)
+{
+  m_old_to_new_mapping = map_attribute_indices(old_info, new_info);
+  m_new_to_old_mapping = map_attribute_indices(new_info, old_info);
+  m_default_buffers = Array<const void *>(new_info.size(), nullptr);
+
+  for (uint i : new_info.indices()) {
+    if (m_new_to_old_mapping[i] >= 0) {
+      m_default_buffers[i] = defaults.get(new_info.name_of(i), new_info.type_of(i));
+    }
+  }
+}
+
+void AttributesInfoDiff::update(uint capacity,
+                                uint used_size,
+                                ArrayRef<void *> old_buffers,
+                                MutableArrayRef<void *> new_buffers) const
+{
+  BLI_assert(old_buffers.size() == m_old_info->size());
+  BLI_assert(new_buffers.size() == m_new_info->size());
+
+  for (uint new_index : m_new_info->indices()) {
+    int old_index = m_new_to_old_mapping[new_index];
+    const CPPType &type = m_new_info->type_of(new_index);
+
+    if (old_index == -1) {
+      void *new_buffer = MEM_malloc_arrayN(capacity, type.size(), __func__);
+
+      GenericMutableArrayRef{type, new_buffer, used_size}.fill__uninitialized(
+          m_default_buffers[new_index]);
+
+      new_buffers[new_index] = new_buffer;
+    }
+    else {
+      new_buffers[new_index] = old_buffers[old_index];
+    }
+  };
+
+  for (uint old_index : m_old_info->indices()) {
+    int new_index = m_old_to_new_mapping[old_index];
+
+    if (new_index == -1) {
+      MEM_freeN(old_buffers[old_index]);
+    }
+  }
+}
+
 }  // namespace FN



More information about the Bf-blender-cvs mailing list