From 98aa7276c8e53eb83c98caa6e125d9358d9a4d3a Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 13 Oct 2022 17:21:23 -0500 Subject: Curves: Multithread position vertex buffer extraction On a Ryzen 3700x I observed a 4ms improvement (from 5ms to 1ms) on every redraw when sculpting with 88000 curves. --- .../blender/draw/intern/draw_cache_impl_curves.cc | 48 ++++++++++++---------- 1 file changed, 26 insertions(+), 22 deletions(-) (limited to 'source') diff --git a/source/blender/draw/intern/draw_cache_impl_curves.cc b/source/blender/draw/intern/draw_cache_impl_curves.cc index 329bc4a4700..5ed02fd55fd 100644 --- a/source/blender/draw/intern/draw_cache_impl_curves.cc +++ b/source/blender/draw/intern/draw_cache_impl_curves.cc @@ -17,6 +17,7 @@ #include "BLI_math_vector.h" #include "BLI_math_vector.hh" #include "BLI_span.hh" +#include "BLI_task.hh" #include "BLI_utildefines.h" #include "DNA_curves_types.h" @@ -223,38 +224,41 @@ static void curves_batch_cache_fill_segments_proc_pos( MutableSpan posTime_data, MutableSpan hairLength_data) { + SCOPED_TIMER_AVERAGED(__func__); + using namespace blender; /* TODO: use hair radius layer if available. */ - const int curve_num = curves_id.geometry.curve_num; const blender::bke::CurvesGeometry &curves = blender::bke::CurvesGeometry::wrap( curves_id.geometry); Span positions = curves.positions(); - for (const int i_curve : IndexRange(curve_num)) { - const IndexRange points = curves.points_for_curve(i_curve); + threading::parallel_for(curves.curves_range(), 1024, [&](const IndexRange range) { + for (const int i_curve : range) { + const IndexRange points = curves.points_for_curve(i_curve); - Span curve_positions = positions.slice(points); - MutableSpan curve_posTime_data = posTime_data.slice(points); + Span curve_positions = positions.slice(points); + MutableSpan curve_posTime_data = posTime_data.slice(points); - float total_len = 0.0f; - for (const int i_point : curve_positions.index_range()) { - if (i_point > 0) { - total_len += blender::math::distance(curve_positions[i_point - 1], - curve_positions[i_point]); - } - curve_posTime_data[i_point].position = curve_positions[i_point]; - curve_posTime_data[i_point].parameter = total_len; - } - hairLength_data[i_curve] = total_len; - - /* Assign length value. */ - if (total_len > 0.0f) { - const float factor = 1.0f / total_len; - /* Divide by total length to have a [0-1] number. */ + float total_len = 0.0f; for (const int i_point : curve_positions.index_range()) { - curve_posTime_data[i_point].parameter *= factor; + if (i_point > 0) { + total_len += blender::math::distance(curve_positions[i_point - 1], + curve_positions[i_point]); + } + curve_posTime_data[i_point].position = curve_positions[i_point]; + curve_posTime_data[i_point].parameter = total_len; + } + hairLength_data[i_curve] = total_len; + + /* Assign length value. */ + if (total_len > 0.0f) { + const float factor = 1.0f / total_len; + /* Divide by total length to have a [0-1] number. */ + for (const int i_point : curve_positions.index_range()) { + curve_posTime_data[i_point].parameter *= factor; + } } } - } + }); } static void curves_batch_cache_ensure_procedural_pos(const Curves &curves, -- cgit v1.2.3