[Bf-blender-cvs] [7497a2bb361] temp-viewport-compositor-compiler: Viewport Compositor: Add operations executor

Omar Emara noreply at git.blender.org
Wed Feb 16 21:08:49 CET 2022


Commit: 7497a2bb361dee9bd83e714f6bfe8e3366954e5e
Author: Omar Emara
Date:   Wed Feb 16 22:06:48 2022 +0200
Branches: temp-viewport-compositor-compiler
https://developer.blender.org/rB7497a2bb361dee9bd83e714f6bfe8e3366954e5e

Viewport Compositor: Add operations executor

Add operations stream executor and support proper reference counting
using texture pool.

===================================================================

M	source/blender/draw/engines/compositor/compositor_engine.cc
M	source/blender/nodes/NOD_compositor_execute.hh
M	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 021e916ee52..8eb570b0809 100644
--- a/source/blender/draw/engines/compositor/compositor_engine.cc
+++ b/source/blender/draw/engines/compositor/compositor_engine.cc
@@ -88,11 +88,9 @@ static void draw()
 
 }  // namespace blender::viewport_compositor
 
-using namespace blender::viewport_compositor;
-
 static void compositor_draw(void *UNUSED(data))
 {
-  draw();
+  blender::viewport_compositor::draw();
 }
 
 extern "C" {
diff --git a/source/blender/nodes/NOD_compositor_execute.hh b/source/blender/nodes/NOD_compositor_execute.hh
index 5288684f3b3..8d6e40c21b0 100644
--- a/source/blender/nodes/NOD_compositor_execute.hh
+++ b/source/blender/nodes/NOD_compositor_execute.hh
@@ -61,17 +61,24 @@ class TexturePool {
 
  public:
   /* Check if there is an available texture with the given specification in the pool, if such
-   * texture exists, return it, otherwise, return a newly allocated texture. The texture can be
-   * reference counted by providing the number of users that will be using this texture. The
-   * reference count will then be users_count + 1, because the texture pool is itself considered a
-   * user. Expect the texture to be uncleared and contains garbage data. */
-  GPUTexture *acquire(int width, int height, eGPUTextureFormat format, int users_count = 1);
-
-  /* Put the texture back into the pool, potentially to be acquired later by another user. The
-   * texture is only effectively release when its reference count reaches one. Notice that the
-   * texture is release when the texture reference count reaches one not zero, because the texture
-   * pool is itself considered a user of the texture. Expects the texture to be one that was
-   * acquired using the same texture pool. */
+   * texture exists, return it, otherwise, return a newly allocated texture. Expect the texture to
+   * be uncleared and contains garbage data. */
+  GPUTexture *acquire(int width, int height, eGPUTextureFormat format);
+
+  /* Shorthand for acquire with GPU_RGBA16F format. */
+  GPUTexture *acquire_color(int width, int height);
+
+  /* Shorthand for acquire with GPU_RGB16F format. */
+  GPUTexture *acquire_vector(int width, int height);
+
+  /* Shorthand for acquire with GPU_R16F format. */
+  GPUTexture *acquire_float(int width, int height);
+
+  /* Decrement the reference count of the texture and put it back into the pool if its reference
+   * count reaches one, potentially to be acquired later by another user. Notice that the texture
+   * is release when the texture reference count reaches one, not zero, because the texture pool is
+   * itself considered a user of the texture. Expects the texture to be one that was acquired using
+   * the same texture pool. */
   void release(GPUTexture *texture);
 
  private:
@@ -115,9 +122,10 @@ enum class ResultType : uint8_t {
   Color,
 };
 
-/* A structure that describes the result of an operation. An operator can have multiple results
+/* A class that describes the result of an operation. An operator can have multiple results
  * corresponding to multiple outputs. A result either represents a single value or a texture. */
-struct Result {
+class Result {
+ public:
   /* The base type of the texture or the type of the single value. */
   ResultType type;
   /* If true, the result is a texture, otherwise, the result is a single value. */
@@ -130,6 +138,15 @@ struct Result {
     float vector[3];
     float color[4];
   } data;
+
+ public:
+  Result(ResultType type, bool is_texture);
+
+  /* If the result is a texture, increment its reference count.  */
+  void incremenet_reference_count();
+
+  /* If the result is a texture, release it back into the given texture pool.  */
+  void release(TexturePool &texture_pool);
 };
 
 /* --------------------------------------------------------------------
@@ -140,6 +157,9 @@ struct Result {
  * in the compositor. */
 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 computed
    * result for that output. The initialize method is expected to add the needed results. The
    * contents of the results data are uninitialized prior to the invocation of the execute method,
@@ -153,6 +173,10 @@ class Operation {
   Map<StringRef, Result *> inputs_to_results_map_;
 
  public:
+  Operation(Context &context);
+
+  virtual ~Operation() = default;
+
   /* This method should return true if this operation can only operate on buffers, otherwise,
    * return false if the operation can be applied pixel-wise. */
   virtual bool is_buffered() const = 0;
@@ -179,11 +203,19 @@ class Operation {
   Result &get_result(StringRef identifier);
 
   /* Map the input identified by the given identifier to a reference to the result it is connected
-   * to. See inputs_to_results_map_ member for more details. */
+   * to. This also increments the reference count of texture results. See inputs_to_results_map_
+   * member for more details. */
   void map_input_to_result(StringRef identifier, Result *result);
 
   /* Get a reference to the result connected to the input identified by the given identifier. */
   const Result &get_input(StringRef identifier) const;
+
+  /* Release any textures allocated for the results mapped to the inputs of the operation. This is
+   * called after the execution of the operation to declare that the results are no longer needed
+   * by this operation. */
+  void release_inputs();
+
+  Context &context();
 };
 
 /* --------------------------------------------------------------------
@@ -196,9 +228,6 @@ using namespace nodes::derived_node_tree_types;
  * bNodeType.get_compositor_operation, passing the given inputs to the base constructor.  */
 class NodeOperation : public 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_;
   /* The node that this operation represents. */
   DNode node_;
 
@@ -207,8 +236,6 @@ class NodeOperation : public Operation {
 
   virtual bool is_buffered() const override;
 
-  Context &context();
-
   /* Returns true if the output identified by the given identifier is needed and should be
    * computed, otherwise returns false. */
   bool is_output_needed(StringRef identifier) const;
@@ -222,6 +249,8 @@ class NodeOperation : public Operation {
  * node operations by hiding certain implementations details. See any of the derived classes as an
  * example. */
 class MetaOperation : public Operation {
+ public:
+  MetaOperation(Context &context);
 };
 
 /* --------------------------------------------------------------------
@@ -240,7 +269,7 @@ class SingleValueInputOperation : public MetaOperation {
   DInputSocket input_;
 
  public:
-  SingleValueInputOperation(DInputSocket input);
+  SingleValueInputOperation(Context &context, DInputSocket input);
 
   virtual bool is_buffered() const override;
 
@@ -286,6 +315,10 @@ class Evaluator {
  public:
   Evaluator(Context &context, bNodeTree *scene_node_tree);
 
+  /* Delete operations in the operations stream. */
+  ~Evaluator();
+
+  /* Compile the compositor node tree into an operations stream then execute that stream. */
   void evaluate();
 
  private:
@@ -335,6 +368,13 @@ class Evaluator {
 
   /* Map the input to the result of a newly emitted and initialized SingleValueInputOperation. */
   void map_node_unlinked_input_to_result(DInputSocket input);
+
+  /* Execute every operation in the stream in order. This essentially calls execute_operation for
+   * every operation in order. */
+  void execute_operations_stream();
+
+  /* Execute the given operation then call its release method and release its inputs. */
+  void execute_operation(Operation *operation);
 };
 
 }  // namespace blender::viewport_compositor
diff --git a/source/blender/nodes/intern/node_compositor_execute.cc b/source/blender/nodes/intern/node_compositor_execute.cc
index ec3bc2f6aa1..9a0dc4b38b9 100644
--- a/source/blender/nodes/intern/node_compositor_execute.cc
+++ b/source/blender/nodes/intern/node_compositor_execute.cc
@@ -62,19 +62,37 @@ bool operator==(const TexturePoolKey &a, const TexturePoolKey &b)
   return a.width == b.width && a.height == b.height && a.format == b.format;
 }
 
-GPUTexture *TexturePool::acquire(int width, int height, eGPUTextureFormat format, int users_count)
+GPUTexture *TexturePool::acquire(int width, int height, eGPUTextureFormat format)
 {
   const TexturePoolKey key = TexturePoolKey(width, height, format);
   Vector<GPUTexture *> &available_textures = textures_.lookup_or_add_default(key);
-  GPUTexture *texture = available_textures.is_empty() ? allocate_texture(width, height, format) :
-                                                        available_textures.pop_last();
-  /* Add 1 to the users count because the texture pool itself is considered a user. */
-  GPU_texture_set_reference_count(texture, users_count + 1);
-  return texture;
+  if (available_textures.is_empty()) {
+    return allocate_texture(width, height, format);
+  }
+  return available_textures.pop_last();
+}
+
+GPUTexture *TexturePool::acquire_color(int width, int height)
+{
+  return acquire(width, height, GPU_RGBA16F);
+}
+
+GPUTexture *TexturePool::acquire_vector(int width, int height)
+{
+  return acquire(width, height, GPU_RGB16F);
+}
+
+GPUTexture *TexturePool::acquire_float(int width, int height)
+{
+  return acquire(width, height, GPU_R16F);
 }
 
 void TexturePool::release(GPUTexture *texture)
 {
+  /* Since the given texture will always have at least one more user beside the texture pool itself
+   * in a well behaved evaluation, this will not actually free the texture, it merely decrement the
+   * reference the count. */
+  GPU_texture_free(texture);
   /* Don't release if the texture still has more than 1 user. We check if the reference count is
    * more than 1, not zero, because the textu

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list