Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Basnett <cmbasnett@gmail.com>2022-09-17 03:50:37 +0300
committerColin Basnett <cmbasnett@gmail.com>2022-09-17 03:50:37 +0300
commit564bda241a973396da51d7c3ccd9efd97d51728a (patch)
tree4d9aa4cccd82e2e606b47774afa5e1015bf14768 /source/blender/blenlib/intern/index_mask.cc
parent0fff238150d076576053c25b646f653d6e3b0edb (diff)
parent48d7ff68f0df209c77bbb081ab46fbc109fd825a (diff)
Merge branch 'master' into feature-imformatfeature-imformat
Diffstat (limited to 'source/blender/blenlib/intern/index_mask.cc')
-rw-r--r--source/blender/blenlib/intern/index_mask.cc52
1 files changed, 50 insertions, 2 deletions
diff --git a/source/blender/blenlib/intern/index_mask.cc b/source/blender/blenlib/intern/index_mask.cc
index 1e301bc5fb9..e9af183d60d 100644
--- a/source/blender/blenlib/intern/index_mask.cc
+++ b/source/blender/blenlib/intern/index_mask.cc
@@ -128,7 +128,9 @@ Vector<IndexRange> IndexMask::extract_ranges_invert(const IndexRange full_range,
} // namespace blender
-namespace blender::index_mask_ops::detail {
+namespace blender::index_mask_ops {
+
+namespace detail {
IndexMask find_indices_based_on_predicate__merge(
IndexMask indices_to_check,
@@ -140,6 +142,7 @@ IndexMask find_indices_based_on_predicate__merge(
int64_t result_mask_size = 0;
for (Vector<Vector<int64_t>> &local_sub_masks : sub_masks) {
for (Vector<int64_t> &sub_mask : local_sub_masks) {
+ BLI_assert(!sub_mask.is_empty());
all_vectors.append(&sub_mask);
result_mask_size += sub_mask.size();
}
@@ -193,4 +196,49 @@ IndexMask find_indices_based_on_predicate__merge(
return r_indices.as_span();
}
-} // namespace blender::index_mask_ops::detail
+} // namespace detail
+
+IndexMask find_indices_from_virtual_array(const IndexMask indices_to_check,
+ const VArray<bool> &virtual_array,
+ const int64_t parallel_grain_size,
+ Vector<int64_t> &r_indices)
+{
+ if (virtual_array.is_single()) {
+ return virtual_array.get_internal_single() ? indices_to_check : IndexMask(0);
+ }
+ if (virtual_array.is_span()) {
+ const Span<bool> span = virtual_array.get_internal_span();
+ return find_indices_based_on_predicate(
+ indices_to_check, 4096, r_indices, [&](const int64_t i) { return span[i]; });
+ }
+
+ threading::EnumerableThreadSpecific<Vector<bool>> materialize_buffers;
+ threading::EnumerableThreadSpecific<Vector<Vector<int64_t>>> sub_masks;
+
+ threading::parallel_for(
+ indices_to_check.index_range(), parallel_grain_size, [&](const IndexRange range) {
+ const IndexMask sliced_mask = indices_to_check.slice(range);
+
+ /* To avoid virtual function call overhead from accessing the virtual array,
+ * materialize the necessary indices for this chunk into a reused buffer. */
+ Vector<bool> &buffer = materialize_buffers.local();
+ buffer.reinitialize(sliced_mask.size());
+ virtual_array.materialize_compressed(sliced_mask, buffer);
+
+ Vector<int64_t> masked_indices;
+ sliced_mask.to_best_mask_type([&](auto best_mask) {
+ for (const int64_t i : IndexRange(best_mask.size())) {
+ if (buffer[i]) {
+ masked_indices.append(best_mask[i]);
+ }
+ }
+ });
+ if (!masked_indices.is_empty()) {
+ sub_masks.local().append(std::move(masked_indices));
+ }
+ });
+
+ return detail::find_indices_based_on_predicate__merge(indices_to_check, sub_masks, r_indices);
+}
+
+} // namespace blender::index_mask_ops