Realtime Compositor: Implement zero cost external images #115574
@ -72,7 +72,11 @@ enum class ResultPrecision : uint8_t {
|
|||||||
* the results of identity operations, that is, operations that do nothing to their inputs in
|
* the results of identity operations, that is, operations that do nothing to their inputs in
|
||||||
* certain configurations. In which case, the proxy result is left as is with no extra
|
* certain configurations. In which case, the proxy result is left as is with no extra
|
||||||
* transformation on its domain whatsoever. Proxy results can be created by calling the
|
* transformation on its domain whatsoever. Proxy results can be created by calling the
|
||||||
* pass_through method, see that method for more details. */
|
* pass_through method, see that method for more details.
|
||||||
|
*
|
||||||
|
* A result can wrap an external texture that is not allocated nor managed by the result. This is
|
||||||
|
* set up by a call to the wrap_external method. In that case, when the reference count eventually
|
||||||
|
* reach zero, the texture will not be freed. */
|
||||||
class Result {
|
class Result {
|
||||||
private:
|
private:
|
||||||
/* The base type of the result's texture or single value. */
|
/* The base type of the result's texture or single value. */
|
||||||
@ -120,6 +124,10 @@ class Result {
|
|||||||
* calling the pass_through method, which sets this result to be the master of a target result.
|
* calling the pass_through method, which sets this result to be the master of a target result.
|
||||||
* See that method for more information. */
|
* See that method for more information. */
|
||||||
Result *master_ = nullptr;
|
Result *master_ = nullptr;
|
||||||
|
/* If true, then the result wraps an external texture that is not allocated nor managed by the
|
||||||
|
* result. This is set up by a call to the wrap_external method. In that case, when the reference
|
||||||
|
* count eventually reach zero, the texture will not be freed. */
|
||||||
|
bool is_external_ = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/* Construct a result of the given type and precision with the given texture pool that will be
|
/* Construct a result of the given type and precision with the given texture pool that will be
|
||||||
@ -203,6 +211,13 @@ class Result {
|
|||||||
* a practical example of use. */
|
* a practical example of use. */
|
||||||
void steal_data(Result &source);
|
void steal_data(Result &source);
|
||||||
|
|
||||||
|
/* Set up the result to wrap an external texture that is not allocated nor managed by the result.
|
||||||
|
* The is_external_ member will be set to true, the domain will be set to have the same size as
|
||||||
|
* the texture, and the texture will be set to the given texture. See the is_external_ member for
|
||||||
|
* more information. The given texture should have the same format as the result and is assumed
|
||||||
|
* to have a lifetime that covers the evaluation of the compositor. */
|
||||||
|
void wrap_external(GPUTexture *texture);
|
||||||
|
|
||||||
/* Sets the transformation of the domain of the result to the given transformation. */
|
/* Sets the transformation of the domain of the result to the given transformation. */
|
||||||
void set_transformation(const float3x3 &transformation);
|
void set_transformation(const float3x3 &transformation);
|
||||||
|
|
||||||
|
@ -192,6 +192,19 @@ void Result::steal_data(Result &source)
|
|||||||
source.texture_pool_ = nullptr;
|
source.texture_pool_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Result::wrap_external(GPUTexture *texture)
|
||||||
|
{
|
||||||
|
const eGPUTextureFormat texture_format = GPU_texture_format(texture);
|
||||||
|
BLI_assert(texture_format == get_texture_format());
|
||||||
|
BLI_assert(!is_allocated());
|
||||||
|
BLI_assert(!master_);
|
||||||
|
|
||||||
|
texture_ = texture;
|
||||||
|
is_external_ = true;
|
||||||
|
is_single_value_ = false;
|
||||||
|
domain_ = Domain(int2(GPU_texture_width(texture), GPU_texture_height(texture)));
|
||||||
|
}
|
||||||
|
|
||||||
void Result::set_transformation(const float3x3 &transformation)
|
void Result::set_transformation(const float3x3 &transformation)
|
||||||
{
|
{
|
||||||
domain_.transformation = transformation;
|
domain_.transformation = transformation;
|
||||||
@ -298,7 +311,9 @@ void Result::release()
|
|||||||
* texture pool. */
|
* texture pool. */
|
||||||
reference_count_--;
|
reference_count_--;
|
||||||
if (reference_count_ == 0) {
|
if (reference_count_ == 0) {
|
||||||
|
if (!is_external_) {
|
||||||
texture_pool_->release(texture_);
|
texture_pool_->release(texture_);
|
||||||
|
}
|
||||||
texture_ = nullptr;
|
texture_ = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,9 +108,7 @@ class KeyingScreenOperation : public NodeOperation {
|
|||||||
KeyingScreen &cached_keying_screen = context().cache_manager().keying_screens.get(
|
KeyingScreen &cached_keying_screen = context().cache_manager().keying_screens.get(
|
||||||
context(), get_movie_clip(), movie_tracking_object, get_smoothness());
|
context(), get_movie_clip(), movie_tracking_object, get_smoothness());
|
||||||
|
|
||||||
const Domain domain = compute_domain();
|
keying_screen.wrap_external(cached_keying_screen.texture());
|
||||||
keying_screen.allocate_texture(domain);
|
|
||||||
GPU_texture_copy(keying_screen.texture(), cached_keying_screen.texture());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Domain compute_domain() override
|
Domain compute_domain() override
|
||||||
|
@ -101,8 +101,7 @@ class MaskOperation : public NodeOperation {
|
|||||||
get_motion_blur_samples(),
|
get_motion_blur_samples(),
|
||||||
get_motion_blur_shutter());
|
get_motion_blur_shutter());
|
||||||
|
|
||||||
output_mask.allocate_texture(domain);
|
output_mask.wrap_external(cached_mask.texture());
|
||||||
GPU_texture_copy(output_mask.texture(), cached_mask.texture());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Domain compute_domain() override
|
Domain compute_domain() override
|
||||||
|
@ -63,13 +63,11 @@ class TextureOperation : public NodeOperation {
|
|||||||
get_input("Scale").get_vector_value_default(float4(0.0f)).xy());
|
get_input("Scale").get_vector_value_default(float4(0.0f)).xy());
|
||||||
|
|
||||||
if (color_result.should_compute()) {
|
if (color_result.should_compute()) {
|
||||||
color_result.allocate_texture(domain);
|
color_result.wrap_external(cached_texture.color_texture());
|
||||||
GPU_texture_copy(color_result.texture(), cached_texture.color_texture());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value_result.should_compute()) {
|
if (value_result.should_compute()) {
|
||||||
value_result.allocate_texture(domain);
|
value_result.wrap_external(cached_texture.value_texture());
|
||||||
GPU_texture_copy(value_result.texture(), cached_texture.value_texture());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user