[Bf-blender-cvs] [ea5a9c8ec0b] functions: use array allocator in simulate_with_max_n_events function

Jacques Lucke noreply at git.blender.org
Sun Jun 30 16:01:06 CEST 2019


Commit: ea5a9c8ec0bdb75f5611a141b0c7c8d01b1f3481
Author: Jacques Lucke
Date:   Sun Jun 30 13:11:26 2019 +0200
Branches: functions
https://developer.blender.org/rBea5a9c8ec0bdb75f5611a141b0c7c8d01b1f3481

use array allocator in simulate_with_max_n_events function

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

M	source/blender/blenlib/BLI_fixed_array_allocator.hpp
M	source/blender/blenlib/BLI_vector_adaptor.hpp
M	source/blender/simulations/bparticles/core.hpp
M	source/blender/simulations/bparticles/simulate.cpp

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

diff --git a/source/blender/blenlib/BLI_fixed_array_allocator.hpp b/source/blender/blenlib/BLI_fixed_array_allocator.hpp
index 2edcae2022d..34fc9f8ac29 100644
--- a/source/blender/blenlib/BLI_fixed_array_allocator.hpp
+++ b/source/blender/blenlib/BLI_fixed_array_allocator.hpp
@@ -15,6 +15,8 @@ class FixedArrayAllocator {
   {
   }
 
+  FixedArrayAllocator(FixedArrayAllocator &other) = delete;
+
   ~FixedArrayAllocator()
   {
     for (void *ptr : m_all_pointers) {
@@ -46,7 +48,7 @@ class FixedArrayAllocator {
 
   template<typename T> T *allocate_array()
   {
-    return this->allocate_array(sizeof(T));
+    return (T *)this->allocate_array(sizeof(T));
   }
 
   template<typename T> void deallocate_array(T *ptr)
diff --git a/source/blender/blenlib/BLI_vector_adaptor.hpp b/source/blender/blenlib/BLI_vector_adaptor.hpp
index 65691b74818..39a04afb9ac 100644
--- a/source/blender/blenlib/BLI_vector_adaptor.hpp
+++ b/source/blender/blenlib/BLI_vector_adaptor.hpp
@@ -29,6 +29,7 @@
 #pragma once
 
 #include "BLI_array_ref.hpp"
+#include "BLI_vector_adaptor.hpp"
 
 namespace BLI {
 
@@ -51,12 +52,14 @@ template<typename T> class VectorAdaptor {
    * clear, where the new adaptor should take the memory from.
    */
   VectorAdaptor(VectorAdaptor &other) = delete;
+  VectorAdaptor(VectorAdaptor &&other) = delete;
 
   /**
    * Construct using any pointer and a capacity.
    * The initial size is set to zero.
    */
-  VectorAdaptor(T *ptr, uint capacity) : m_start(ptr), m_end(ptr), m_capacity(capacity)
+  VectorAdaptor(T *ptr, uint capacity, uint size = 0)
+      : m_start(ptr), m_end(ptr + size), m_capacity(capacity)
   {
   }
 
@@ -69,11 +72,19 @@ template<typename T> class VectorAdaptor {
   {
   }
 
+  /**
+   * Elements should continue to live after the adapter is destructed.
+   */
   ~VectorAdaptor()
+  {
+  }
+
+  void clear()
   {
     for (T &value : *this) {
       value.~T();
     }
+    m_end = m_start;
   }
 
   /**
@@ -121,6 +132,11 @@ template<typename T> class VectorAdaptor {
     return m_end - m_start;
   }
 
+  operator ArrayRef<T>() const
+  {
+    return ArrayRef<T>(m_start, this->size());
+  }
+
   T &operator[](uint index)
   {
     BLI_assert(index < this->size());
diff --git a/source/blender/simulations/bparticles/core.hpp b/source/blender/simulations/bparticles/core.hpp
index ce767a2aa65..ca35241af0e 100644
--- a/source/blender/simulations/bparticles/core.hpp
+++ b/source/blender/simulations/bparticles/core.hpp
@@ -9,6 +9,7 @@
 #include "BLI_utildefines.h"
 #include "BLI_string_ref.hpp"
 #include "BLI_small_map.hpp"
+#include "BLI_vector_adaptor.hpp"
 
 #include "attributes.hpp"
 #include "particles_container.hpp"
@@ -23,6 +24,7 @@ using BLI::SmallMap;
 using BLI::SmallSetVector;
 using BLI::SmallVector;
 using BLI::StringRef;
+using BLI::VectorAdaptor;
 using std::unique_ptr;
 
 class ParticlesState {
diff --git a/source/blender/simulations/bparticles/simulate.cpp b/source/blender/simulations/bparticles/simulate.cpp
index 274e2df040a..55c7f32448a 100644
--- a/source/blender/simulations/bparticles/simulate.cpp
+++ b/source/blender/simulations/bparticles/simulate.cpp
@@ -157,8 +157,8 @@ BLI_NOINLINE static void find_unfinished_particles(
     ArrayRef<float> time_factors_to_next_event,
     ArrayRef<float> durations,
     ArrayRef<uint8_t> kill_states,
-    SmallVector<uint> &r_unfinished_particle_indices,
-    SmallVector<float> &r_remaining_durations)
+    VectorAdaptor<uint> &r_unfinished_particle_indices,
+    VectorAdaptor<float> &r_remaining_durations)
 {
 
   for (uint i : indices_with_event) {
@@ -203,8 +203,8 @@ BLI_NOINLINE static void simulate_to_next_event(BlockAllocator &block_allocator,
                                                 ArrayRef<float> durations,
                                                 float end_time,
                                                 ArrayRef<EventAction *> events,
-                                                SmallVector<uint> &r_unfinished_particle_indices,
-                                                SmallVector<float> &r_remaining_durations)
+                                                VectorAdaptor<uint> &r_unfinished_particle_indices,
+                                                VectorAdaptor<float> &r_remaining_durations)
 {
   SmallVector<int> next_event_indices(particles.size());
   SmallVector<float> time_factors_to_next_event(particles.size());
@@ -256,47 +256,68 @@ BLI_NOINLINE static void simulate_to_next_event(BlockAllocator &block_allocator,
 
 BLI_NOINLINE static void simulate_with_max_n_events(
     uint max_events,
+    FixedArrayAllocator &array_allocator,
     BlockAllocator &block_allocator,
     ParticlesBlock &block,
     AttributeArrays attribute_offsets,
     ArrayRef<float> durations,
     float end_time,
     ArrayRef<EventAction *> events,
-    SmallVector<uint> &r_unfinished_particle_indices)
+    VectorAdaptor<uint> &r_unfinished_particle_indices)
 {
+  BLI_assert(array_allocator.array_size() >= block.active_amount());
+  uint *indices_A = array_allocator.allocate_array<uint>();
+  uint *indices_B = array_allocator.allocate_array<uint>();
+  float *durations_A = array_allocator.allocate_array<float>();
+  float *durations_B = array_allocator.allocate_array<float>();
+
   /* Handle first event separately to be able to use the static number range. */
-  ParticleSet particles_to_simulate(block, static_number_range_ref(block.active_range()));
-  SmallVector<uint> unfinished_particle_indices;
-  SmallVector<float> remaining_durations;
-
-  simulate_to_next_event(block_allocator,
-                         particles_to_simulate,
-                         attribute_offsets,
-                         durations,
-                         end_time,
-                         events,
-                         unfinished_particle_indices,
-                         remaining_durations);
-
-  for (uint iteration = 0; iteration < max_events - 1; iteration++) {
-    particles_to_simulate = ParticleSet(block, unfinished_particle_indices);
-    SmallVector<uint> unfinished_particle_indices_after;
-    SmallVector<float> remaining_durations_after;
+  uint amount_left = block.active_amount();
+
+  {
+    VectorAdaptor<uint> indices_output(indices_A, amount_left);
+    VectorAdaptor<float> durations_output(durations_A, amount_left);
+    simulate_to_next_event(block_allocator,
+                           ParticleSet(block, static_number_range_ref(0, amount_left)),
+                           attribute_offsets,
+                           durations,
+                           end_time,
+                           events,
+                           indices_output,
+                           durations_output);
+    BLI_assert(indices_output.size() == durations_output.size());
+    amount_left = indices_output.size();
+  }
+
+  for (uint iteration = 0; iteration < max_events - 1 && amount_left > 0; iteration++) {
+    VectorAdaptor<uint> indices_input(indices_A, amount_left, amount_left);
+    VectorAdaptor<uint> indices_output(indices_B, amount_left, 0);
+    VectorAdaptor<float> durations_input(durations_A, amount_left, amount_left);
+    VectorAdaptor<float> durations_output(durations_B, amount_left, 0);
 
     simulate_to_next_event(block_allocator,
-                           particles_to_simulate,
+                           ParticleSet(block, indices_input),
                            attribute_offsets,
-                           remaining_durations,
+                           durations_input,
                            end_time,
                            events,
-                           unfinished_particle_indices_after,
-                           remaining_durations_after);
+                           indices_output,
+                           durations_output);
+    BLI_assert(indices_output.size() == durations_output.size());
+
+    amount_left = indices_output.size();
+    std::swap(indices_A, indices_B);
+    std::swap(durations_A, durations_B);
+  }
 
-    unfinished_particle_indices = std::move(unfinished_particle_indices_after);
-    remaining_durations = std::move(remaining_durations_after);
+  for (uint i = 0; i < amount_left; i++) {
+    r_unfinished_particle_indices.append(indices_A[i]);
   }
 
-  r_unfinished_particle_indices = std::move(unfinished_particle_indices);
+  array_allocator.deallocate_array(indices_A);
+  array_allocator.deallocate_array(indices_B);
+  array_allocator.deallocate_array(durations_A);
+  array_allocator.deallocate_array(durations_B);
 }
 
 BLI_NOINLINE static void add_float3_arrays(ArrayRef<float3> base, ArrayRef<float3> values)
@@ -372,8 +393,11 @@ BLI_NOINLINE static void simulate_block(FixedArrayAllocator &array_allocator,
     apply_remaining_offsets(all_particles_in_block, attribute_offsets);
   }
   else {
-    SmallVector<uint> unfinished_particle_indices;
+    uint *indices_array = array_allocator.allocate_array<uint>();
+    VectorAdaptor<uint> unfinished_particle_indices(indices_array, amount);
+
     simulate_with_max_n_events(10,
+                               array_allocator,
                                block_allocator,
                                block,
                                attribute_offsets,
@@ -382,8 +406,12 @@ BLI_NOINLINE static void simulate_block(FixedArrayAllocator &array_allocator,
                                events,
                                unfinished_particle_indices);
 
-    ParticleSet remaining_particles(block, unfinished_particle_indices);
-    apply_remaining_offsets(remaining_particles, attribute_offsets);
+    if (unfinished_particle_indices.size() > 0) {
+      ParticleSet remaining_particles(block, unfinished_particle_indices);
+      apply_remaining_offsets(remaining_particles, attribute_offsets);
+    }
+
+    array_allocator.deallocate_array(indices_array);
   }
 
   attribute_offsets_core.deallocate_in_array_allocator(array_allocator);



More information about the Bf-blender-cvs mailing list