[Bf-blender-cvs] [7e225823772] temp-viewport-compositor-compiler: Viewport Compositor: Move components to bf_nodes
Omar Emara
noreply at git.blender.org
Mon Feb 14 11:22:44 CET 2022
Commit: 7e22582377203538d24ff693359aed2f6359bfe4
Author: Omar Emara
Date: Mon Feb 14 10:11:12 2022 +0200
Branches: temp-viewport-compositor-compiler
https://developer.blender.org/rB7e22582377203538d24ff693359aed2f6359bfe4
Viewport Compositor: Move components to bf_nodes
We want to avoid directly linking bf_nodes to bf_draw, so we should
start reorganizing implementation files. All components are moved to
bf_nodes, this is also where interfaces are defined to be implemented in
the compositor engine.
===================================================================
M source/blender/draw/engines/compositor/compositor_engine.cc
M source/blender/nodes/CMakeLists.txt
M source/blender/nodes/NOD_compositor_execute.hh
A source/blender/nodes/intern/node_compositor_execute.cc
===================================================================
diff --git a/source/blender/draw/engines/compositor/compositor_engine.cc b/source/blender/draw/engines/compositor/compositor_engine.cc
index 340f9310f08..4d25f72b1d6 100644
--- a/source/blender/draw/engines/compositor/compositor_engine.cc
+++ b/source/blender/draw/engines/compositor/compositor_engine.cc
@@ -22,315 +22,30 @@
* Engine processing the render buffer using GLSL to apply the scene compositing node tree.
*/
-#include "DRW_render.h"
-
-#include "BLI_hash.hh"
-#include "BLI_map.hh"
-#include "BLI_set.hh"
-#include "BLI_string_ref.hh"
-#include "BLI_utildefines.h"
-#include "BLI_vector.hh"
-#include "BLI_vector_set.hh"
-
-#include "DNA_node_types.h"
#include "DNA_scene_types.h"
-#include "GPU_texture.h"
+#include "DRW_render.h"
#include "IMB_colormanagement.h"
#include "NOD_compositor_execute.hh"
-#include "NOD_derived_node_tree.hh"
+
+#include "GPU_texture.h"
#include "compositor_shader.hh"
namespace blender::compositor {
-using nodes::CompositorContext;
-using namespace nodes::derived_node_tree_types;
-
-/* A key structure used to identify a texture in a texture pool. Defines a hash and an equality
- * operator for use in a hash map. */
-class TexturePoolKey {
- public:
- int width;
- int height;
- eGPUTextureFormat format;
-
- TexturePoolKey(int width, int height, eGPUTextureFormat format)
- : width(width), height(height), format(format)
- {
- }
-
- TexturePoolKey(const GPUTexture *texture)
- {
- width = GPU_texture_width(texture);
- height = GPU_texture_height(texture);
- format = GPU_texture_format(texture);
- }
-
- uint64_t hash() const
- {
- return get_default_hash_3(width, height, format);
- }
-};
-
-inline bool operator==(const TexturePoolKey &a, const TexturePoolKey &b)
-{
- return a.width == b.width && a.height == b.height && a.format == b.format;
-}
-
-/* A pool of textures that can be reused transparently throughout the evaluation of the node tree.
- * Uses the DRW texture pool as a base for allocation. The acquired textures are uncleared and are
- * expected to contain garbage data. */
-class TexturePool {
- private:
- /* The set of textures in the pool that are currently in use. */
- Set<GPUTexture *> in_use_textures_;
- /* The set of textures in the pool that are available to acquire. */
- Map<TexturePoolKey, GPUTexture *> available_textures_;
-
- public:
- /* Check if there is an available texture with the given specification in the pool, if such
- * texture exists, return it, otherwise, get a new texture from the DRW texture pool. */
- GPUTexture *acquire(int width, int height, eGPUTextureFormat format)
- {
- const TexturePoolKey key = TexturePoolKey(width, height, format);
- std::optional<GPUTexture *> available_texture = available_textures_.pop_try(key);
- if (available_texture) {
- return *available_texture;
- }
- DrawEngineType *owner = (DrawEngineType *)this;
- GPUTexture *new_texture = DRW_texture_pool_query_2d(width, height, format, owner);
- in_use_textures_.add_new(new_texture);
- return new_texture;
- }
-
- /* Move the texture from the in-use textures set to the available textures set, potentially to be
- * acquired later by another user. */
- void release(GPUTexture *texture)
- {
- in_use_textures_.remove_contained(texture);
- available_textures_.add_new(TexturePoolKey(texture), texture);
- }
-};
-
class DRWCompositorContext : public CompositorContext {
- private:
- /* The node currently being executed. */
- DNode node_;
- /* A map associating output sockets with the textures storing their contents. The map only stores
- * the textures that were already computed by a dependency node and are still needed by one or
- * more dependent nodes, so the node currently executing can get its inputs and outputs from this
- * member. See get_input_texture and get_output_texture. */
- const Map<DSocket, GPUTexture *> &allocated_textures_;
-
- public:
- DRWCompositorContext(DNode node, const Map<DSocket, GPUTexture *> &allocated_textures)
- : node_(node), allocated_textures_(allocated_textures)
- {
- }
-
- const GPUTexture *get_input_texture(StringRef identifier) override
- {
- /* Find the output socket connected to the input with the given input identifier and return its
- * allocated texture. If the input is not linked, return nullptr. */
- GPUTexture *texture = nullptr;
- node_.input_by_identifier(identifier).foreach_origin_socket([&](const DSocket origin) {
- texture = allocated_textures_.lookup(origin);
- });
- return texture;
- }
-
- const GPUTexture *get_output_texture(StringRef identifier) override
- {
- return allocated_textures_.lookup(node_.output_by_identifier(identifier));
- }
-
- const GPUTexture *get_viewport_texture() override
+ GPUTexture *get_viewport_texture() override
{
return DRW_viewport_texture_list_get()->color;
}
- const GPUTexture *get_pass_texture(int view_layer, eScenePassType pass_type) override
+ GPUTexture *get_pass_texture(int view_layer, eScenePassType pass_type) override
{
return DRW_render_pass_find(DRW_context_state_get()->scene, view_layer, pass_type)->pass_tx;
}
-
- const bNode &node() override
- {
- return *node_->bnode();
- }
-};
-
-class Compiler {
- public:
- private:
- /* The derived and reference node trees repressing the compositor setup. */
- NodeTreeRefMap tree_ref_map_;
- DerivedNodeTree tree_;
- /* The output node whose result should be computed and drawn. */
- DNode output_node_;
- /* Stores a heuristic estimation of the number of needed intermediate buffers
- * to compute every node and all of its dependencies. */
- Map<DNode, int> needed_buffers_;
- /* An ordered set of nodes defining the schedule of node execution. */
- VectorSet<DNode> node_schedule_;
-
- public:
- Compiler(bNodeTree *scene_node_tree) : tree_(*scene_node_tree, tree_ref_map_){};
-
- void compile()
- {
- compute_output_node();
- compute_needed_buffers(output_node_);
- compute_schedule(output_node_);
- }
-
- void dump_schedule()
- {
- for (const DNode &node : node_schedule_) {
- std::cout << node->name() << std::endl;
- }
- }
-
- private:
- /* Computes the output node whose result should be computed and drawn. The output node is the
- * node marked as NODE_DO_OUTPUT. If multiple types of output nodes are marked, then the
- * preference will be CMP_NODE_COMPOSITE > CMP_NODE_VIEWER > CMP_NODE_SPLITVIEWER. */
- void compute_output_node()
- {
- const NodeTreeRef &root_tree = tree_.root_context().tree();
- for (const NodeRef *node : root_tree.nodes_by_type("CompositorNodeComposite")) {
- if (node->bnode()->flag & NODE_DO_OUTPUT) {
- output_node_ = DNode(&tree_.root_context(), node);
- return;
- }
- }
- for (const NodeRef *node : root_tree.nodes_by_type("CompositorNodeViewer")) {
- if (node->bnode()->flag & NODE_DO_OUTPUT) {
- output_node_ = DNode(&tree_.root_context(), node);
- return;
- }
- }
- for (const NodeRef *node : root_tree.nodes_by_type("CompositorNodeSplitViewer")) {
- if (node->bnode()->flag & NODE_DO_OUTPUT) {
- output_node_ = DNode(&tree_.root_context(), node);
- return;
- }
- }
- }
-
- /* Computes a heuristic estimation of the number of needed intermediate buffers to compute this
- * node and all of its dependencies. The method recursively computes the needed buffers for all
- * node dependencies and stores them in the needed_buffers_ map. So the root/output node can be
- * provided to compute the needed buffers for all nodes.
- *
- * Consider a node that takes n number of buffers as an input from a number of node dependencies,
- * which we shall call the input nodes. The node also computes and outputs m number of buffers.
- * In order for the node to compute its output, a number of intermediate buffers will be needed.
- * Since the node takes n buffers and outputs m buffers, then the number of buffers directly
- * needed by the node is (n + m). But each of the input buffers are computed by a node that, in
- * turn, needs a number of buffers to compute its output. So the total number of buffers needed
- * to compute the output of the node is max(n + m, d) where d is the number of buffers needed by
- * the input node that needs the largest number of buffers. We only consider the input node that
- * needs the largest number of buffers, because those buffers can be reused by any input node
- * that needs a lesser number of buffers.
- *
- * If the node tree was, in fact, a tree, then this would be an accurate computation. However,
- * the node tree is in fact a graph that allows output sharing, so the computation in this case
- * is merely a heuristic estimation that works well in most cases. */
- int compute_needed_buffers(DNode node)
- {
- /* Compute the number of buffers that the node takes as an input as well as the number of
- * buffers needed to compute the most demanding dependency node. */
- int input_buffers = 0;
- int buffers_needed_by_dependencies = 0;
- for (const InputSocketRef *input_ref : node->inputs()) {
- const DInputSocket input{node.context(), input_ref};
- /* Only consider inputs that are linked, that is, those that take a buffer. */
- input.foreach_origin_socket([&](const DSocket origin) {
- input_buffers++;
- /* The origin node was already computed before, so skip it. */
- if (needed_buffers_.contains(origin.node())) {
- return;
- }
- /* Recursively compute the number of buffers needed to compute this dependency node. */
- const int buffers_needed_by_origin = compute_needed_buffers(origin.node());
- if (buffers_needed_by_origin > buffers_needed_by_dependencies) {
- buffers_needed_by_dependencies = buffers_needed_by_origin;
- }
- });
- }
-
- /* Compute the number of buffers that will be computed/output by this node. */
- int output_buffers = 0;
- for (const OutputSocketRef *output : node->outputs()) {
- if (output->logically_linked_sockets().size() != 0) {
- output_buffers++;
- }
-
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list