[Bf-blender-cvs] [2d925db8b02] functions: fix double free and optimize when particle function inputs have no dependencies

Jacques Lucke noreply at git.blender.org
Wed Jul 24 19:12:22 CEST 2019


Commit: 2d925db8b0283327717372d95aa3597db913bee0
Author: Jacques Lucke
Date:   Wed Jul 24 19:07:38 2019 +0200
Branches: functions
https://developer.blender.org/rB2d925db8b0283327717372d95aa3597db913bee0

fix double free and optimize when particle function inputs have no dependencies

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

M	source/blender/blenlib/BLI_array_allocator.hpp
M	source/blender/blenlib/BLI_stack.hpp
M	source/blender/simulations/bparticles/actions.cpp
M	source/blender/simulations/bparticles/forces.cpp
M	source/blender/simulations/bparticles/offset_handlers.cpp
M	source/blender/simulations/bparticles/particle_function.cpp
M	source/blender/simulations/bparticles/particle_function.hpp
M	source/blender/simulations/bparticles/step_description_interfaces.hpp

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

diff --git a/source/blender/blenlib/BLI_array_allocator.hpp b/source/blender/blenlib/BLI_array_allocator.hpp
index a7878dd8ce0..a2aa570ed45 100644
--- a/source/blender/blenlib/BLI_array_allocator.hpp
+++ b/source/blender/blenlib/BLI_array_allocator.hpp
@@ -63,6 +63,7 @@ class ArrayAllocator {
   void deallocate(void *ptr, uint element_size)
   {
     Stack<void *> &stack = this->stack_for_element_size(element_size);
+    BLI_assert(!stack.contains(ptr));
     stack.push(ptr);
   }
 
diff --git a/source/blender/blenlib/BLI_stack.hpp b/source/blender/blenlib/BLI_stack.hpp
index 7fd10767ce6..f32b6a2dbbd 100644
--- a/source/blender/blenlib/BLI_stack.hpp
+++ b/source/blender/blenlib/BLI_stack.hpp
@@ -120,6 +120,14 @@ template<typename T, uint N = 4> class Stack {
   {
     m_elements.clear_and_make_small();
   }
+
+  /**
+   * Does a linear search to check if the value is in the stack.
+   */
+  bool contains(const T &value)
+  {
+    return m_elements.contains(value);
+  }
 };
 
 } /* namespace BLI */
