[Bf-blender-cvs] [bedc219f856] temp-viewport-compositor-compiler: Viewport Compositor: Add result pass through

Omar Emara noreply at git.blender.org
Mon Mar 14 13:55:06 CET 2022


Commit: bedc219f85613ade90e6c437733b35e66ad67009
Author: Omar Emara
Date:   Mon Mar 14 14:51:06 2022 +0200
Branches: temp-viewport-compositor-compiler
https://developer.blender.org/rBbedc219f85613ade90e6c437733b35e66ad67009

Viewport Compositor: Add result pass through

Add support for passing results from inputs to outputs unchanged to
avoid unecessary input copies.

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

M	source/blender/nodes/NOD_compositor_execute.hh
M	source/blender/nodes/composite/nodes/node_composite_transform.cc
M	source/blender/nodes/intern/node_compositor_execute.cc

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

diff --git a/source/blender/nodes/NOD_compositor_execute.hh b/source/blender/nodes/NOD_compositor_execute.hh
index 0535e94dba5..d9b928337da 100644
--- a/source/blender/nodes/NOD_compositor_execute.hh
+++ b/source/blender/nodes/NOD_compositor_execute.hh
@@ -223,8 +223,10 @@ class Result {
   GPUTexture *texture_ = nullptr;
   /* The texture pool used to allocate the texture of the result, this should be initialized during
    * construction. */
-  TexturePool &texture_pool_;
-  /* The number of users currently referencing and using this result. */
+  TexturePool *texture_pool_ = nullptr;
+  /* The number of users currently referencing and using this result. If this result have a master
+   * result, then this reference count is irrelevant and shadowed by the reference count of the
+   * master result. */
   int reference_count_ = 0;
   /* If the result is a single value, this member stores the value of the result, the value of
    * which will be identical to that stored in the texture member. While this member stores 4
@@ -236,6 +238,12 @@ class Result {
   /* The transformation of the result. This only matters if the result was a texture. See the
    * Domain class. */
   Transformation2D transformation_ = Transformation2D::identity();
+  /* If not nullptr, then this result wraps and uses the texture of another master result. In this
+   * case, calls to texture-related methods like increment_reference_count and release should
+   * operate on the master result as opposed to this result. This member is typically set upon
+   * calling the pass_through method, which sets this result to be the master of a target result.
+   * See that method for more information. */
+  Result *master_ = nullptr;
 
  public:
   Result(ResultType type, TexturePool &texture_pool);
@@ -262,6 +270,18 @@ class Result {
   /* Unbind the texture which was previously bound using bind_as_image. */
   void unbind_as_image() const;
 
+  /* Pass this result through to a target result. This method makes the target result a copy of
+   * this result, essentially having identical values between the two and consequently sharing the
+   * underlying texture. Additionally, this result is set to be the master of the target result, by
+   * setting the master member of the target. Finally, the reference count of the result is
+   * incremented by the reference count of the target result. This is typically called in the
+   * allocate method of an operation whose input texture will not change and can be passed to the
+   * output directly. It should be noted that such operations can still adjust other properties of
+   * the result, like its transformation. So for instance, the transform operation passes its input
+   * through to its output because it will not change it, however, it may adjusts its
+   * transformation. */
+  void pass_through(Result &target);
+
   /* Transform the result by the given transformation. This effectively pre-multiply the given
    * transformation by the current transformation of the result. */
   void transform(const Transformation2D &transformation);
@@ -290,12 +310,15 @@ class Result {
    * texture. Otherwise, an undefined behavior is invoked. */
   void set_color_value(const float4 &value);
 
-  /* Increment the reference count of the result. This should be called when a user gets a
-   * reference to the result to use as an input. */
-  void incremenet_reference_count();
+  /* Increment the reference count of the result by the given count. This should be called when a
+   * user gets a reference to the result to use. If this result have a master result, the reference
+   * count of the master result is incremented instead. */
+  void increment_reference_count(int count = 1);
 
-  /* Release the result texture back into the texture pool. This should be called when a user that
-   * previously referenced and incremented the reference count of the result no longer needs it. */
+  /* Decrement the reference count of the result and release the result texture back into the
+   * texture pool if the reference count reaches zero. This should be called when a user that
+   * previously referenced and incremented the reference count of the result no longer needs it. If
+   * this result have a master result, the master result is released instead. */
   void release();
 
   /* Returns the type of the result. */
@@ -310,6 +333,10 @@ class Result {
   /* Returns the allocated GPU texture of the result. */
   GPUTexture *texture() const;
 
+  /* Returns the reference count of the result. If this result have a master result, then the
+   * reference count of the master result is returned instead. */
+  int reference_count() const;
+
   /* Returns the size of the allocated texture. */
   int2 size() const;
 
diff --git a/source/blender/nodes/composite/nodes/node_composite_transform.cc b/source/blender/nodes/composite/nodes/node_composite_transform.cc
index 1e44849e2e3..9a4fdbebca2 100644
--- a/source/blender/nodes/composite/nodes/node_composite_transform.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_transform.cc
@@ -63,27 +63,13 @@ class TransformOperation : public NodeOperation {
 
   void allocate() override
   {
-    const Result &input = get_input("Image");
+    Result &input = get_input("Image");
     Result &result = get_result("Image");
-    if (input.is_texture()) {
-      result.allocate_texture(input.size());
-    }
-    else {
-      result.allocate_single_value();
-    }
+    input.pass_through(result);
   }
 
   void execute() override
   {
-    const Result &input = get_input("Image");
-    Result &result = get_result("Image");
-    if (result.is_single_value()) {
-      result.set_color_value(input.get_color_value());
-      return;
-    }
-
-    GPU_texture_copy(result.texture(), input.texture());
-
     const float2 translation = float2(get_input("X").get_float_value(),
                                       get_input("Y").get_float_value());
     const float rotation = get_input("Angle").get_float_value();
@@ -92,6 +78,7 @@ class TransformOperation : public NodeOperation {
     const Transformation2D transformation = Transformation2D::from_translation_rotation_scale(
         translation, rotation, scale);
 
+    Result &result = get_result("Image");
     result.transform(transformation);
   }
 };
diff --git a/source/blender/nodes/intern/node_compositor_execute.cc b/source/blender/nodes/intern/node_compositor_execute.cc
index aa42fdf4364..73e60b6e134 100644
--- a/source/blender/nodes/intern/node_compositor_execute.cc
+++ b/source/blender/nodes/intern/node_compositor_execute.cc
@@ -142,7 +142,7 @@ bool operator!=(const Domain &a, const Domain &b)
  */
 
 Result::Result(ResultType type, TexturePool &texture_pool)
-    : type_(type), texture_pool_(texture_pool)
+    : type_(type), texture_pool_(&texture_pool)
 {
 }
 
@@ -151,13 +151,13 @@ void Result::allocate_texture(int2 size)
   is_texture_ = true;
   switch (type_) {
     case ResultType::Float:
-      texture_ = texture_pool_.acquire_float(size);
+      texture_ = texture_pool_->acquire_float(size);
       return;
     case ResultType::Vector:
-      texture_ = texture_pool_.acquire_vector(size);
+      texture_ = texture_pool_->acquire_vector(size);
       return;
     case ResultType::Color:
-      texture_ = texture_pool_.acquire_color(size);
+      texture_ = texture_pool_->acquire_color(size);
       return;
   }
 }
@@ -169,13 +169,13 @@ void Result::allocate_single_value()
   const int2 texture_size{1, 1};
   switch (type_) {
     case ResultType::Float:
-      texture_ = texture_pool_.acquire_float(texture_size);
+      texture_ = texture_pool_->acquire_float(texture_size);
       return;
     case ResultType::Vector:
-      texture_ = texture_pool_.acquire_vector(texture_size);
+      texture_ = texture_pool_->acquire_vector(texture_size);
       return;
     case ResultType::Color:
-      texture_ = texture_pool_.acquire_color(texture_size);
+      texture_ = texture_pool_->acquire_color(texture_size);
       return;
   }
 }
@@ -202,6 +202,15 @@ void Result::unbind_as_image() const
   GPU_texture_image_unbind(texture_);
 }
 
+void Result::pass_through(Result &target)
+{
+  /* Increment the reference count of the master by the original reference count of the target. */
+  increment_reference_count(target.reference_count());
+  /* Copy the result to the target and set its master. */
+  target = *this;
+  target.master_ = this;
+}
+
 void Result::transform(const Transformation2D &transformation)
 {
   transformation_ = transformation * transformation_;
@@ -240,16 +249,30 @@ void Result::set_color_value(const float4 &value)
   GPU_texture_update(texture_, GPU_DATA_FLOAT, value_);
 }
 
-void Result::incremenet_reference_count()
+void Result::increment_reference_count(int count)
 {
-  reference_count_++;
+  /* If there is a master result, increment its reference count instead. */
+  if (master_) {
+    master_->increment_reference_count(count);
+    return;
+  }
+
+  reference_count_ += count;
 }
 
 void Result::release()
 {
+  /* If there is a master result, release it instead. */
+  if (master_) {
+    master_->release();
+    return;
+  }
+
+  /* Decrement the reference count, and if it reaches zero, release the texture back into the
+   * texture pool. */
   reference_count_--;
   if (reference_count_ == 0) {
-    texture_pool_.release(texture_);
+    texture_pool_->release(texture_);
   }
 }
 
@@ -273,6 +296,15 @@ GPUTexture *Result::texture() const
   return texture_;
 }
 
+int Result::reference_count() const
+{
+  /* If there is a master result, return its reference count instead. */
+  if (master_) {
+    return master_->reference_count();
+  }
+  return reference_count_;
+}
+
 int2 Result::size() const
 {
   return int2{GPU_texture_width(texture_), GPU_texture_height(texture_)};
@@ -332,7 +364,7 @@ Result &Operation::get_result(StringRef identifier)
 void Operation::map_input_to_result(StringRef identifier, Result *result)
 {
   inputs_to_results_map_.add_new(identifier, result);
-  result->incremenet_reference_count();
+  result->increment_reference_count();
 }
 
 void Operation::pre_allocate()



More information about the Bf-blender-cvs mailing list