Blender  V2.93
multi_function_network_evaluation.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
39 
40 #include "BLI_resource_scope.hh"
41 #include "BLI_stack.hh"
42 
43 namespace blender::fn {
44 
45 struct Value;
46 
55  private:
56  LinearAllocator<> allocator_;
57  IndexMask mask_;
58  Array<Value *> value_per_output_id_;
59  int64_t min_array_size_;
60 
61  public:
62  MFNetworkEvaluationStorage(IndexMask mask, int socket_id_amount);
64 
65  /* Add the values that have been provided by the caller of the multi-function network. */
66  void add_single_input_from_caller(const MFOutputSocket &socket, const GVArray &virtual_array);
68  const GVVectorArray &virtual_vector_array);
70  void add_vector_output_from_caller(const MFOutputSocket &socket, GVectorArray &vector_array);
71 
72  /* Get input buffers for function node evaluations. */
73  const GVArray &get_single_input__full(const MFInputSocket &socket, ResourceScope &scope);
74  const GVArray &get_single_input__single(const MFInputSocket &socket, ResourceScope &scope);
77 
78  /* Get output buffers for function node evaluations. */
83 
84  /* Get mutable buffers for function node evaluations. */
86  const MFOutputSocket &output,
87  ResourceScope &scope);
89  const MFOutputSocket &output,
90  ResourceScope &scope);
92  const MFOutputSocket &output,
93  ResourceScope &scope);
95  const MFOutputSocket &output,
96  ResourceScope &scope);
97 
98  /* Mark a node as being done with evaluation. This might free temporary buffers that are no
99  * longer needed. */
100  void finish_node(const MFFunctionNode &node);
101  void finish_output_socket(const MFOutputSocket &socket);
102  void finish_input_socket(const MFInputSocket &socket);
103 
104  IndexMask mask() const;
105  bool socket_is_computed(const MFOutputSocket &socket);
106  bool is_same_value_for_every_index(const MFOutputSocket &socket);
107  bool socket_has_buffer_for_output(const MFOutputSocket &socket);
108 };
109 
112  : inputs_(std::move(inputs)), outputs_(std::move(outputs))
113 {
114  BLI_assert(outputs_.size() > 0);
115  MFSignatureBuilder signature{"Function Tree"};
116 
117  for (const MFOutputSocket *socket : inputs_) {
118  BLI_assert(socket->node().is_dummy());
119 
120  MFDataType type = socket->data_type();
121  switch (type.category()) {
122  case MFDataType::Single:
123  signature.single_input(socket->name(), type.single_type());
124  break;
125  case MFDataType::Vector:
126  signature.vector_input(socket->name(), type.vector_base_type());
127  break;
128  }
129  }
130 
131  for (const MFInputSocket *socket : outputs_) {
132  BLI_assert(socket->node().is_dummy());
133 
134  MFDataType type = socket->data_type();
135  switch (type.category()) {
136  case MFDataType::Single:
137  signature.single_output(socket->name(), type.single_type());
138  break;
139  case MFDataType::Vector:
140  signature.vector_output(socket->name(), type.vector_base_type());
141  break;
142  }
143  }
144 
145  signature_ = signature.build();
146  this->set_signature(&signature_);
147 }
148 
150 {
151  if (mask.size() == 0) {
152  return;
153  }
154 
155  const MFNetwork &network = outputs_[0]->node().network();
156  Storage storage(mask, network.socket_id_amount());
157 
158  Vector<const MFInputSocket *> outputs_to_initialize_in_the_end;
159 
160  this->copy_inputs_to_storage(params, storage);
161  this->copy_outputs_to_storage(params, storage, outputs_to_initialize_in_the_end);
162  this->evaluate_network_to_compute_outputs(context, storage);
163  this->initialize_remaining_outputs(params, storage, outputs_to_initialize_in_the_end);
164 }
165 
166 BLI_NOINLINE void MFNetworkEvaluator::copy_inputs_to_storage(MFParams params,
167  Storage &storage) const
168 {
169  for (int input_index : inputs_.index_range()) {
170  int param_index = input_index + 0;
171  const MFOutputSocket &socket = *inputs_[input_index];
172  switch (socket.data_type().category()) {
173  case MFDataType::Single: {
174  const GVArray &input_list = params.readonly_single_input(param_index);
175  storage.add_single_input_from_caller(socket, input_list);
176  break;
177  }
178  case MFDataType::Vector: {
179  const GVVectorArray &input_list_list = params.readonly_vector_input(param_index);
180  storage.add_vector_input_from_caller(socket, input_list_list);
181  break;
182  }
183  }
184  }
185 }
186 
187 BLI_NOINLINE void MFNetworkEvaluator::copy_outputs_to_storage(
188  MFParams params,
189  Storage &storage,
190  Vector<const MFInputSocket *> &outputs_to_initialize_in_the_end) const
191 {
192  for (int output_index : outputs_.index_range()) {
193  int param_index = output_index + inputs_.size();
194  const MFInputSocket &socket = *outputs_[output_index];
195  const MFOutputSocket &origin = *socket.origin();
196 
197  if (origin.node().is_dummy()) {
198  BLI_assert(inputs_.contains(&origin));
199  /* Don't overwrite input buffers. */
200  outputs_to_initialize_in_the_end.append(&socket);
201  continue;
202  }
203 
204  if (storage.socket_has_buffer_for_output(origin)) {
205  /* When two outputs will be initialized to the same values. */
206  outputs_to_initialize_in_the_end.append(&socket);
207  continue;
208  }
209 
210  switch (socket.data_type().category()) {
211  case MFDataType::Single: {
212  GMutableSpan span = params.uninitialized_single_output(param_index);
213  storage.add_single_output_from_caller(origin, span);
214  break;
215  }
216  case MFDataType::Vector: {
217  GVectorArray &vector_array = params.vector_output(param_index);
218  storage.add_vector_output_from_caller(origin, vector_array);
219  break;
220  }
221  }
222  }
223 }
224 
225 BLI_NOINLINE void MFNetworkEvaluator::evaluate_network_to_compute_outputs(
226  MFContext &global_context, Storage &storage) const
227 {
228  Stack<const MFOutputSocket *, 32> sockets_to_compute;
229  for (const MFInputSocket *socket : outputs_) {
230  sockets_to_compute.push(socket->origin());
231  }
232 
233  /* This is the main loop that traverses the MFNetwork. */
234  while (!sockets_to_compute.is_empty()) {
235  const MFOutputSocket &socket = *sockets_to_compute.peek();
236  const MFNode &node = socket.node();
237 
238  if (storage.socket_is_computed(socket)) {
239  sockets_to_compute.pop();
240  continue;
241  }
242 
243  BLI_assert(node.is_function());
244  BLI_assert(!node.has_unlinked_inputs());
245  const MFFunctionNode &function_node = node.as_function();
246 
247  bool all_origins_are_computed = true;
248  for (const MFInputSocket *input_socket : function_node.inputs()) {
249  const MFOutputSocket *origin = input_socket->origin();
250  if (origin != nullptr) {
251  if (!storage.socket_is_computed(*origin)) {
252  sockets_to_compute.push(origin);
253  all_origins_are_computed = false;
254  }
255  }
256  }
257 
258  if (all_origins_are_computed) {
259  this->evaluate_function(global_context, function_node, storage);
260  sockets_to_compute.pop();
261  }
262  }
263 }
264 
265 BLI_NOINLINE void MFNetworkEvaluator::evaluate_function(MFContext &global_context,
266  const MFFunctionNode &function_node,
267  Storage &storage) const
268 {
269 
270  const MultiFunction &function = function_node.function();
271  // std::cout << "Function: " << function.name() << "\n";
272 
273  if (this->can_do_single_value_evaluation(function_node, storage)) {
274  /* The function output would be the same for all elements. Therefore, it is enough to call the
275  * function only on a single element. This can avoid many duplicate computations. */
276  MFParamsBuilder params{function, 1};
277  ResourceScope &scope = params.resource_scope();
278 
279  for (int param_index : function.param_indices()) {
280  MFParamType param_type = function.param_type(param_index);
281  switch (param_type.category()) {
283  const MFInputSocket &socket = function_node.input_for_param(param_index);
284  const GVArray &values = storage.get_single_input__single(socket, scope);
285  params.add_readonly_single_input(values);
286  break;
287  }
289  const MFInputSocket &socket = function_node.input_for_param(param_index);
290  const GVVectorArray &values = storage.get_vector_input__single(socket, scope);
291  params.add_readonly_vector_input(values);
292  break;
293  }
295  const MFOutputSocket &socket = function_node.output_for_param(param_index);
296  GMutableSpan values = storage.get_single_output__single(socket);
297  params.add_uninitialized_single_output(values);
298  break;
299  }
301  const MFOutputSocket &socket = function_node.output_for_param(param_index);
302  GVectorArray &values = storage.get_vector_output__single(socket);
303  params.add_vector_output(values);
304  break;
305  }
307  const MFInputSocket &input = function_node.input_for_param(param_index);
308  const MFOutputSocket &output = function_node.output_for_param(param_index);
309  GMutableSpan values = storage.get_mutable_single__single(input, output, scope);
310  params.add_single_mutable(values);
311  break;
312  }
314  const MFInputSocket &input = function_node.input_for_param(param_index);
315  const MFOutputSocket &output = function_node.output_for_param(param_index);
316  GVectorArray &values = storage.get_mutable_vector__single(input, output, scope);
317  params.add_vector_mutable(values);
318  break;
319  }
320  }
321  }
322 
323  function.call(IndexRange(1), params, global_context);
324  }
325  else {
326  MFParamsBuilder params{function, storage.mask().min_array_size()};
327  ResourceScope &scope = params.resource_scope();
328 
329  for (int param_index : function.param_indices()) {
330  MFParamType param_type = function.param_type(param_index);
331  switch (param_type.category()) {
333  const MFInputSocket &socket = function_node.input_for_param(param_index);
334  const GVArray &values = storage.get_single_input__full(socket, scope);
335  params.add_readonly_single_input(values);
336  break;
337  }
339  const MFInputSocket &socket = function_node.input_for_param(param_index);
340  const GVVectorArray &values = storage.get_vector_input__full(socket, scope);
341  params.add_readonly_vector_input(values);
342  break;
343  }
345  const MFOutputSocket &socket = function_node.output_for_param(param_index);
346  GMutableSpan values = storage.get_single_output__full(socket);
347  params.add_uninitialized_single_output(values);
348  break;
349  }
351  const MFOutputSocket &socket = function_node.output_for_param(param_index);
352  GVectorArray &values = storage.get_vector_output__full(socket);
353  params.add_vector_output(values);
354  break;
355  }
357  const MFInputSocket &input = function_node.input_for_param(param_index);
358  const MFOutputSocket &output = function_node.output_for_param(param_index);
359  GMutableSpan values = storage.get_mutable_single__full(input, output, scope);
360  params.add_single_mutable(values);
361  break;
362  }
364  const MFInputSocket &input = function_node.input_for_param(param_index);
365  const MFOutputSocket &output = function_node.output_for_param(param_index);
366  GVectorArray &values = storage.get_mutable_vector__full(input, output, scope);
367  params.add_vector_mutable(values);
368  break;
369  }
370  }
371  }
372 
373  function.call(storage.mask(), params, global_context);
374  }
375 
376  storage.finish_node(function_node);
377 }
378 
379 bool MFNetworkEvaluator::can_do_single_value_evaluation(const MFFunctionNode &function_node,
380  Storage &storage) const
381 {
382  for (const MFInputSocket *socket : function_node.inputs()) {
383  if (!storage.is_same_value_for_every_index(*socket->origin())) {
384  return false;
385  }
386  }
387  if (storage.mask().min_array_size() >= 1) {
388  for (const MFOutputSocket *socket : function_node.outputs()) {
389  if (storage.socket_has_buffer_for_output(*socket)) {
390  return false;
391  }
392  }
393  }
394  return true;
395 }
396 
397 BLI_NOINLINE void MFNetworkEvaluator::initialize_remaining_outputs(
398  MFParams params, Storage &storage, Span<const MFInputSocket *> remaining_outputs) const
399 {
400  ResourceScope scope;
401  for (const MFInputSocket *socket : remaining_outputs) {
402  int param_index = inputs_.size() + outputs_.first_index_of(socket);
403 
404  switch (socket->data_type().category()) {
405  case MFDataType::Single: {
406  const GVArray &values = storage.get_single_input__full(*socket, scope);
407  GMutableSpan output_values = params.uninitialized_single_output(param_index);
408  values.materialize_to_uninitialized(storage.mask(), output_values.data());
409  break;
410  }
411  case MFDataType::Vector: {
412  const GVVectorArray &values = storage.get_vector_input__full(*socket, scope);
413  GVectorArray &output_values = params.vector_output(param_index);
414  output_values.extend(storage.mask(), values);
415  break;
416  }
417  }
418  }
419 }
420 
421 /* -------------------------------------------------------------------- */
425 enum class ValueType {
426  InputSingle,
427  InputVector,
428  OutputSingle,
429  OutputVector,
430  OwnSingle,
431  OwnVector,
432 };
433 
434 struct Value {
436 
438  {
439  }
440 };
441 
442 struct InputSingleValue : public Value {
445 
448  {
449  }
450 };
451 
452 struct InputVectorValue : public Value {
455 
458  {
459  }
460 };
461 
462 struct OutputValue : public Value {
463  bool is_computed = false;
464 
466  {
467  }
468 };
469 
473 
475  {
476  }
477 };
478 
482 
485  {
486  }
487 };
488 
489 struct OwnSingleValue : public Value {
495 
498  span(span),
501  {
502  }
503 };
504 
505 struct OwnVectorValue : public Value {
510 
515  {
516  }
517 };
518 
521 /* -------------------------------------------------------------------- */
526  : mask_(mask),
527  value_per_output_id_(socket_id_amount, nullptr),
528  min_array_size_(mask.min_array_size())
529 {
530 }
531 
533 {
534  for (Value *any_value : value_per_output_id_) {
535  if (any_value == nullptr) {
536  continue;
537  }
538  if (any_value->type == ValueType::OwnSingle) {
539  OwnSingleValue *value = static_cast<OwnSingleValue *>(any_value);
540  GMutableSpan span = value->span;
541  const CPPType &type = span.type();
542  if (value->is_single_allocated) {
543  type.destruct(span.data());
544  }
545  else {
546  type.destruct_indices(span.data(), mask_);
547  MEM_freeN(span.data());
548  }
549  }
550  else if (any_value->type == ValueType::OwnVector) {
551  OwnVectorValue *value = static_cast<OwnVectorValue *>(any_value);
552  delete value->vector_array;
553  }
554  }
555 }
556 
558 {
559  return mask_;
560 }
561 
563 {
564  Value *any_value = value_per_output_id_[socket.id()];
565  if (any_value == nullptr) {
566  return false;
567  }
569  return static_cast<OutputValue *>(any_value)->is_computed;
570  }
571  return true;
572 }
573 
575 {
576  Value *any_value = value_per_output_id_[socket.id()];
577  switch (any_value->type) {
579  return static_cast<OwnSingleValue *>(any_value)->span.size() == 1;
581  return static_cast<OwnVectorValue *>(any_value)->vector_array->size() == 1;
583  return static_cast<InputSingleValue *>(any_value)->virtual_array.is_single();
585  return static_cast<InputVectorValue *>(any_value)->virtual_vector_array.is_single_vector();
587  return static_cast<OutputSingleValue *>(any_value)->span.size() == 1;
589  return static_cast<OutputVectorValue *>(any_value)->vector_array->size() == 1;
590  }
591  BLI_assert(false);
592  return false;
593 }
594 
596 {
597  Value *any_value = value_per_output_id_[socket.id()];
598  if (any_value == nullptr) {
599  return false;
600  }
601 
603  return true;
604 }
605 
607 {
608  for (const MFInputSocket *socket : node.inputs()) {
609  this->finish_input_socket(*socket);
610  }
611  for (const MFOutputSocket *socket : node.outputs()) {
612  this->finish_output_socket(*socket);
613  }
614 }
615 
617 {
618  Value *any_value = value_per_output_id_[socket.id()];
619  if (any_value == nullptr) {
620  return;
621  }
622 
624  static_cast<OutputValue *>(any_value)->is_computed = true;
625  }
626 }
627 
629 {
630  const MFOutputSocket &origin = *socket.origin();
631 
632  Value *any_value = value_per_output_id_[origin.id()];
633  if (any_value == nullptr) {
634  /* Can happen when a value has been forward to the next node. */
635  return;
636  }
637 
638  switch (any_value->type) {
643  break;
644  }
645  case ValueType::OwnSingle: {
646  OwnSingleValue *value = static_cast<OwnSingleValue *>(any_value);
647  BLI_assert(value->max_remaining_users >= 1);
648  value->max_remaining_users--;
649  if (value->max_remaining_users == 0) {
650  GMutableSpan span = value->span;
651  const CPPType &type = span.type();
652  if (value->is_single_allocated) {
653  type.destruct(span.data());
654  }
655  else {
656  type.destruct_indices(span.data(), mask_);
657  MEM_freeN(span.data());
658  }
659  value_per_output_id_[origin.id()] = nullptr;
660  }
661  break;
662  }
663  case ValueType::OwnVector: {
664  OwnVectorValue *value = static_cast<OwnVectorValue *>(any_value);
665  BLI_assert(value->max_remaining_users >= 1);
666  value->max_remaining_users--;
667  if (value->max_remaining_users == 0) {
668  delete value->vector_array;
669  value_per_output_id_[origin.id()] = nullptr;
670  }
671  break;
672  }
673  }
674 }
675 
677  const GVArray &virtual_array)
678 {
679  BLI_assert(value_per_output_id_[socket.id()] == nullptr);
680  BLI_assert(virtual_array.size() >= min_array_size_);
681 
682  auto *value = allocator_.construct<InputSingleValue>(virtual_array).release();
683  value_per_output_id_[socket.id()] = value;
684 }
685 
687  const MFOutputSocket &socket, const GVVectorArray &virtual_vector_array)
688 {
689  BLI_assert(value_per_output_id_[socket.id()] == nullptr);
690  BLI_assert(virtual_vector_array.size() >= min_array_size_);
691 
692  auto *value = allocator_.construct<InputVectorValue>(virtual_vector_array).release();
693  value_per_output_id_[socket.id()] = value;
694 }
695 
697  GMutableSpan span)
698 {
699  BLI_assert(value_per_output_id_[socket.id()] == nullptr);
700  BLI_assert(span.size() >= min_array_size_);
701 
702  auto *value = allocator_.construct<OutputSingleValue>(span).release();
703  value_per_output_id_[socket.id()] = value;
704 }
705 
707  GVectorArray &vector_array)
708 {
709  BLI_assert(value_per_output_id_[socket.id()] == nullptr);
710  BLI_assert(vector_array.size() >= min_array_size_);
711 
712  auto *value = allocator_.construct<OutputVectorValue>(vector_array).release();
713  value_per_output_id_[socket.id()] = value;
714 }
715 
717 {
718  Value *any_value = value_per_output_id_[socket.id()];
719  if (any_value == nullptr) {
720  const CPPType &type = socket.data_type().single_type();
721  void *buffer = MEM_mallocN_aligned(min_array_size_ * type.size(), type.alignment(), AT);
722  GMutableSpan span(type, buffer, min_array_size_);
723 
724  auto *value =
725  allocator_.construct<OwnSingleValue>(span, socket.targets().size(), false).release();
726  value_per_output_id_[socket.id()] = value;
727 
728  return span;
729  }
730 
731  BLI_assert(any_value->type == ValueType::OutputSingle);
732  return static_cast<OutputSingleValue *>(any_value)->span;
733 }
734 
736 {
737  Value *any_value = value_per_output_id_[socket.id()];
738  if (any_value == nullptr) {
739  const CPPType &type = socket.data_type().single_type();
740  void *buffer = allocator_.allocate(type.size(), type.alignment());
741  GMutableSpan span(type, buffer, 1);
742 
743  auto *value =
744  allocator_.construct<OwnSingleValue>(span, socket.targets().size(), true).release();
745  value_per_output_id_[socket.id()] = value;
746 
747  return value->span;
748  }
749 
750  BLI_assert(any_value->type == ValueType::OutputSingle);
751  GMutableSpan span = static_cast<OutputSingleValue *>(any_value)->span;
752  BLI_assert(span.size() == 1);
753  return span;
754 }
755 
757 {
758  Value *any_value = value_per_output_id_[socket.id()];
759  if (any_value == nullptr) {
760  const CPPType &type = socket.data_type().vector_base_type();
761  GVectorArray *vector_array = new GVectorArray(type, min_array_size_);
762 
763  auto *value =
764  allocator_.construct<OwnVectorValue>(*vector_array, socket.targets().size()).release();
765  value_per_output_id_[socket.id()] = value;
766 
767  return *value->vector_array;
768  }
769 
770  BLI_assert(any_value->type == ValueType::OutputVector);
771  return *static_cast<OutputVectorValue *>(any_value)->vector_array;
772 }
773 
775 {
776  Value *any_value = value_per_output_id_[socket.id()];
777  if (any_value == nullptr) {
778  const CPPType &type = socket.data_type().vector_base_type();
779  GVectorArray *vector_array = new GVectorArray(type, 1);
780 
781  auto *value =
782  allocator_.construct<OwnVectorValue>(*vector_array, socket.targets().size()).release();
783  value_per_output_id_[socket.id()] = value;
784 
785  return *value->vector_array;
786  }
787 
788  BLI_assert(any_value->type == ValueType::OutputVector);
789  GVectorArray &vector_array = *static_cast<OutputVectorValue *>(any_value)->vector_array;
790  BLI_assert(vector_array.size() == 1);
791  return vector_array;
792 }
793 
795  const MFOutputSocket &output,
796  ResourceScope &scope)
797 {
798  const MFOutputSocket &from = *input.origin();
799  const MFOutputSocket &to = output;
800  const CPPType &type = from.data_type().single_type();
801 
802  Value *from_any_value = value_per_output_id_[from.id()];
803  Value *to_any_value = value_per_output_id_[to.id()];
804  BLI_assert(from_any_value != nullptr);
806 
807  if (to_any_value != nullptr) {
808  BLI_assert(to_any_value->type == ValueType::OutputSingle);
809  GMutableSpan span = static_cast<OutputSingleValue *>(to_any_value)->span;
810  const GVArray &virtual_array = this->get_single_input__full(input, scope);
811  virtual_array.materialize_to_uninitialized(mask_, span.data());
812  return span;
813  }
814 
815  if (from_any_value->type == ValueType::OwnSingle) {
816  OwnSingleValue *value = static_cast<OwnSingleValue *>(from_any_value);
817  if (value->max_remaining_users == 1 && !value->is_single_allocated) {
818  value_per_output_id_[to.id()] = value;
819  value_per_output_id_[from.id()] = nullptr;
820  value->max_remaining_users = to.targets().size();
821  return value->span;
822  }
823  }
824 
825  const GVArray &virtual_array = this->get_single_input__full(input, scope);
826  void *new_buffer = MEM_mallocN_aligned(min_array_size_ * type.size(), type.alignment(), AT);
827  GMutableSpan new_array_ref(type, new_buffer, min_array_size_);
828  virtual_array.materialize_to_uninitialized(mask_, new_array_ref.data());
829 
830  OwnSingleValue *new_value =
831  allocator_.construct<OwnSingleValue>(new_array_ref, to.targets().size(), false).release();
832  value_per_output_id_[to.id()] = new_value;
833  return new_array_ref;
834 }
835 
837  const MFOutputSocket &output,
838  ResourceScope &scope)
839 {
840  const MFOutputSocket &from = *input.origin();
841  const MFOutputSocket &to = output;
842  const CPPType &type = from.data_type().single_type();
843 
844  Value *from_any_value = value_per_output_id_[from.id()];
845  Value *to_any_value = value_per_output_id_[to.id()];
846  BLI_assert(from_any_value != nullptr);
848 
849  if (to_any_value != nullptr) {
850  BLI_assert(to_any_value->type == ValueType::OutputSingle);
851  GMutableSpan span = static_cast<OutputSingleValue *>(to_any_value)->span;
852  BLI_assert(span.size() == 1);
853  const GVArray &virtual_array = this->get_single_input__single(input, scope);
854  virtual_array.get_single_to_uninitialized(span[0]);
855  return span;
856  }
857 
858  if (from_any_value->type == ValueType::OwnSingle) {
859  OwnSingleValue *value = static_cast<OwnSingleValue *>(from_any_value);
860  if (value->max_remaining_users == 1) {
861  value_per_output_id_[to.id()] = value;
862  value_per_output_id_[from.id()] = nullptr;
863  value->max_remaining_users = to.targets().size();
864  BLI_assert(value->span.size() == 1);
865  return value->span;
866  }
867  }
868 
869  const GVArray &virtual_array = this->get_single_input__single(input, scope);
870 
871  void *new_buffer = allocator_.allocate(type.size(), type.alignment());
872  virtual_array.get_single_to_uninitialized(new_buffer);
873  GMutableSpan new_array_ref(type, new_buffer, 1);
874 
875  OwnSingleValue *new_value =
876  allocator_.construct<OwnSingleValue>(new_array_ref, to.targets().size(), true).release();
877  value_per_output_id_[to.id()] = new_value;
878  return new_array_ref;
879 }
880 
882  const MFOutputSocket &output,
883  ResourceScope &scope)
884 {
885  const MFOutputSocket &from = *input.origin();
886  const MFOutputSocket &to = output;
887  const CPPType &base_type = from.data_type().vector_base_type();
888 
889  Value *from_any_value = value_per_output_id_[from.id()];
890  Value *to_any_value = value_per_output_id_[to.id()];
891  BLI_assert(from_any_value != nullptr);
892  BLI_assert(base_type == to.data_type().vector_base_type());
893 
894  if (to_any_value != nullptr) {
895  BLI_assert(to_any_value->type == ValueType::OutputVector);
896  GVectorArray &vector_array = *static_cast<OutputVectorValue *>(to_any_value)->vector_array;
897  const GVVectorArray &virtual_vector_array = this->get_vector_input__full(input, scope);
898  vector_array.extend(mask_, virtual_vector_array);
899  return vector_array;
900  }
901 
902  if (from_any_value->type == ValueType::OwnVector) {
903  OwnVectorValue *value = static_cast<OwnVectorValue *>(from_any_value);
904  if (value->max_remaining_users == 1) {
905  value_per_output_id_[to.id()] = value;
906  value_per_output_id_[from.id()] = nullptr;
907  value->max_remaining_users = to.targets().size();
908  return *value->vector_array;
909  }
910  }
911 
912  const GVVectorArray &virtual_vector_array = this->get_vector_input__full(input, scope);
913 
914  GVectorArray *new_vector_array = new GVectorArray(base_type, min_array_size_);
915  new_vector_array->extend(mask_, virtual_vector_array);
916 
917  OwnVectorValue *new_value =
918  allocator_.construct<OwnVectorValue>(*new_vector_array, to.targets().size()).release();
919  value_per_output_id_[to.id()] = new_value;
920 
921  return *new_vector_array;
922 }
923 
925  const MFOutputSocket &output,
926  ResourceScope &scope)
927 {
928  const MFOutputSocket &from = *input.origin();
929  const MFOutputSocket &to = output;
930  const CPPType &base_type = from.data_type().vector_base_type();
931 
932  Value *from_any_value = value_per_output_id_[from.id()];
933  Value *to_any_value = value_per_output_id_[to.id()];
934  BLI_assert(from_any_value != nullptr);
935  BLI_assert(base_type == to.data_type().vector_base_type());
936 
937  if (to_any_value != nullptr) {
938  BLI_assert(to_any_value->type == ValueType::OutputVector);
939  GVectorArray &vector_array = *static_cast<OutputVectorValue *>(to_any_value)->vector_array;
940  BLI_assert(vector_array.size() == 1);
941  const GVVectorArray &virtual_vector_array = this->get_vector_input__single(input, scope);
942  vector_array.extend({0}, virtual_vector_array);
943  return vector_array;
944  }
945 
946  if (from_any_value->type == ValueType::OwnVector) {
947  OwnVectorValue *value = static_cast<OwnVectorValue *>(from_any_value);
948  if (value->max_remaining_users == 1) {
949  value_per_output_id_[to.id()] = value;
950  value_per_output_id_[from.id()] = nullptr;
951  value->max_remaining_users = to.targets().size();
952  return *value->vector_array;
953  }
954  }
955 
956  const GVVectorArray &virtual_vector_array = this->get_vector_input__single(input, scope);
957 
958  GVectorArray *new_vector_array = new GVectorArray(base_type, 1);
959  new_vector_array->extend({0}, virtual_vector_array);
960 
961  OwnVectorValue *new_value =
962  allocator_.construct<OwnVectorValue>(*new_vector_array, to.targets().size()).release();
963  value_per_output_id_[to.id()] = new_value;
964  return *new_vector_array;
965 }
966 
968  ResourceScope &scope)
969 {
970  const MFOutputSocket &origin = *socket.origin();
971  Value *any_value = value_per_output_id_[origin.id()];
972  BLI_assert(any_value != nullptr);
973 
974  if (any_value->type == ValueType::OwnSingle) {
975  OwnSingleValue *value = static_cast<OwnSingleValue *>(any_value);
976  if (value->is_single_allocated) {
977  return scope.construct<GVArrayForSingleValueRef>(
978  __func__, value->span.type(), min_array_size_, value->span.data());
979  }
980 
981  return scope.construct<GVArrayForGSpan>(__func__, value->span);
982  }
983  if (any_value->type == ValueType::InputSingle) {
984  InputSingleValue *value = static_cast<InputSingleValue *>(any_value);
985  return value->virtual_array;
986  }
987  if (any_value->type == ValueType::OutputSingle) {
988  OutputSingleValue *value = static_cast<OutputSingleValue *>(any_value);
989  BLI_assert(value->is_computed);
990  return scope.construct<GVArrayForGSpan>(__func__, value->span);
991  }
992 
993  BLI_assert(false);
994  return scope.construct<GVArrayForEmpty>(__func__, CPPType::get<float>());
995 }
996 
998  ResourceScope &scope)
999 {
1000  const MFOutputSocket &origin = *socket.origin();
1001  Value *any_value = value_per_output_id_[origin.id()];
1002  BLI_assert(any_value != nullptr);
1003 
1004  if (any_value->type == ValueType::OwnSingle) {
1005  OwnSingleValue *value = static_cast<OwnSingleValue *>(any_value);
1006  BLI_assert(value->span.size() == 1);
1007  return scope.construct<GVArrayForGSpan>(__func__, value->span);
1008  }
1009  if (any_value->type == ValueType::InputSingle) {
1010  InputSingleValue *value = static_cast<InputSingleValue *>(any_value);
1012  return value->virtual_array;
1013  }
1014  if (any_value->type == ValueType::OutputSingle) {
1015  OutputSingleValue *value = static_cast<OutputSingleValue *>(any_value);
1016  BLI_assert(value->is_computed);
1017  BLI_assert(value->span.size() == 1);
1018  return scope.construct<GVArrayForGSpan>(__func__, value->span);
1019  }
1020 
1021  BLI_assert(false);
1022  return scope.construct<GVArrayForEmpty>(__func__, CPPType::get<float>());
1023 }
1024 
1026  const MFInputSocket &socket, ResourceScope &scope)
1027 {
1028  const MFOutputSocket &origin = *socket.origin();
1029  Value *any_value = value_per_output_id_[origin.id()];
1030  BLI_assert(any_value != nullptr);
1031 
1032  if (any_value->type == ValueType::OwnVector) {
1033  OwnVectorValue *value = static_cast<OwnVectorValue *>(any_value);
1034  if (value->vector_array->size() == 1) {
1035  GSpan span = (*value->vector_array)[0];
1036  return scope.construct<GVVectorArrayForSingleGSpan>(__func__, span, min_array_size_);
1037  }
1038 
1039  return scope.construct<GVVectorArrayForGVectorArray>(__func__, *value->vector_array);
1040  }
1041  if (any_value->type == ValueType::InputVector) {
1042  InputVectorValue *value = static_cast<InputVectorValue *>(any_value);
1043  return value->virtual_vector_array;
1044  }
1045  if (any_value->type == ValueType::OutputVector) {
1046  OutputVectorValue *value = static_cast<OutputVectorValue *>(any_value);
1047  return scope.construct<GVVectorArrayForGVectorArray>(__func__, *value->vector_array);
1048  }
1049 
1050  BLI_assert(false);
1051  return scope.construct<GVVectorArrayForSingleGSpan>(__func__, GSpan(CPPType::get<float>()), 0);
1052 }
1053 
1055  const MFInputSocket &socket, ResourceScope &scope)
1056 {
1057  const MFOutputSocket &origin = *socket.origin();
1058  Value *any_value = value_per_output_id_[origin.id()];
1059  BLI_assert(any_value != nullptr);
1060 
1061  if (any_value->type == ValueType::OwnVector) {
1062  OwnVectorValue *value = static_cast<OwnVectorValue *>(any_value);
1063  BLI_assert(value->vector_array->size() == 1);
1064  return scope.construct<GVVectorArrayForGVectorArray>(__func__, *value->vector_array);
1065  }
1066  if (any_value->type == ValueType::InputVector) {
1067  InputVectorValue *value = static_cast<InputVectorValue *>(any_value);
1069  return value->virtual_vector_array;
1070  }
1071  if (any_value->type == ValueType::OutputVector) {
1072  OutputVectorValue *value = static_cast<OutputVectorValue *>(any_value);
1073  BLI_assert(value->vector_array->size() == 1);
1074  return scope.construct<GVVectorArrayForGVectorArray>(__func__, *value->vector_array);
1075  }
1076 
1077  BLI_assert(false);
1078  return scope.construct<GVVectorArrayForSingleGSpan>(__func__, GSpan(CPPType::get<float>()), 0);
1079 }
1080 
1083 } // namespace blender::fn
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define BLI_NOINLINE
#define ELEM(...)
#define AT
_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
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White Value
#define output
void * allocate(const int64_t size, const int64_t alignment)
destruct_ptr< T > construct(Args &&... args)
T & construct(const char *name, Args &&... args)
const CPPType & type() const
void materialize_to_uninitialized(const IndexMask mask, void *dst) const
void get_single_to_uninitialized(void *r_value) const
void extend(int64_t index, const GVArray &values)
const CPPType & vector_base_type() const
const CPPType & single_type() const
GMutableSpan get_single_output__full(const MFOutputSocket &socket)
const GVVectorArray & get_vector_input__single(const MFInputSocket &socket, ResourceScope &scope)
GVectorArray & get_mutable_vector__full(const MFInputSocket &input, const MFOutputSocket &output, ResourceScope &scope)
void add_single_input_from_caller(const MFOutputSocket &socket, const GVArray &virtual_array)
const GVArray & get_single_input__full(const MFInputSocket &socket, ResourceScope &scope)
bool is_same_value_for_every_index(const MFOutputSocket &socket)
const GVArray & get_single_input__single(const MFInputSocket &socket, ResourceScope &scope)
GVectorArray & get_vector_output__single(const MFOutputSocket &socket)
MFNetworkEvaluationStorage(IndexMask mask, int socket_id_amount)
GVectorArray & get_mutable_vector__single(const MFInputSocket &input, const MFOutputSocket &output, ResourceScope &scope)
bool socket_has_buffer_for_output(const MFOutputSocket &socket)
GMutableSpan get_mutable_single__full(const MFInputSocket &input, const MFOutputSocket &output, ResourceScope &scope)
void add_single_output_from_caller(const MFOutputSocket &socket, GMutableSpan span)
GVectorArray & get_vector_output__full(const MFOutputSocket &socket)
const GVVectorArray & get_vector_input__full(const MFInputSocket &socket, ResourceScope &scope)
GMutableSpan get_single_output__single(const MFOutputSocket &socket)
void add_vector_output_from_caller(const MFOutputSocket &socket, GVectorArray &vector_array)
GMutableSpan get_mutable_single__single(const MFInputSocket &input, const MFOutputSocket &output, ResourceScope &scope)
void add_vector_input_from_caller(const MFOutputSocket &socket, const GVVectorArray &virtual_vector_array)
MFNetworkEvaluator(Vector< const MFOutputSocket * > inputs, Vector< const MFInputSocket * > outputs)
void call(IndexMask mask, MFParams params, MFContext context) const override
const MFDataType & data_type() const
MFParamType param_type(int param_index) const
IndexRange param_indices() const
void set_signature(const MFSignature *signature)
const MFSignature & signature() const
OperationNode * node
StackEntry * from
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
__kernel void ccl_constant KernelData ccl_global void ccl_global char ccl_global int ccl_global char ccl_global unsigned int ccl_global float * buffer
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_mallocN_aligned)(size_t len, size_t alignment, const char *str)
Definition: mallocn.c:49
static bNodeSocketTemplate outputs[]
static bNodeSocketTemplate inputs[]
struct SELECTID_Context context
Definition: select_engine.c:47
__int64 int64_t
Definition: stdint.h:92
InputSingleValue(const GVArray &virtual_array)
InputVectorValue(const GVVectorArray &virtual_vector_array)
OwnSingleValue(GMutableSpan span, int max_remaining_users, bool is_single_allocated)
OwnVectorValue(GVectorArray &vector_array, int max_remaining_users)
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)