[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