[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