[Bf-blender-cvs] [551ae21bff3] functions: use block allocator to allow muliple emitters to emit into the same block
Jacques Lucke
noreply at git.blender.org
Thu Jun 27 15:49:57 CEST 2019
Commit: 551ae21bff3fcfdec1e30f9d5cabf350498ed119
Author: Jacques Lucke
Date: Thu Jun 27 13:25:01 2019 +0200
Branches: functions
https://developer.blender.org/rB551ae21bff3fcfdec1e30f9d5cabf350498ed119
use block allocator to allow muliple emitters to emit into the same block
===================================================================
M source/blender/simulations/bparticles/core.cpp
M source/blender/simulations/bparticles/core.hpp
M source/blender/simulations/bparticles/particles_container.cpp
M source/blender/simulations/bparticles/particles_container.hpp
M source/blender/simulations/bparticles/simulate.cpp
===================================================================
diff --git a/source/blender/simulations/bparticles/core.cpp b/source/blender/simulations/bparticles/core.cpp
index 67ad13ded1b..0bda6770598 100644
--- a/source/blender/simulations/bparticles/core.cpp
+++ b/source/blender/simulations/bparticles/core.cpp
@@ -33,19 +33,46 @@ ParticlesState::~ParticlesState()
}
}
-/* EmitterInterface
+/* Block Allocator
******************************************/
-EmitTarget &EmitterInterface::request(uint particle_type_id, uint size)
+BlockAllocator::BlockAllocator(ParticlesState &state) : m_state(state)
+{
+}
+
+ParticlesBlock &BlockAllocator::get_non_full_block(uint particle_type_id)
{
ParticlesContainer &container = m_state.particle_container(particle_type_id);
+ uint index = 0;
+ while (index < m_block_cache.size()) {
+ if (m_block_cache[index]->inactive_amount() == 0) {
+ m_block_cache.remove_and_reorder(index);
+ continue;
+ }
+
+ if (m_block_cache[index]->container() == container) {
+ return *m_block_cache[index];
+ }
+ index++;
+ }
+
+ ParticlesBlock &block = container.new_block();
+ m_block_cache.append(&block);
+ return block;
+}
+
+/* EmitterInterface
+ ******************************************/
+
+EmitTarget &EmitterInterface::request(uint particle_type_id, uint size)
+{
SmallVector<ParticlesBlock *> blocks;
SmallVector<Range<uint>> ranges;
uint remaining_size = size;
while (remaining_size > 0) {
- ParticlesBlock &block = *container.new_block();
+ ParticlesBlock &block = m_allocator.get_non_full_block(particle_type_id);
uint size_to_use = std::min(block.size(), remaining_size);
block.active_amount() += size_to_use;
@@ -56,6 +83,7 @@ EmitTarget &EmitterInterface::request(uint particle_type_id, uint size)
remaining_size -= size_to_use;
}
+ ParticlesContainer &container = m_state.particle_container(particle_type_id);
m_targets.append(EmitTarget(particle_type_id, container.attributes_info(), blocks, ranges));
return m_targets.last();
}
diff --git a/source/blender/simulations/bparticles/core.hpp b/source/blender/simulations/bparticles/core.hpp
index c86192c023c..7ddced9956d 100644
--- a/source/blender/simulations/bparticles/core.hpp
+++ b/source/blender/simulations/bparticles/core.hpp
@@ -47,6 +47,17 @@ class ParticlesState {
}
};
+class BlockAllocator {
+ private:
+ ParticlesState &m_state;
+ SmallVector<ParticlesBlock *> m_block_cache;
+
+ public:
+ BlockAllocator(ParticlesState &state);
+
+ ParticlesBlock &get_non_full_block(uint particle_type_id);
+};
+
class EmitTarget {
private:
uint m_particle_type_id;
@@ -110,10 +121,12 @@ class EmitTarget {
class EmitterInterface {
private:
ParticlesState &m_state;
+ BlockAllocator &m_allocator;
SmallVector<EmitTarget> m_targets;
public:
- EmitterInterface(ParticlesState &state) : m_state(state)
+ EmitterInterface(ParticlesState &state, BlockAllocator &allocator)
+ : m_state(state), m_allocator(allocator)
{
}
diff --git a/source/blender/simulations/bparticles/particles_container.cpp b/source/blender/simulations/bparticles/particles_container.cpp
index b1f7bf1119c..ab4d586f4e4 100644
--- a/source/blender/simulations/bparticles/particles_container.cpp
+++ b/source/blender/simulations/bparticles/particles_container.cpp
@@ -17,29 +17,28 @@ ParticlesContainer::~ParticlesContainer()
while (m_blocks.size() > 0) {
ParticlesBlock *block = m_blocks.any();
block->clear();
- this->release_block(block);
+ this->release_block(*block);
}
}
-ParticlesBlock *ParticlesContainer::new_block()
+ParticlesBlock &ParticlesContainer::new_block()
{
AttributeArraysCore attributes_core = AttributeArraysCore::NewWithSeparateAllocations(
m_attributes_info, m_block_size);
ParticlesBlock *block = new ParticlesBlock(*this, attributes_core);
m_blocks.add_new(block);
- return block;
+ return *block;
}
-void ParticlesContainer::release_block(ParticlesBlock *block)
+void ParticlesContainer::release_block(ParticlesBlock &block)
{
- BLI_assert(block);
- BLI_assert(block->active_amount() == 0);
- BLI_assert(m_blocks.contains(block));
- BLI_assert(&block->container() == this);
-
- block->attributes_core().free_buffers();
- m_blocks.remove(block);
- delete block;
+ BLI_assert(block.active_amount() == 0);
+ BLI_assert(m_blocks.contains(&block));
+ BLI_assert(&block.container() == this);
+
+ block.attributes_core().free_buffers();
+ m_blocks.remove(&block);
+ delete █
}
static SmallVector<int> map_attribute_indices(AttributesInfo &from_info, AttributesInfo &to_info)
diff --git a/source/blender/simulations/bparticles/particles_container.hpp b/source/blender/simulations/bparticles/particles_container.hpp
index 53eb94c2708..86cfea31727 100644
--- a/source/blender/simulations/bparticles/particles_container.hpp
+++ b/source/blender/simulations/bparticles/particles_container.hpp
@@ -41,8 +41,10 @@ class ParticlesContainer {
const SmallSet<ParticlesBlock *> &active_blocks();
- ParticlesBlock *new_block();
- void release_block(ParticlesBlock *block);
+ ParticlesBlock &new_block();
+ void release_block(ParticlesBlock &block);
+
+ friend bool operator==(const ParticlesContainer &a, const ParticlesContainer &b);
};
class ParticlesBlock {
@@ -105,6 +107,11 @@ inline const SmallSet<ParticlesBlock *> &ParticlesContainer::active_blocks()
return m_blocks;
}
+inline bool operator==(const ParticlesContainer &a, const ParticlesContainer &b)
+{
+ return &a == &b;
+}
+
/* Particles Block
****************************************/
diff --git a/source/blender/simulations/bparticles/simulate.cpp b/source/blender/simulations/bparticles/simulate.cpp
index 9719453cf66..82e104b6a64 100644
--- a/source/blender/simulations/bparticles/simulate.cpp
+++ b/source/blender/simulations/bparticles/simulate.cpp
@@ -373,10 +373,11 @@ BLI_NOINLINE static void delete_tagged_particles(ArrayRef<ParticlesBlock *> bloc
BLI_NOINLINE static void emit_new_particles_from_emitter(StepDescription &description,
ParticlesState &state,
+ BlockAllocator &block_allocator,
TimeSpan time_span,
Emitter &emitter)
{
- EmitterInterface interface(state);
+ EmitterInterface interface(state, block_allocator);
emitter.emit(interface);
for (EmitTarget &target : interface.targets()) {
@@ -416,7 +417,7 @@ BLI_NOINLINE static void compress_all_blocks(ParticlesContainer &particles)
for (ParticlesBlock *block : blocks) {
if (block->is_empty()) {
- particles.release_block(block);
+ particles.release_block(*block);
}
}
}
@@ -474,8 +475,9 @@ void simulate_step(ParticlesState &state, StepDescription &description)
step_individual_particles(container.active_blocks().to_small_vector(), time_span, type);
}
+ BlockAllocator block_allocator(state);
for (Emitter *emitter : description.emitters()) {
- emit_new_particles_from_emitter(description, state, time_span, *emitter);
+ emit_new_particles_from_emitter(description, state, block_allocator, time_span, *emitter);
}
for (uint type_id : description.particle_type_ids()) {
More information about the Bf-blender-cvs
mailing list