BLI: refactor IndexMask for better performance and memory usage #104629
|
@ -56,9 +56,9 @@ template<typename T> void copy_assign_compressed_cb(const void *src, void *dst,
|
|||
const T *src_ = static_cast<const T *>(src);
|
||||
T *dst_ = static_cast<T *>(dst);
|
||||
|
||||
mask.to_best_mask_type([&](auto best_mask) {
|
||||
for (const int64_t i : IndexRange(best_mask.size())) {
|
||||
dst_[i] = src_[best_mask[i]];
|
||||
mask.foreach_span_or_range([&](const auto mask_segment) {
|
||||
for (const int64_t i : IndexRange(mask_segment.size())) {
|
||||
dst_[i] = src_[mask_segment[i]];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -79,9 +79,9 @@ template<typename T> void copy_construct_compressed_cb(const void *src, void *ds
|
|||
const T *src_ = static_cast<const T *>(src);
|
||||
T *dst_ = static_cast<T *>(dst);
|
||||
|
||||
mask.to_best_mask_type([&](auto best_mask) {
|
||||
for (const int64_t i : IndexRange(best_mask.size())) {
|
||||
new (dst_ + i) T(src_[best_mask[i]]);
|
||||
mask.foreach_span_or_range([&](const auto mask_segment) {
|
||||
for (const int64_t i : IndexRange(mask_segment.size())) {
|
||||
new (dst_ + i) T(src_[mask_segment[i]]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -52,16 +52,16 @@ inline void interpolate_to_masked(const Span<T> src,
|
|||
BLI_assert(indices.size() == dst_mask.size());
|
||||
const int last_src_index = src.size() - 1;
|
||||
|
||||
dst_mask.to_best_mask_type([&](auto dst_mask) {
|
||||
for (const int i : IndexRange(dst_mask.size())) {
|
||||
dst_mask.foreach_span_or_range([&](auto dst_mask_segment) {
|
||||
for (const int i : IndexRange(dst_mask_segment.size())) {
|
||||
const int prev_index = indices[i];
|
||||
const float factor = factors[i];
|
||||
const bool is_cyclic_case = prev_index == last_src_index;
|
||||
if (is_cyclic_case) {
|
||||
dst[dst_mask[i]] = math::interpolate(src.last(), src.first(), factor);
|
||||
dst[dst_mask_segment[i]] = math::interpolate(src.last(), src.first(), factor);
|
||||
}
|
||||
else {
|
||||
dst[dst_mask[i]] = math::interpolate(src[prev_index], src[prev_index + 1], factor);
|
||||
dst[dst_mask_segment[i]] = math::interpolate(src[prev_index], src[prev_index + 1], factor);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -127,9 +127,9 @@ template<typename T> class VArrayImpl {
|
|||
*/
|
||||
virtual void materialize_compressed(IndexMask mask, T *dst) const
|
||||
{
|
||||
mask.to_best_mask_type([&](auto best_mask) {
|
||||
for (const int64_t i : IndexRange(best_mask.size())) {
|
||||
dst[i] = this->get(best_mask[i]);
|
||||
mask.foreach_span_or_range([&](const auto mask_segment) {
|
||||
for (const int64_t i : IndexRange(mask_segment.size())) {
|
||||
dst[i] = this->get(mask_segment[i]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -139,9 +139,9 @@ template<typename T> class VArrayImpl {
|
|||
*/
|
||||
virtual void materialize_compressed_to_uninitialized(IndexMask mask, T *dst) const
|
||||
{
|
||||
mask.to_best_mask_type([&](auto best_mask) {
|
||||
for (const int64_t i : IndexRange(best_mask.size())) {
|
||||
new (dst + i) T(this->get(best_mask[i]));
|
||||
mask.foreach_span_or_range([&](const auto mask_segment) {
|
||||
for (const int64_t i : IndexRange(mask_segment.size())) {
|
||||
new (dst + i) T(this->get(mask_segment[i]));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -241,18 +241,18 @@ template<typename T> class VArrayImpl_For_Span : public VMutableArrayImpl<T> {
|
|||
|
||||
void materialize_compressed(IndexMask mask, T *dst) const override
|
||||
{
|
||||
mask.to_best_mask_type([&](auto best_mask) {
|
||||
for (const int64_t i : IndexRange(best_mask.size())) {
|
||||
dst[i] = data_[best_mask[i]];
|
||||
mask.foreach_span_or_range([&](const auto mask_segment) {
|
||||
for (const int64_t i : IndexRange(mask_segment.size())) {
|
||||
dst[i] = data_[mask_segment[i]];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void materialize_compressed_to_uninitialized(IndexMask mask, T *dst) const override
|
||||
{
|
||||
mask.to_best_mask_type([&](auto best_mask) {
|
||||
for (const int64_t i : IndexRange(best_mask.size())) {
|
||||
new (dst + i) T(data_[best_mask[i]]);
|
||||
mask.foreach_span_or_range([&](const auto mask_segment) {
|
||||
for (const int64_t i : IndexRange(mask_segment.size())) {
|
||||
new (dst + i) T(data_[mask_segment[i]]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -383,18 +383,18 @@ template<typename T, typename GetFunc> class VArrayImpl_For_Func final : public
|
|||
|
||||
void materialize_compressed(IndexMask mask, T *dst) const override
|
||||
{
|
||||
mask.to_best_mask_type([&](auto best_mask) {
|
||||
for (const int64_t i : IndexRange(best_mask.size())) {
|
||||
dst[i] = get_func_(best_mask[i]);
|
||||
mask.foreach_span_or_range([&](const auto mask_segment) {
|
||||
for (const int64_t i : IndexRange(mask_segment.size())) {
|
||||
dst[i] = get_func_(mask_segment[i]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void materialize_compressed_to_uninitialized(IndexMask mask, T *dst) const override
|
||||
{
|
||||
mask.to_best_mask_type([&](auto best_mask) {
|
||||
for (const int64_t i : IndexRange(best_mask.size())) {
|
||||
new (dst + i) T(get_func_(best_mask[i]));
|
||||
mask.foreach_span_or_range([&](const auto mask_segment) {
|
||||
for (const int64_t i : IndexRange(mask_segment.size())) {
|
||||
new (dst + i) T(get_func_(mask_segment[i]));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -446,18 +446,18 @@ class VArrayImpl_For_DerivedSpan final : public VMutableArrayImpl<ElemT> {
|
|||
|
||||
void materialize_compressed(IndexMask mask, ElemT *dst) const override
|
||||
{
|
||||
mask.to_best_mask_type([&](auto best_mask) {
|
||||
for (const int64_t i : IndexRange(best_mask.size())) {
|
||||
dst[i] = GetFunc(data_[best_mask[i]]);
|
||||
mask.foreach_span_or_range([&](const auto mask_segment) {
|
||||
for (const int64_t i : IndexRange(mask_segment.size())) {
|
||||
dst[i] = GetFunc(data_[mask_segment[i]]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void materialize_compressed_to_uninitialized(IndexMask mask, ElemT *dst) const override
|
||||
{
|
||||
mask.to_best_mask_type([&](auto best_mask) {
|
||||
for (const int64_t i : IndexRange(best_mask.size())) {
|
||||
new (dst + i) ElemT(GetFunc(data_[best_mask[i]]));
|
||||
mask.foreach_span_or_range([&](const auto mask_segment) {
|
||||
for (const int64_t i : IndexRange(mask_segment.size())) {
|
||||
new (dst + i) ElemT(GetFunc(data_[mask_segment[i]]));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -671,8 +671,8 @@ template<typename T> class CustomMF_Constant : public MultiFunction {
|
|||
void call(IndexMask mask, Params params, Context /*context*/) const override
|
||||
{
|
||||
MutableSpan<T> output = params.uninitialized_single_output<T>(0);
|
||||
mask.to_best_mask_type([&](const auto &mask) {
|
||||
for (const int64_t i : mask) {
|
||||
mask.foreach_span_or_range([&](const auto mask_segment) {
|
||||
for (const int64_t i : mask_segment) {
|
||||
new (&output[i]) T(value_);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -80,11 +80,11 @@ class SeparateRGBAFunction : public mf::MultiFunction {
|
|||
}
|
||||
|
||||
devirtualize_varray(colors, [&](auto colors) {
|
||||
mask.to_best_mask_type([&](auto mask) {
|
||||
mask.foreach_span_or_range([&](const auto mask_segment) {
|
||||
const int used_outputs_num = used_outputs.size();
|
||||
const int *used_outputs_data = used_outputs.data();
|
||||
|
||||
for (const int64_t i : mask) {
|
||||
for (const int64_t i : mask_segment) {
|
||||
const ColorGeometry4f &color = colors[i];
|
||||
for (const int out_i : IndexRange(used_outputs_num)) {
|
||||
const int channel = used_outputs_data[out_i];
|
||||
|
|
|
@ -137,8 +137,8 @@ static void sample_indices_and_lengths(const Span<float> accumulated_lengths,
|
|||
const float total_length = accumulated_lengths.last();
|
||||
length_parameterize::SampleSegmentHint hint;
|
||||
|
||||
mask.to_best_mask_type([&](const auto mask) {
|
||||
for (const int64_t i : mask) {
|
||||
mask.foreach_span_or_range([&](const auto mask_segment) {
|
||||
for (const int64_t i : mask_segment) {
|
||||
const float sample_length = length_mode == GEO_NODE_CURVE_SAMPLE_FACTOR ?
|
||||
sample_lengths[i] * total_length :
|
||||
sample_lengths[i];
|
||||
|
@ -171,9 +171,9 @@ static void sample_indices_and_factors_to_compressed(const Span<float> accumulat
|
|||
|
||||
switch (length_mode) {
|
||||
case GEO_NODE_CURVE_SAMPLE_FACTOR:
|
||||
mask.to_best_mask_type([&](const auto mask) {
|
||||
for (const int64_t i : IndexRange(mask.size())) {
|
||||
const float length = sample_lengths[mask[i]] * total_length;
|
||||
mask.foreach_span_or_range([&](const auto mask_segment) {
|
||||
for (const int64_t i : IndexRange(mask_segment.size())) {
|
||||
const float length = sample_lengths[mask_segment[i]] * total_length;
|
||||
length_parameterize::sample_at_length(accumulated_lengths,
|
||||
std::clamp(length, 0.0f, total_length),
|
||||
r_segment_indices[i],
|
||||
|
@ -183,9 +183,9 @@ static void sample_indices_and_factors_to_compressed(const Span<float> accumulat
|
|||
});
|
||||
break;
|
||||
case GEO_NODE_CURVE_SAMPLE_LENGTH:
|
||||
mask.to_best_mask_type([&](const auto mask) {
|
||||
for (const int64_t i : IndexRange(mask.size())) {
|
||||
const float length = sample_lengths[mask[i]];
|
||||
mask.foreach_span_or_range([&](const auto mask_segment) {
|
||||
for (const int64_t i : IndexRange(mask_segment.size())) {
|
||||
const float length = sample_lengths[mask_segment[i]];
|
||||
length_parameterize::sample_at_length(accumulated_lengths,
|
||||
std::clamp(length, 0.0f, total_length),
|
||||
r_segment_indices[i],
|
||||
|
|
|
@ -63,11 +63,11 @@ class MF_SeparateXYZ : public mf::MultiFunction {
|
|||
}
|
||||
|
||||
devirtualize_varray(vectors, [&](auto vectors) {
|
||||
mask.to_best_mask_type([&](auto mask) {
|
||||
mask.foreach_span_or_range([&](const auto mask_segment) {
|
||||
const int used_outputs_num = used_outputs.size();
|
||||
const int *used_outputs_data = used_outputs.data();
|
||||
|
||||
for (const int64_t i : mask) {
|
||||
for (const int64_t i : mask_segment) {
|
||||
const float3 &vector = vectors[i];
|
||||
for (const int out_i : IndexRange(used_outputs_num)) {
|
||||
const int coordinate = used_outputs_data[out_i];
|
||||
|
|
Loading…
Reference in New Issue