Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/compositor/realtime_compositor/COM_operation.hh')
-rw-r--r--source/blender/compositor/realtime_compositor/COM_operation.hh175
1 files changed, 175 insertions, 0 deletions
diff --git a/source/blender/compositor/realtime_compositor/COM_operation.hh b/source/blender/compositor/realtime_compositor/COM_operation.hh
new file mode 100644
index 00000000000..38518c00c04
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/COM_operation.hh
@@ -0,0 +1,175 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+#include <memory>
+#include <string>
+
+#include "BLI_map.hh"
+#include "BLI_string_ref.hh"
+#include "BLI_vector.hh"
+
+#include "COM_context.hh"
+#include "COM_domain.hh"
+#include "COM_input_descriptor.hh"
+#include "COM_result.hh"
+#include "COM_static_shader_manager.hh"
+#include "COM_texture_pool.hh"
+
+namespace blender::realtime_compositor {
+
+class SimpleOperation;
+
+/* A type representing a vector of simple operations that store the input processors for a
+ * particular input. */
+using ProcessorsVector = Vector<std::unique_ptr<SimpleOperation>>;
+
+/* ------------------------------------------------------------------------------------------------
+ * Operation
+ *
+ * The operation is the basic unit of the compositor. The evaluator compiles the compositor node
+ * tree into an ordered stream of operations which are then executed in order during evaluation.
+ * The operation class can be sub-classed to implement a new operation. Operations have a number of
+ * inputs and outputs that are declared during construction and are identified by string
+ * identifiers. Inputs are declared by calling declare_input_descriptor providing an appropriate
+ * descriptor. Those inputs are mapped to the results computed by other operations whose outputs
+ * are linked to the inputs. Such mappings are established by the compiler during compilation by
+ * calling the map_input_to_result method. Outputs are populated by calling the populate_result
+ * method, providing a result of an appropriate type. Upon execution, the operation allocates a
+ * result for each of its outputs and computes their value based on its inputs and options.
+ *
+ * Each input may have one or more input processors, which are simple operations that process the
+ * inputs before the operation is executed, see the discussion in COM_simple_operation.hh for more
+ * information. And thus the effective input of the operation is the result of the last input
+ * processor if one exists. Input processors are added and evaluated by calling the
+ * add_and_evaluate_input_processors method, which provides a default implementation that does
+ * things like implicit conversion, domain realization, and more. This default implementation can,
+ * however, be overridden, extended, or removed. Once the input processors are added and evaluated
+ * for the first time, they are stored in the operation and future evaluations can evaluate them
+ * directly without having to add them again.
+ *
+ * The operation is evaluated by calling the evaluate method, which first adds the input processors
+ * if they weren't added already and evaluates them, then it resets the results of the operation,
+ * then it calls the execute method of the operation, and finally it releases the results mapped to
+ * the inputs to declare that they are no longer needed. */
+class Operation {
+ private:
+ /* A reference to the compositor context. This member references the same object in all
+ * operations but is included in the class for convenience. */
+ Context &context_;
+ /* A mapping between each output of the operation identified by its identifier and the result for
+ * that output. A result for each output of the operation should be constructed and added to the
+ * map during operation construction by calling the populate_result method. The results should be
+ * allocated and their contents should be computed in the execute method. */
+ Map<std::string, Result> results_;
+ /* A mapping between each input of the operation identified by its identifier and its input
+ * descriptor. Those descriptors should be declared during operation construction by calling the
+ * declare_input_descriptor method. */
+ Map<std::string, InputDescriptor> input_descriptors_;
+ /* A mapping between each input of the operation identified by its identifier and a pointer to
+ * the computed result providing its data. The mapped result is either one that was computed by
+ * another operation or one that was internally computed in the operation by the last input
+ * processor for that input. It is the responsibility of the evaluator to map the inputs to their
+ * linked results before evaluating the operation by calling the map_input_to_result method. */
+ Map<StringRef, Result *> results_mapped_to_inputs_;
+ /* A mapping between each input of the operation identified by its identifier and an ordered list
+ * of simple operations to process that input. This is initialized the first time the input
+ * processors are evaluated by calling the add_and_evaluate_input_processors method. Further
+ * evaluations will evaluate the processors directly without the need to add them again. The
+ * input_processors_added_ member indicates whether the processors were already added and can be
+ * evaluated directly or need to be added and evaluated. */
+ Map<StringRef, ProcessorsVector> input_processors_;
+ /* True if the input processors were already added and can be evaluated directly. False if the
+ * input processors are not yet added and needs to be added. */
+ bool input_processors_added_ = false;
+
+ public:
+ Operation(Context &context);
+
+ virtual ~Operation();
+
+ /* Evaluate the operation by:
+ * 1. Evaluating the input processors.
+ * 2. Resetting the results of the operation.
+ * 3. Calling the execute method of the operation.
+ * 4. Releasing the results mapped to the inputs. */
+ void evaluate();
+
+ /* Get a reference to the output result identified by the given identifier. */
+ Result &get_result(StringRef identifier);
+
+ /* Map the input identified by the given identifier to the result providing its data. See
+ * results_mapped_to_inputs_ for more details. This should be called by the evaluator to
+ * establish links between different operations. */
+ void map_input_to_result(StringRef identifier, Result *result);
+
+ protected:
+ /* Compute the operation domain of this operation. By default, this implements a default logic
+ * that infers the operation domain from the inputs, which may be overridden for a different
+ * logic. See the discussion in COM_domain.hh for the inference logic and more information. */
+ virtual Domain compute_domain();
+
+ /* Add and evaluate any needed input processors, which essentially just involves calling the
+ * add_and_evaluate_input_processor method with the needed processors. This is called before
+ * executing the operation to prepare its inputs. The class defines a default implementation
+ * which adds typically needed processors, but derived classes can override the method to have
+ * a different implementation, extend the implementation, or remove it entirely. */
+ virtual void add_and_evaluate_input_processors();
+
+ /* Given the identifier of an input of the operation and a processor operation:
+ * - Add the given processor to the list of input processors for the input.
+ * - Map the input of the processor to be the result of the last input processor or the result
+ * mapped to the input if no previous processors exists.
+ * - Switch the result mapped to the input to be the output result of the processor.
+ * - Evaluate the processor. */
+ void add_and_evaluate_input_processor(StringRef identifier, SimpleOperation *processor);
+
+ /* This method should allocate the operation results, execute the operation, and compute the
+ * output results. */
+ virtual void execute() = 0;
+
+ /* Get a reference to the result connected to the input identified by the given identifier. */
+ Result &get_input(StringRef identifier) const;
+
+ /* Switch the result mapped to the input identified by the given identifier with the given
+ * result. */
+ void switch_result_mapped_to_input(StringRef identifier, Result *result);
+
+ /* Add the given result to the results_ map identified by the given output identifier. This
+ * should be called during operation construction for all outputs. The provided result shouldn't
+ * be allocated or initialized, this will happen later during execution. */
+ void populate_result(StringRef identifier, Result result);
+
+ /* Declare the descriptor of the input identified by the given identifier to be the given
+ * descriptor. Adds the given descriptor to the input_descriptors_ map identified by the given
+ * input identifier. This should be called during operation constructor for all inputs. */
+ void declare_input_descriptor(StringRef identifier, InputDescriptor descriptor);
+
+ /* Get a reference to the descriptor of the input identified by the given identified. */
+ InputDescriptor &get_input_descriptor(StringRef identifier);
+
+ /* Returns a reference to the compositor context. */
+ Context &context();
+
+ /* Returns a reference to the texture pool of the compositor context. */
+ TexturePool &texture_pool() const;
+
+ /* Returns a reference to the shader manager of the compositor context. */
+ StaticShaderManager &shader_manager() const;
+
+ private:
+ /* Evaluate the input processors. If the input processors were already added they will be
+ * evaluated directly. Otherwise, the input processors will be added and evaluated. */
+ void evaluate_input_processors();
+
+ /* Resets the results of the operation. See the reset method in the Result class for more
+ * information. */
+ void reset_results();
+
+ /* Release the results that are mapped to the inputs of the operation. This is called after the
+ * evaluation of the operation to declare that the results are no longer needed by this
+ * operation. */
+ void release_inputs();
+};
+
+} // namespace blender::realtime_compositor