Blender  V3.3
FN_multi_function_params.hh
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #pragma once
4 
14 #include <mutex>
15 
16 #include "BLI_generic_pointer.hh"
19 #include "BLI_resource_scope.hh"
20 
22 
23 namespace blender::fn {
24 
26  private:
27  ResourceScope scope_;
28  const MFSignature *signature_;
29  IndexMask mask_;
30  int64_t min_array_size_;
31  Vector<GVArray> virtual_arrays_;
32  Vector<GMutableSpan> mutable_spans_;
33  Vector<const GVVectorArray *> virtual_vector_arrays_;
34  Vector<GVectorArray *> vector_arrays_;
35 
36  std::mutex mutex_;
37  Vector<std::pair<int, GMutableSpan>> dummy_output_spans_;
38 
39  friend class MFParams;
40 
41  MFParamsBuilder(const MFSignature &signature, const IndexMask mask)
42  : signature_(&signature), mask_(mask), min_array_size_(mask.min_array_size())
43  {
44  virtual_arrays_.reserve(signature.virtual_array_num);
45  mutable_spans_.reserve(signature.span_num);
46  virtual_vector_arrays_.reserve(signature.virtual_vector_array_num);
47  vector_arrays_.reserve(signature.vector_array_num);
48  }
49 
50  public:
56  MFParamsBuilder(const class MultiFunction &fn, const IndexMask *mask);
57 
58  template<typename T> void add_readonly_single_input_value(T value, StringRef expected_name = "")
59  {
60  this->assert_current_param_type(MFParamType::ForSingleInput(CPPType::get<T>()), expected_name);
61  virtual_arrays_.append_unchecked_as(
62  varray_tag::single{}, CPPType::get<T>(), min_array_size_, &value);
63  }
64  template<typename T> void add_readonly_single_input(const T *value, StringRef expected_name = "")
65  {
66  this->assert_current_param_type(MFParamType::ForSingleInput(CPPType::get<T>()), expected_name);
67  virtual_arrays_.append_unchecked_as(
68  varray_tag::single_ref{}, CPPType::get<T>(), min_array_size_, value);
69  }
70  void add_readonly_single_input(const GSpan span, StringRef expected_name = "")
71  {
72  this->assert_current_param_type(MFParamType::ForSingleInput(span.type()), expected_name);
73  BLI_assert(span.size() >= min_array_size_);
74  virtual_arrays_.append_unchecked_as(varray_tag::span{}, span);
75  }
76  void add_readonly_single_input(GPointer value, StringRef expected_name = "")
77  {
78  this->assert_current_param_type(MFParamType::ForSingleInput(*value.type()), expected_name);
79  virtual_arrays_.append_unchecked_as(
80  varray_tag::single_ref{}, *value.type(), min_array_size_, value.get());
81  }
82  void add_readonly_single_input(GVArray varray, StringRef expected_name = "")
83  {
84  this->assert_current_param_type(MFParamType::ForSingleInput(varray.type()), expected_name);
85  BLI_assert(varray.size() >= min_array_size_);
86  virtual_arrays_.append_unchecked_as(std::move(varray));
87  }
88 
89  void add_readonly_vector_input(const GVectorArray &vector_array, StringRef expected_name = "")
90  {
92  expected_name);
93  }
94  void add_readonly_vector_input(const GSpan single_vector, StringRef expected_name = "")
95  {
97  scope_.construct<GVVectorArray_For_SingleGSpan>(single_vector, min_array_size_),
98  expected_name);
99  }
100  void add_readonly_vector_input(const GVVectorArray &ref, StringRef expected_name = "")
101  {
102  this->assert_current_param_type(MFParamType::ForVectorInput(ref.type()), expected_name);
103  BLI_assert(ref.size() >= min_array_size_);
104  virtual_vector_arrays_.append_unchecked(&ref);
105  }
106 
107  template<typename T> void add_uninitialized_single_output(T *value, StringRef expected_name = "")
108  {
109  this->add_uninitialized_single_output(GMutableSpan(CPPType::get<T>(), value, 1),
110  expected_name);
111  }
113  {
114  this->assert_current_param_type(MFParamType::ForSingleOutput(ref.type()), expected_name);
115  BLI_assert(ref.size() >= min_array_size_);
116  mutable_spans_.append_unchecked(ref);
117  }
118  void add_ignored_single_output(StringRef expected_name = "")
119  {
120  this->assert_current_param_name(expected_name);
121  const int param_index = this->current_param_index();
122  const MFParamType &param_type = signature_->param_types[param_index];
124  const CPPType &type = param_type.data_type().single_type();
125  /* An empty span indicates that this is ignored. */
126  const GMutableSpan dummy_span{type};
127  mutable_spans_.append_unchecked(dummy_span);
128  }
129 
130  void add_vector_output(GVectorArray &vector_array, StringRef expected_name = "")
131  {
132  this->assert_current_param_type(MFParamType::ForVectorOutput(vector_array.type()),
133  expected_name);
134  BLI_assert(vector_array.size() >= min_array_size_);
135  vector_arrays_.append_unchecked(&vector_array);
136  }
137 
138  void add_single_mutable(GMutableSpan ref, StringRef expected_name = "")
139  {
140  this->assert_current_param_type(MFParamType::ForMutableSingle(ref.type()), expected_name);
141  BLI_assert(ref.size() >= min_array_size_);
142  mutable_spans_.append_unchecked(ref);
143  }
144 
145  void add_vector_mutable(GVectorArray &vector_array, StringRef expected_name = "")
146  {
147  this->assert_current_param_type(MFParamType::ForMutableVector(vector_array.type()),
148  expected_name);
149  BLI_assert(vector_array.size() >= min_array_size_);
150  vector_arrays_.append_unchecked(&vector_array);
151  }
152 
153  GMutableSpan computed_array(int param_index)
154  {
155  BLI_assert(ELEM(signature_->param_types[param_index].category(),
158  int data_index = signature_->data_index(param_index);
159  return mutable_spans_[data_index];
160  }
161 
163  {
164  BLI_assert(ELEM(signature_->param_types[param_index].category(),
167  int data_index = signature_->data_index(param_index);
168  return *vector_arrays_[data_index];
169  }
170 
172  {
173  return scope_;
174  }
175 
176  private:
177  void assert_current_param_type(MFParamType param_type, StringRef expected_name = "")
178  {
179  UNUSED_VARS_NDEBUG(param_type, expected_name);
180 #ifdef DEBUG
181  int param_index = this->current_param_index();
182 
183  if (expected_name != "") {
184  StringRef actual_name = signature_->param_names[param_index];
185  BLI_assert(actual_name == expected_name);
186  }
187 
188  MFParamType expected_type = signature_->param_types[param_index];
189  BLI_assert(expected_type == param_type);
190 #endif
191  }
192 
193  void assert_current_param_name(StringRef expected_name)
194  {
195  UNUSED_VARS_NDEBUG(expected_name);
196 #ifdef DEBUG
197  if (expected_name.is_empty()) {
198  return;
199  }
200  const int param_index = this->current_param_index();
201  StringRef actual_name = signature_->param_names[param_index];
202  BLI_assert(actual_name == expected_name);
203 #endif
204  }
205 
206  int current_param_index() const
207  {
208  return virtual_arrays_.size() + mutable_spans_.size() + virtual_vector_arrays_.size() +
209  vector_arrays_.size();
210  }
211 };
212 
213 class MFParams {
214  private:
215  MFParamsBuilder *builder_;
216 
217  public:
218  MFParams(MFParamsBuilder &builder) : builder_(&builder)
219  {
220  }
221 
222  template<typename T> VArray<T> readonly_single_input(int param_index, StringRef name = "")
223  {
224  const GVArray &varray = this->readonly_single_input(param_index, name);
225  return varray.typed<T>();
226  }
227  const GVArray &readonly_single_input(int param_index, StringRef name = "")
228  {
229  this->assert_correct_param(param_index, name, MFParamCategory::SingleInput);
230  int data_index = builder_->signature_->data_index(param_index);
231  return builder_->virtual_arrays_[data_index];
232  }
233 
240  bool single_output_is_required(int param_index, StringRef name = "")
241  {
242  this->assert_correct_param(param_index, name, MFParamCategory::SingleOutput);
243  int data_index = builder_->signature_->data_index(param_index);
244  return !builder_->mutable_spans_[data_index].is_empty();
245  }
246 
247  template<typename T>
249  {
250  return this->uninitialized_single_output(param_index, name).typed<T>();
251  }
253  {
254  this->assert_correct_param(param_index, name, MFParamCategory::SingleOutput);
255  int data_index = builder_->signature_->data_index(param_index);
256  GMutableSpan span = builder_->mutable_spans_[data_index];
257  if (!span.is_empty()) {
258  return span;
259  }
260  /* The output is ignored by the caller, but the multi-function does not handle this case. So
261  * create a temporary buffer that the multi-function can write to. */
262  return this->ensure_dummy_single_output(data_index);
263  }
264 
269  template<typename T>
271  {
272  return this->uninitialized_single_output_if_required(param_index, name).typed<T>();
273  }
275  {
276  this->assert_correct_param(param_index, name, MFParamCategory::SingleOutput);
277  int data_index = builder_->signature_->data_index(param_index);
278  return builder_->mutable_spans_[data_index];
279  }
280 
281  template<typename T>
282  const VVectorArray<T> &readonly_vector_input(int param_index, StringRef name = "")
283  {
284  const GVVectorArray &vector_array = this->readonly_vector_input(param_index, name);
285  return builder_->scope_.construct<VVectorArray_For_GVVectorArray<T>>(vector_array);
286  }
287  const GVVectorArray &readonly_vector_input(int param_index, StringRef name = "")
288  {
289  this->assert_correct_param(param_index, name, MFParamCategory::VectorInput);
290  int data_index = builder_->signature_->data_index(param_index);
291  return *builder_->virtual_vector_arrays_[data_index];
292  }
293 
294  template<typename T>
296  {
297  return {this->vector_output(param_index, name)};
298  }
299  GVectorArray &vector_output(int param_index, StringRef name = "")
300  {
301  this->assert_correct_param(param_index, name, MFParamCategory::VectorOutput);
302  int data_index = builder_->signature_->data_index(param_index);
303  return *builder_->vector_arrays_[data_index];
304  }
305 
306  template<typename T> MutableSpan<T> single_mutable(int param_index, StringRef name = "")
307  {
308  return this->single_mutable(param_index, name).typed<T>();
309  }
310  GMutableSpan single_mutable(int param_index, StringRef name = "")
311  {
312  this->assert_correct_param(param_index, name, MFParamCategory::SingleMutable);
313  int data_index = builder_->signature_->data_index(param_index);
314  return builder_->mutable_spans_[data_index];
315  }
316 
317  template<typename T>
319  {
320  return {this->vector_mutable(param_index, name)};
321  }
322  GVectorArray &vector_mutable(int param_index, StringRef name = "")
323  {
324  this->assert_correct_param(param_index, name, MFParamCategory::VectorMutable);
325  int data_index = builder_->signature_->data_index(param_index);
326  return *builder_->vector_arrays_[data_index];
327  }
328 
329  private:
330  void assert_correct_param(int param_index, StringRef name, MFParamType param_type)
331  {
332  UNUSED_VARS_NDEBUG(param_index, name, param_type);
333 #ifdef DEBUG
334  BLI_assert(builder_->signature_->param_types[param_index] == param_type);
335  if (name.size() > 0) {
336  BLI_assert(builder_->signature_->param_names[param_index] == name);
337  }
338 #endif
339  }
340 
341  void assert_correct_param(int param_index, StringRef name, MFParamCategory category)
342  {
343  UNUSED_VARS_NDEBUG(param_index, name, category);
344 #ifdef DEBUG
345  BLI_assert(builder_->signature_->param_types[param_index].category() == category);
346  if (name.size() > 0) {
347  BLI_assert(builder_->signature_->param_names[param_index] == name);
348  }
349 #endif
350  }
351 
352  GMutableSpan ensure_dummy_single_output(int data_index);
353 };
354 
355 } // namespace blender::fn
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define UNUSED_VARS_NDEBUG(...)
#define ELEM(...)
ThreadMutex mutex
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
const CPPType & type() const
const void * get() const
const CPPType * type() const
const CPPType & type() const
int64_t size() const
const CPPType & type() const
VArray< T > typed() const
const CPPType & type() const
T & construct(Args &&...args)
constexpr int64_t size() const
int64_t size() const
Definition: BLI_vector.hh:694
void append_unchecked_as(ForwardT &&...value)
Definition: BLI_vector.hh:492
void append_unchecked(const T &value)
Definition: BLI_vector.hh:484
void reserve(const int64_t min_capacity)
Definition: BLI_vector.hh:340
const CPPType & single_type() const
static MFParamType ForVectorInput(const CPPType &base_type)
static MFParamType ForSingleOutput(const CPPType &type)
static MFParamType ForMutableSingle(const CPPType &type)
static MFParamType ForVectorOutput(const CPPType &base_type)
static MFParamType ForMutableVector(const CPPType &base_type)
static MFParamType ForSingleInput(const CPPType &type)
void add_uninitialized_single_output(GMutableSpan ref, StringRef expected_name="")
MFParamsBuilder(const class MultiFunction &fn, const IndexMask *mask)
void add_readonly_vector_input(const GSpan single_vector, StringRef expected_name="")
void add_readonly_single_input(const GSpan span, StringRef expected_name="")
void add_readonly_vector_input(const GVVectorArray &ref, StringRef expected_name="")
void add_readonly_single_input(GPointer value, StringRef expected_name="")
void add_uninitialized_single_output(T *value, StringRef expected_name="")
void add_vector_mutable(GVectorArray &vector_array, StringRef expected_name="")
MFParamsBuilder(const class MultiFunction &fn, int64_t size)
void add_readonly_single_input(GVArray varray, StringRef expected_name="")
GVectorArray & computed_vector_array(int param_index)
void add_vector_output(GVectorArray &vector_array, StringRef expected_name="")
void add_readonly_vector_input(const GVectorArray &vector_array, StringRef expected_name="")
void add_readonly_single_input_value(T value, StringRef expected_name="")
void add_ignored_single_output(StringRef expected_name="")
void add_single_mutable(GMutableSpan ref, StringRef expected_name="")
GMutableSpan computed_array(int param_index)
void add_readonly_single_input(const T *value, StringRef expected_name="")
MutableSpan< T > uninitialized_single_output(int param_index, StringRef name="")
GVectorArray_TypedMutableRef< T > vector_output(int param_index, StringRef name="")
bool single_output_is_required(int param_index, StringRef name="")
const GVVectorArray & readonly_vector_input(int param_index, StringRef name="")
const VVectorArray< T > & readonly_vector_input(int param_index, StringRef name="")
MutableSpan< T > single_mutable(int param_index, StringRef name="")
GVectorArray & vector_mutable(int param_index, StringRef name="")
MFParams(MFParamsBuilder &builder)
GMutableSpan uninitialized_single_output_if_required(int param_index, StringRef name="")
MutableSpan< T > uninitialized_single_output_if_required(int param_index, StringRef name="")
const GVArray & readonly_single_input(int param_index, StringRef name="")
GMutableSpan single_mutable(int param_index, StringRef name="")
VArray< T > readonly_single_input(int param_index, StringRef name="")
GMutableSpan uninitialized_single_output(int param_index, StringRef name="")
GVectorArray_TypedMutableRef< T > vector_mutable(int param_index, StringRef name="")
GVectorArray & vector_output(int param_index, StringRef name="")
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
#define T
__int64 int64_t
Definition: stdint.h:89
int data_index(int param_index) const