Blender V5.0
COM_pixel_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 "BLI_map.hh"
8#include "BLI_string_ref.hh"
9#include "BLI_vector_set.hh"
10
12
13#include "COM_context.hh"
14#include "COM_operation.hh"
15#include "COM_scheduler.hh"
16
17namespace blender::compositor {
18
19using namespace nodes::derived_node_tree_types;
20
21/* A type representing a contiguous subset of the node execution schedule that will be compiled
22 * into a Pixel Operation. */
24
25/* ------------------------------------------------------------------------------------------------
26 * Pixel Operation
27 *
28 * An operation that is evaluated pixel-wise and is compiled from a contiguous subset of the node
29 * execution schedule, whose nodes all represent pixel-wise operations. The subset of the node
30 * execution schedule is called a Pixel Compile Unit and contains nodes that are called Pixel
31 * nodes, see the discussion in COM_compile_state.hh for more information. Since the nodes inside
32 * the compile unit are all pixel wise, they can be combined into a single operation that can be
33 * evaluated more efficiently. This is an abstract class that should be implemented to compile and
34 * evaluate the compile unit as needed.
35 *
36 * Consider the following node graph with a node execution schedule denoted by the number on each
37 * node. The compiler may decide to compile a subset of the execution schedule into a pixel
38 * operation if they are all pixel nodes, in this case, the nodes from 3 to 5 were compiled
39 * together into a pixel operation. This subset is called the pixel compile unit. See the
40 * discussion in COM_evaluator.hh for more information on the compilation process. Links that are
41 * internal to the pixel operation are established between the input and outputs of the pixel
42 * nodes, for instance, the links between nodes 3 and 4 as well as those between nodes 4 and 5.
43 * However, links that cross the boundary of the pixel operation needs special handling.
44 *
45 * Pixel Operation
46 * +------------------------------------------------------+
47 * .------------. | .------------. .------------. .------------. | .------------.
48 * | Node 1 | | | Node 3 | | Node 4 | | Node 5 | | | Node 6 |
49 * | |----|--| |--| |------| |--|--| |
50 * | | .-|--| | | | .---| | | | |
51 * '------------' | | '------------' '------------' | '------------' | '------------'
52 * | +----------------------------------|-------------------+
53 * .------------. | |
54 * | Node 2 | | |
55 * | |--'------------------------------------'
56 * | |
57 * '------------'
58 *
59 * Links from nodes that are not part of the pixel operation to nodes that are part of the pixel
60 * operation are considered inputs of the operation itself and are declared as such. For instance,
61 * the link from node 1 to node 3 is declared as an input to the operation, and the same applies
62 * for the links from node 2 to nodes 3 and 5. Note, however, that only one input is declared for
63 * each distinct output socket, so both links from node 2 share the same input of the operation.
64 *
65 * Links from nodes that are part of the pixel operation to nodes that are not part of the pixel
66 * operation are considered outputs of the operation itself and are declared as such. For instance,
67 * the link from node 5 to node 6 is declared as an output to the operation. */
68class PixelOperation : public Operation {
69 protected:
70 /* The compile unit that will be compiled into this pixel operation. */
72 /* A reference to the node execution schedule that is being compiled. */
74 /* A map that associates the identifier of each input of the operation with the output socket it
75 * is linked to. This is needed to help the compiler establish links between operations. */
77 /* A map that associates the output socket of a node that is not part of the pixel operation to
78 * the identifier of the input of the operation that was declared for it. */
80 /* A map that associates each of the needed implicit inputs with the identifiers of the inputs of
81 * the operation that were declared for them. */
83 /* A map that associates the identifier of each input of the operation with the number of node
84 * inputs that use it, that is, its reference count. This is needed to correct the reference
85 * counts of results linked to the inputs of the operation, since the results that provide the
86 * inputs aren't aware that multiple of their outgoing links are now part of a single pixel
87 * operation. For instance, if an output is linked to both inputs of a Math node, its computed
88 * reference count would be 2, but the pixel operation of the Math node would only create a
89 * single shared input for it, so from the point of view of the evaluator, the reference count
90 * should actually be 1. So the result's reference count should be corrected by decrementing it
91 * by the internal reference count computed in this map minus 1. */
93 /* A map that associates the output socket that provides the result of an output of the operation
94 * with the identifier of that output. This is needed to help the compiler establish links
95 * between operations. */
97 /* A vector set that stores all output sockets that are used as previews for nodes inside the
98 * pixel operation. */
100
101 public:
102 PixelOperation(Context &context, PixelCompileUnit &compile_unit, const Schedule &schedule);
103
104 /* Returns the maximum number of outputs that the PixelOperation can have. Pixel compile units
105 * need to be split into smaller units if the numbers of outputs they have is more than the
106 * number returned by this method. */
108
109 /* Compute a node preview for all nodes in the pixel operations if the node requires a preview.
110 *
111 * Previews are computed from results that are populated for outputs that are used to compute
112 * previews even if they are internally linked, and those outputs are stored and tracked in the
113 * preview_outputs_ vector set, see the populate_results_for_node method for more information. */
114 void compute_preview() override;
115
116 /* Get the identifier of the operation output corresponding to the given output socket. This is
117 * called by the compiler to identify the operation output that provides the result for an input
118 * by providing the output socket that the input is linked to. See
119 * output_sockets_to_output_identifiers_map_ for more information. */
121
122 /* Get a reference to the inputs to linked outputs map of the operation. This is called by the
123 * compiler to identify the output that each input of the operation is linked to for correct
124 * input mapping. See inputs_to_linked_outputs_map_ for more information. */
126
127 /* Get a reference to the implicit inputs to input identifiers map of the operation. This is
128 * called by the compiler to link the operations inputs with their corresponding implicit input
129 * results. See implicit_inputs_to_input_identifiers_map_ for more information. */
131
132 /* Returns the internal reference count of the operation input with the given identifier. See the
133 * inputs_to_reference_counts_map_ member for more information. */
134 int get_internal_input_reference_count(const StringRef &identifier);
135
136 /* Compute and set the initial reference counts of all the results of the operation. The
137 * reference counts of the results are the number of operations that use those results, which is
138 * computed as the number of inputs linked to the output corresponding to each of the results of
139 * the operation, but only the linked inputs whose node is part of the schedule but not part of
140 * the pixel operation, since inputs that are part of the pixel operations are internal links.
141 *
142 * Additionally, results that are used as node previews gets an extra reference count because
143 * they are referenced and released by the compute_preview method.
144 *
145 * The node execution schedule is given as an input. */
146 void compute_results_reference_counts(const Schedule &schedule);
147};
148
149} // namespace blender::compositor
Operation(Context &context)
Definition operation.cc:22
StringRef get_output_identifier_from_output_socket(DOutputSocket output_socket)
Map< DOutputSocket, std::string > outputs_to_declared_inputs_map_
Map< std::string, DOutputSocket > inputs_to_linked_outputs_map_
Map< std::string, int > inputs_to_reference_counts_map_
Map< std::string, DOutputSocket > & get_inputs_to_linked_outputs_map()
int get_internal_input_reference_count(const StringRef &identifier)
VectorSet< DOutputSocket > preview_outputs_
Map< DOutputSocket, std::string > output_sockets_to_output_identifiers_map_
PixelOperation(Context &context, PixelCompileUnit &compile_unit, const Schedule &schedule)
Map< ImplicitInput, std::string > implicit_inputs_to_input_identifiers_map_
static int maximum_number_of_outputs(Context &context)
void compute_results_reference_counts(const Schedule &schedule)
Map< ImplicitInput, std::string > & get_implicit_inputs_to_input_identifiers_map()
VectorSet< DNode > Schedule
VectorSet< DNode > PixelCompileUnit