[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