Blender V5.0
COM_multi_function_procedure_operation.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#pragma once
6
7#include <memory>
8
9#include "BLI_map.hh"
10#include "BLI_set.hh"
11#include "BLI_vector.hh"
12
16
18#include "NOD_multi_function.hh"
19
20#include "COM_context.hh"
23#include "COM_scheduler.hh"
24
25namespace blender::compositor {
26
27using namespace nodes::derived_node_tree_types;
28
29/* ------------------------------------------------------------------------------------------------
30 * Multi-Function Procedure Operation
31 *
32 * A pixel operation that evaluates a multi-function procedure built from the pixel compile unit
33 * using the multi-function procedure builder, see FN_multi_function_procedure_builder.hh for more
34 * information. Also see the PixelOperation class for more information on pixel operations. */
36 private:
37 /* The multi-function procedure, its builder, and executor that are backing the operation. This
38 * is created and compiled during construction. */
39 mf::Procedure procedure_;
40 mf::ProcedureBuilder procedure_builder_;
41 std::unique_ptr<mf::ProcedureExecutor> procedure_executor_;
42 /* A map that associates each node in the compile unit with an instance of its multi-function
43 * builder. */
45 /* A map that associates the output sockets of each node to the variables that were created for
46 * them. */
47 Map<DOutputSocket, mf::Variable *> output_to_variable_map_;
48 /* A map that associates implicit inputs to the variables that were created for them. */
49 Map<ImplicitInput, mf::Variable *> implicit_input_to_variable_map_;
50 /* A vector that stores the intermediate variables that were implicitly created for the procedure
51 * but are not associated with a node output. Those variables are for such multi-functions like
52 * constant inputs and implicit conversion. */
53 Vector<mf::Variable *> implicit_variables_;
54 /* A set that stores the variables that are used as the outputs of the procedure. */
55 Set<mf::Variable *> output_variables_;
56 /* A vector that stores the identifiers of the parameters of the multi-function procedure in
57 * order. The parameters include both inputs and outputs. This is used to retrieve the input and
58 * output results for each of the parameters in the procedure. Note that parameters have no
59 * identifiers and are identified solely by their order. */
60 Vector<std::string> parameter_identifiers_;
61
62 public:
63 /* Build a multi-function procedure as well as an executor for it from the given pixel compile
64 * unit and execution schedule. */
66 PixelCompileUnit &compile_unit,
67 const Schedule &schedule);
68
69 /* Calls the multi-function procedure executor on the domain of the operator passing in the
70 * inputs and outputs as parameters. */
71 void execute() override;
72
73 private:
74 /* Builds the procedure by going over the nodes in the compile unit, calling their
75 * multi-functions and creating any necessary inputs or outputs to the operation/procedure. */
76 void build_procedure();
77
78 /* Get the variables corresponding to the inputs of the given node. The variables can be those
79 * that were returned by a previous call to a multi-function, those that were generated as
80 * constants for unlinked inputs, or those that were added as inputs to the operation/procedure
81 * itself. The variables are implicitly converted to the type expected by the multi-function. */
82 Vector<mf::Variable *> get_input_variables(DNode node, const mf::MultiFunction &multi_function);
83
84 /* Returns a constant variable that was created by calling a constant function carrying the value
85 * of the given input socket. */
86 mf::Variable *get_constant_input_variable(DInputSocket input);
87
88 /* Given an unlinked input with an implicit input. Declare an input to the operation/procedure
89 * for that implicit input if not done already and return a variable that represent that implicit
90 * input. The implicit input and type are taken from the given origin input, which will be equal
91 * to the input in most cases, but can also be an unlinked input of a group node */
92 mf::Variable *get_implicit_input_variable(const DInputSocket input, const DInputSocket origin);
93
94 /* Given an input in a node that is part of the compile unit that is connected to an output that
95 * is in a non that is not part of the compile unit. Declare an input to the operation/procedure
96 * for that output if not done already and return a variable that represent that input. */
97 mf::Variable *get_multi_function_input_variable(DInputSocket input_socket,
98 DOutputSocket output_socket);
99
100 /* Given the variables that were returned by calling the multi-function for the given node,
101 * assign the variables to their corresponding outputs. And if an output is connected to a node
102 * outside of the compile unit or is used as the preview of the node, declare an output to the
103 * operation/procedure for it. */
104 void assign_output_variables(DNode node, Vector<mf::Variable *> &variables);
105
106 /* Populate an output to the operator/procedure for the given output socket whose value is stored
107 * in the given variable. The variable is implicitly converted to the type expected by the
108 * socket. */
109 void populate_operation_result(DOutputSocket output_socket, mf::Variable *variable);
110
111 /* Convert the given variable to the given expected type. This is done by adding an implicit
112 * conversion function whose output variable will be returned. If no conversion is needed, the
113 * given variable is returned as is. If conversion is not possible, a fallback default variable
114 * will b returned. */
115 mf::Variable *convert_variable(mf::Variable *variable, const mf::DataType expected_type);
116
117 /* Returns true if the operation operates on single values, that is, all of its inputs are single
118 * values. Assumes the procedure is already build. */
119 bool is_single_value_operation();
120};
121
122} // namespace blender::compositor
MultiFunctionProcedureOperation(Context &context, PixelCompileUnit &compile_unit, const Schedule &schedule)
PixelOperation(Context &context, PixelCompileUnit &compile_unit, const Schedule &schedule)
#define input
VectorSet< DNode > Schedule
VectorSet< DNode > PixelCompileUnit