[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