Blender V4.3
BLI_task_size_hints.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#pragma once
6
11#include <optional>
12
13#include "BLI_index_range.hh"
14#include "BLI_span.hh"
15#include "BLI_utildefines.h"
16
17namespace blender::threading {
18
26 public:
27 enum class Type {
29 Static,
37 };
38
40
41 protected:
42 TaskSizeHints(const Type type) : type(type) {}
43};
44
45namespace detail {
46
48 public:
50
51 TaskSizeHints_Static(const int64_t size) : TaskSizeHints(Type::Static), size(size) {}
52};
53
55 public:
56 std::optional<int64_t> full_size;
57
62
64 virtual void lookup_individual_sizes(IndexRange /*range*/,
65 MutableSpan<int64_t> r_sizes) const = 0;
66};
67
75
76template<typename Fn>
78 private:
79 Fn fn_;
80
81 public:
82 TaskSizeHints_IndividualLookupFn(Fn fn, const std::optional<int64_t> full_size)
83 : TaskSizeHints_IndividualLookup(full_size), fn_(std::move(fn))
84 {
85 }
86
87 void lookup_individual_sizes(const IndexRange range, MutableSpan<int64_t> r_sizes) const override
88 {
89 fn_(range, r_sizes);
90 }
91};
92
93template<typename Fn>
95 private:
96 Fn fn_;
97
98 public:
100 {
101 }
102
103 int64_t lookup_accumulated_size(const IndexRange range) const override
104 {
105 return fn_(range);
106 }
107};
108
109} // namespace detail
110
111inline bool use_single_thread(const TaskSizeHints &size_hints,
112 const IndexRange range,
113 const int64_t threshold)
114{
115#ifdef __GNUC__ /* False positive warning with GCC. */
116# pragma GCC diagnostic push
117# pragma GCC diagnostic ignored "-Warray-bounds"
118#endif
119 switch (size_hints.type) {
121 const int64_t size = static_cast<const detail::TaskSizeHints_Static &>(size_hints).size;
122 return size * range.size() <= threshold;
123 }
125 const std::optional<int64_t> &full_size =
126 static_cast<const detail::TaskSizeHints_IndividualLookup &>(size_hints).full_size;
127 if (full_size.has_value()) {
128 if (*full_size <= threshold) {
129 return true;
130 }
131 }
132 return false;
133 }
135 const int64_t accumulated_size =
136 static_cast<const detail::TaskSizeHints_AccumulatedLookup &>(size_hints)
137 .lookup_accumulated_size(range);
138 return accumulated_size <= threshold;
139 }
140 }
141#ifdef __GNUC__
142# pragma GCC diagnostic pop
143#endif
145 return true;
146}
147
157template<typename Fn>
158inline auto individual_task_sizes(Fn &&fn, const std::optional<int64_t> full_size = std::nullopt)
159{
160 auto array_fn = [fn = std::forward<Fn>(fn)](const IndexRange range,
161 MutableSpan<int64_t> r_sizes) {
162 for (const int64_t i : range.index_range()) {
163 r_sizes[i] = fn(range[i]);
164 }
165 };
167 full_size);
168}
169
178template<typename Fn> inline auto accumulated_task_sizes(Fn &&fn)
179{
181}
182
183} // namespace blender::threading
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
int64_t lookup_accumulated_size(const IndexRange range) const override
virtual int64_t lookup_accumulated_size(IndexRange range) const =0
TaskSizeHints_IndividualLookupFn(Fn fn, const std::optional< int64_t > full_size)
void lookup_individual_sizes(const IndexRange range, MutableSpan< int64_t > r_sizes) const override
TaskSizeHints_IndividualLookup(std::optional< int64_t > full_size)
virtual void lookup_individual_sizes(IndexRange, MutableSpan< int64_t > r_sizes) const =0
IndexRange range
auto individual_task_sizes(Fn &&fn, const std::optional< int64_t > full_size=std::nullopt)
auto accumulated_task_sizes(Fn &&fn)
bool use_single_thread(const TaskSizeHints &size_hints, const IndexRange range, const int64_t threshold)
__int64 int64_t
Definition stdint.h:89