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() _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs