[Bf-blender-cvs] [fcfa225e5dd] functions-experimental-refactor: move multi function network evaluation to functions2

Jacques Lucke noreply at git.blender.org
Fri Nov 1 20:31:45 CET 2019


Commit: fcfa225e5ddaf96d87e8447810f4e33dcdba0eaa
Author: Jacques Lucke
Date:   Fri Nov 1 20:14:01 2019 +0100
Branches: functions-experimental-refactor
https://developer.blender.org/rBfcfa225e5ddaf96d87e8447810f4e33dcdba0eaa

move multi function network evaluation to functions2

===================================================================

M	source/blender/functions2/CMakeLists.txt
M	source/blender/functions2/FN_multi_functions.h
A	source/blender/functions2/intern/multi_functions/network.cc
A	source/blender/functions2/intern/multi_functions/network.h
M	source/blender/modifiers/intern/MOD_functiondeform_cxx.cc

===================================================================

diff --git a/source/blender/functions2/CMakeLists.txt b/source/blender/functions2/CMakeLists.txt
index 05604ca75ac..f48cd582851 100644
--- a/source/blender/functions2/CMakeLists.txt
+++ b/source/blender/functions2/CMakeLists.txt
@@ -24,6 +24,7 @@ endif()
 set(SRC
   intern/multi_functions/lists.cc
   intern/multi_functions/mixed.cc
+  intern/multi_functions/network.cc
   intern/cpp_type.cc
   intern/cpp_types.cc
   intern/generic_tuple.cc
@@ -45,6 +46,7 @@ set(SRC
 
   intern/multi_functions/lists.h
   intern/multi_functions/mixed.h
+  intern/multi_functions/network.h
   intern/cpp_types.h
 )
 
diff --git a/source/blender/functions2/FN_multi_functions.h b/source/blender/functions2/FN_multi_functions.h
index ee30aa921e5..c45360605b4 100644
--- a/source/blender/functions2/FN_multi_functions.h
+++ b/source/blender/functions2/FN_multi_functions.h
@@ -3,5 +3,6 @@
 
 #include "intern/multi_functions/lists.h"
 #include "intern/multi_functions/mixed.h"
+#include "intern/multi_functions/network.h"
 
 #endif /* __FN_MULTI_FUNCTIONS_H__ */
diff --git a/source/blender/functions2/intern/multi_functions/network.cc b/source/blender/functions2/intern/multi_functions/network.cc
new file mode 100644
index 00000000000..91b451fb57a
--- /dev/null
+++ b/source/blender/functions2/intern/multi_functions/network.cc
@@ -0,0 +1,260 @@
+#include "network.h"
+
+namespace FN {
+
+void MF_EvaluateNetwork::call(const MFMask &mask, MFParams &params, MFContext &context) const
+{
+  if (mask.indices_amount() == 0) {
+    return;
+  }
+
+  Storage storage(mask);
+  this->copy_inputs_to_storage(params, storage);
+  this->evaluate_network_to_compute_outputs(mask, context, storage);
+  this->copy_computed_values_to_outputs(mask, params, storage);
+}
+
+BLI_NOINLINE void MF_EvaluateNetwork::copy_inputs_to_storage(MFParams &params,
+                                                             Storage &storage) const
+{
+  for (uint i = 0; i < m_inputs.size(); i++) {
+    const MFOutputSocket &socket = *m_inputs[i];
+    switch (socket.type().category()) {
+      case MFDataType::Single: {
+        GenericVirtualListRef input_list = params.readonly_single_input(i, "Input");
+        for (const MFInputSocket *target : socket.targets()) {
+          storage.set_virtual_list_for_input__non_owning(*target, input_list);
+        }
+        break;
+      }
+      case MFDataType::Vector: {
+        GenericVirtualListListRef input_list_list = params.readonly_vector_input(i, "Input");
+        for (const MFInputSocket *target : socket.targets()) {
+          const MFNode &target_node = target->node();
+          if (target_node.is_function()) {
+            const MFFunctionNode &target_function_node = target_node.as_function();
+            uint param_index = target_function_node.input_param_indices()[target->index()];
+            MFParamType param_type = target_function_node.function().param_type(param_index);
+
+            if (param_type.is_readonly_vector_input()) {
+              storage.set_virtual_list_list_for_input__non_owning(*target, input_list_list);
+            }
+            else if (param_type.is_mutable_vector()) {
+              GenericVectorArray *vector_array = new GenericVectorArray(param_type.base_type(),
+                                                                        input_list_list.size());
+              for (uint i = 0; i < input_list_list.size(); i++) {
+                vector_array->extend_single__copy(i, input_list_list[i]);
+              }
+              storage.set_vector_array_for_input__non_owning(*target, vector_array);
+              storage.take_vector_array_ownership(vector_array);
+            }
+            else {
+              BLI_assert(false);
+            }
+          }
+          else {
+            storage.set_virtual_list_list_for_input__non_owning(*target, input_list_list);
+          }
+        }
+        break;
+      }
+      case MFDataType::None: {
+        BLI_assert(false);
+        break;
+      }
+    }
+  }
+}
+
+BLI_NOINLINE void MF_EvaluateNetwork::evaluate_network_to_compute_outputs(
+    const MFMask &mask, MFContext &global_context, Storage &storage) const
+{
+  Stack<const MFSocket *> sockets_to_compute;
+
+  for (const MFInputSocket *input_socket : m_outputs) {
+    sockets_to_compute.push(input_socket);
+  }
+
+  while (!sockets_to_compute.empty()) {
+    const MFSocket &socket = *sockets_to_compute.peek();
+
+    if (socket.is_input()) {
+      const MFInputSocket &input_socket = socket.as_input();
+      if (storage.input_is_computed(input_socket)) {
+        sockets_to_compute.pop();
+      }
+      else {
+        const MFOutputSocket &origin = input_socket.origin();
+        sockets_to_compute.push(&origin);
+      }
+    }
+    else {
+      const MFOutputSocket &output_socket = socket.as_output();
+      const MFFunctionNode &function_node = output_socket.node().as_function();
+
+      uint not_computed_inputs_amount = 0;
+      for (const MFInputSocket *input_socket : function_node.inputs()) {
+        if (!storage.input_is_computed(*input_socket)) {
+          not_computed_inputs_amount++;
+          sockets_to_compute.push(input_socket);
+        }
+      }
+
+      bool all_inputs_are_computed = not_computed_inputs_amount == 0;
+      if (all_inputs_are_computed) {
+        this->compute_and_forward_outputs(mask, global_context, function_node, storage);
+        sockets_to_compute.pop();
+      }
+    }
+  }
+}
+
+BLI_NOINLINE void MF_EvaluateNetwork::compute_and_forward_outputs(
+    const MFMask &mask,
+    MFContext &global_context,
+    const MFFunctionNode &function_node,
+    Storage &storage) const
+{
+  uint array_size = mask.min_array_size();
+
+  const MultiFunction &function = function_node.function();
+  MFParamsBuilder params_builder(function, array_size);
+
+  Vector<std::pair<const MFOutputSocket *, GenericMutableArrayRef>> single_outputs_to_forward;
+  Vector<std::pair<const MFOutputSocket *, GenericVectorArray *>> vector_outputs_to_forward;
+
+  for (uint param_index : function.param_indices()) {
+    MFParamType param_type = function.param_type(param_index);
+    switch (param_type.category()) {
+      case MFParamType::None: {
+        BLI_assert(false);
+        break;
+      }
+      case MFParamType::ReadonlySingleInput: {
+        uint input_socket_index = function_node.input_param_indices().first_index(param_index);
+        const MFInputSocket &input_socket = *function_node.inputs()[input_socket_index];
+        GenericVirtualListRef values = storage.get_virtual_list_for_input(input_socket);
+        params_builder.add_readonly_single_input(values);
+        break;
+      }
+      case MFParamType::ReadonlyVectorInput: {
+        uint input_socket_index = function_node.input_param_indices().first_index(param_index);
+        const MFInputSocket &input_socket = *function_node.inputs()[input_socket_index];
+        GenericVirtualListListRef values = storage.get_virtual_list_list_for_input(input_socket);
+        params_builder.add_readonly_vector_input(values);
+        break;
+      }
+      case MFParamType::SingleOutput: {
+        uint output_socket_index = function_node.output_param_indices().first_index(param_index);
+        const MFOutputSocket &output_socket = *function_node.outputs()[output_socket_index];
+        GenericMutableArrayRef values_destination = this->allocate_array(
+            output_socket.type().type(), array_size);
+        params_builder.add_single_output(values_destination);
+        single_outputs_to_forward.append({&output_socket, values_destination});
+        break;
+      }
+      case MFParamType::VectorOutput: {
+        uint output_socket_index = function_node.output_param_indices().first_index(param_index);
+        const MFOutputSocket &output_socket = *function_node.outputs()[output_socket_index];
+        auto *values_destination = new GenericVectorArray(output_socket.type().base_type(),
+                                                          array_size);
+        params_builder.add_vector_output(*values_destination);
+        vector_outputs_to_forward.append({&output_socket, values_destination});
+        break;
+      }
+      case MFParamType::MutableVector: {
+        uint input_socket_index = function_node.input_param_indices().first_index(param_index);
+        const MFInputSocket &input_socket = *function_node.inputs()[input_socket_index];
+
+        uint output_socket_index = function_node.output_param_indices().first_index(param_index);
+        const MFOutputSocket &output_socket = *function_node.outputs()[output_socket_index];
+
+        GenericVectorArray &values = storage.get_vector_array_for_input(input_socket);
+        params_builder.add_mutable_vector(values);
+        vector_outputs_to_forward.append({&output_socket, &values});
+        break;
+      }
+    }
+  }
+
+  MFParams &params = params_builder.build();
+  function.call(mask, params, global_context);
+
+  for (auto single_forward_info : single_outputs_to_forward) {
+    const MFOutputSocket &output_socket = *single_forward_info.first;
+    GenericMutableArrayRef values = single_forward_info.second;
+    storage.take_array_ref_ownership(values);
+
+    for (const MFInputSocket *target : output_socket.targets()) {
+      storage.set_virtual_list_for_input__non_owning(*target, values);
+    }
+  }
+
+  for (auto vector_forward_info : vector_outputs_to_forward) {
+    const MFOutputSocket &output_socket = *vector_forward_info.first;
+    GenericVectorArray *values = vector_forward_info.second;
+    storage.take_vector_array_ownership__not_twice(values);
+
+    for (const MFInputSocket *target : output_socket.targets()) {
+      const MFNode &target_node = target->node();
+      if (target_node.is_function()) {
+        const MFFunctionNode &target_function_node = target_node.as_function();
+        uint param_index = target_function_node.input_param_indices()[target->index()];
+        MFParamType param_type = target_function_node.function().param_type(param_index);
+
+        if (param_type.is_readonly_vector_input()) {
+          storage.set_virtual_list_list_for_input__non_owning(*target, *values);
+        }
+        else if (param_type.is_mutable_vector()) {
+    

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list