diff --git a/source/blender/simulations/bparticles/actions.cpp b/source/blender/simulations/bparticles/actions.cpp
index 3c8a3d17c67..17d8cc3777e 100644
--- a/source/blender/simulations/bparticles/actions.cpp
+++ b/source/blender/simulations/bparticles/actions.cpp
@@ -18,7 +18,7 @@ void ChangeDirectionAction::execute(ActionInterface &interface)
   auto inputs = m_compute_inputs.compute(interface);
 
   for (uint pindex : particles.pindices()) {
-    float3 direction = inputs.get<float3>("Direction", 0, pindex);
+    float3 direction = inputs->get<float3>("Direction", 0, pindex);
 
     velocities[pindex] = direction;
 
@@ -63,8 +63,8 @@ void ExplodeAction::execute(ActionInterface &interface)
   auto inputs = m_compute_inputs.compute(interface);
 
   for (uint pindex : particles.pindices()) {
-    uint parts_amount = std::max(0, inputs.get<int>("Amount", 0, pindex));
-    float speed = inputs.get<float>("Speed", 1, pindex);
+    uint parts_amount = std::max(0, inputs->get<int>("Amount", 0, pindex));
+    float speed = inputs->get<float>("Speed", 1, pindex);
 
     new_positions.append_n_times(positions[pindex], parts_amount);
     new_birth_times.append_n_times(interface.current_times()[pindex], parts_amount);
@@ -92,7 +92,7 @@ void ConditionAction::execute(ActionInterface &interface)
 
   Vector<uint> true_pindices, false_pindices;
   for (uint pindex : particles.pindices()) {
-    if (inputs.get<bool>("Condition", 0, pindex)) {
+    if (inputs->get<bool>("Condition", 0, pindex)) {
       true_pindices.append(pindex);
     }
     else {
diff --git a/source/blender/simulations/bparticles/forces.cpp b/source/blender/simulations/bparticles/forces.cpp
index 279a7d83630..9101e7d9271 100644
--- a/source/blender/simulations/bparticles/forces.cpp
+++ b/source/blender/simulations/bparticles/forces.cpp
@@ -38,7 +38,7 @@ void TurbulenceForce::add_force(ForceInterface &interface)
 
   for (uint pindex = 0; pindex < block.active_amount(); pindex++) {
     float3 pos = positions[pindex];
-    float3 strength = inputs.get<float3>("Strength", 0, pindex);
+    float3 strength = inputs->get<float3>("Strength", 0, pindex);
     float x = (BLI_gNoise(0.5f, pos.x, pos.y, pos.z + 1000.0f, false, 1) - 0.5f) * strength.x;
     float y = (BLI_gNoise(0.5f, pos.x, pos.y + 1000.0f, pos.z, false, 1) - 0.5f) * strength.y;
     float z = (BLI_gNoise(0.5f, pos.x + 1000.0f, pos.y, pos.z, false, 1) - 0.5f) * strength.z;
diff --git a/source/blender/simulations/bparticles/offset_handlers.cpp b/source/blender/simulations/bparticles/offset_handlers.cpp
index 325533e21aa..c9aee57a7f1 100644
--- a/source/blender/simulations/bparticles/offset_handlers.cpp
+++ b/source/blender/simulations/bparticles/offset_handlers.cpp
@@ -13,7 +13,7 @@ void CreateTrailHandler::execute(OffsetHandlerInterface &interface)
   Vector<float3> new_positions;
   Vector<float> new_birth_times;
   for (uint pindex : particles.pindices()) {
-    float rate = inputs.get<float>("Rate", 0, pindex);
+    float rate = inputs->get<float>("Rate", 0, pindex);
     if (rate <= 0.0f) {
       continue;
     }
diff --git a/source/blender/simulations/bparticles/particle_function.cpp b/source/blender/simulations/bparticles/particle_function.cpp
index 825e80554a1..ca31936ba04 100644
--- a/source/blender/simulations/bparticles/particle_function.cpp
+++ b/source/blender/simulations/bparticles/particle_function.cpp
@@ -2,98 +2,135 @@
 
 namespace BParticles {
 
-ParticleFunctionResult ParticleFunction::compute(ActionInterface &action_interface)
+std::unique_ptr<ParticleFunctionResult> ParticleFunction::compute(ActionInterface &interface)
 {
-  return this->compute(action_interface.array_allocator(),
-                       action_interface.particles().pindices(),
-                       action_interface.particles().attributes(),
-                       &action_interface.context());
+  return this->compute(interface.array_allocator(),
+                       interface.particles().pindices(),
+                       interface.particles().attributes(),
+                       &interface.context());
 }
 
-ParticleFunctionResult ParticleFunction::compute(OffsetHandlerInterface &offset_handler_interface)
+std::unique_ptr<ParticleFunctionResult> ParticleFunction::compute(
+    OffsetHandlerInterface &interface)
 {
-  return this->compute(offset_handler_interface.array_allocator(),
-                       offset_handler_interface.particles().pindices(),
-                       offset_handler_interface.particles().attributes(),
+  return this->compute(interface.array_allocator(),
+                       interface.particles().pindices(),
+                       interface.particles().attributes(),
                        nullptr);
 }
 
-ParticleFunctionResult ParticleFunction::compute(ForceInterface &force_interface)
+std::unique_ptr<ParticleFunctionResult> ParticleFunction::compute(ForceInterface &interface)
 {
-  ParticlesBlock &block = force_interface.block();
-  return this->compute(force_interface.array_allocator(),
+  ParticlesBlock &block = interface.block();
+  return this->compute(interface.array_allocator(),
                        block.active_range().as_array_ref(),
                        block.attributes(),
                        nullptr);
 }
 
-ParticleFunctionResult ParticleFunction::compute(ArrayAllocator &array_allocator,
-                                                 ArrayRef<uint> pindices,
-                                                 AttributeArrays attributes,
-                                                 ActionContext *action_context)
+std::unique_ptr<ParticleFunctionResult> ParticleFunction::compute(EventFilterInterface &interface)
 {
-  Vector<void *> input_buffers;
-  Vector<uint> input_strides;
-
-  for (uint i = 0; i < m_fn->input_amount(); i++) {
-    StringRef input_name = m_fn->input_name(i);
-    void *input_buffer = nullptr;
-    uint input_stride = 0;
-    if (input_name.startswith("Attribute")) {
-      StringRef attribute_name = input_name.drop_prefix("Attribute: ");
-      uint attribute_index = attributes.attribute_index(attribute_name);
-      input_buffer = attributes.get_ptr(attribute_index);
-      input_stride = attributes.attribute_stride(attribute_index);
-    }
-    else if (action_context != nullptr && input_name.startswith("Action Context")) {
-      StringRef context_name = input_name.drop_prefix("Action Context: ");
-      ActionContext::ContextArray array = action_context->get_context_array(context_name);
-      input_buffer = array.buffer;
-      input_stride = array.stride;
-    }
-    else {
-      BLI_assert(false);
-    }
-    BLI_assert(input_buffer != nullptr);
+  return this->compute(interface.array_allocator(),
+                       interface.particles().pindices(),
+                       interface.particles().attributes(),
+                       nullptr);
+}
 
-    input_buffers.append(input_buffer);
-    input_strides.append(input_stride);
-  }
+std::unique_ptr<ParticleFunctionResult> ParticleFunction::compute(ArrayAllocator &array_allocator,
+                                                                  ArrayRef<uint> pindices,
+                                                                  AttributeArrays attributes,
+                                                                  ActionContext *action_context)
+{
+  if (m_fn->input_amount() == 0) {
+    BLI_assert(array_allocator.array_size() >= 1);
+
+    ParticleFunctionResult *result = new ParticleFunctionResult();
+    result->m_fn = m_fn.ptr();
+    result->m_array_allocator = &array_allocator;
+
+    FN_TUPLE_CALL_ALLOC_TUPLES(*m_body, fn_in, fn_out);
+    m_body->call__setup_execution_context(fn_in, fn_out);
 
-  ParticleFunctionResult result;
-  result.m_fn = m_fn.ptr();
-  result.m_array_allocator = &array_allocator;
+    for (uint i = 0; i < m_fn->output_amount(); i++) {
+      CPPTypeInfo &type_info = m_fn->output_type(i)->extension<CPPTypeInfo>();
 
-  for (uint i = 0; i < m_fn->output_amount(); i++) {
-    CPPTypeInfo &type_info = m_fn->output_type(i)->extension<CPPTypeInfo>();
+      uint output_stride = type_info.size_of_type();
+      void *output_buffer = array_allocator.allocate(output_stride);
 
-    uint output_stride = type_info.size_of_type();
-    void *output_buffer = array_allocator.allocate(output_stride);
+      result->m_buffers.append(output_buffer);
+      result->m_strides.append(output_stride);
+      result->m_only_first.append(true);
 
-    result.m_buffers.append(output_buffer);
-    result.m_strides.append(output_stride);
+      fn_out.relocate_out__dynamic(i, output_buffer);
+    }
+
+    return std::unique_ptr<ParticleFunctionResult>(result);
   }
+  else {
+    Vector<void *> input_buffers;
+    Vector<uint> input_strides;
+
+    for (uint i = 0; i < m_fn->input_amount(); i++) {
+      StringRef input_name = m_fn->input_name(i);
+      void *input_buffer = nullptr;
+      uint input_stride = 0;
+      if (input_name.startswith("Attribute")) {
+        StringRef attribute_name = input_name.drop_prefix("Attribute: ");
+        uint attribute_index = attributes.attribute_index(attribute_name);
+        input_buffer = attributes.get_ptr(attribute_index);
+        input_str

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list