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
|
||||
* 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
|
||||
* 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 {
|
||||
private:
|
||||
/* 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.
|
||||
* See that method for more information. */
|
||||
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:
|
||||
/* 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. */
|
||||
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. */
|
||||
void set_transformation(const float3x3 &transformation);
|
||||
|
||||
|
@ -192,6 +192,19 @@ void Result::steal_data(Result &source)
|
||||
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)
|
||||
{
|
||||
domain_.transformation = transformation;
|
||||
@ -298,7 +311,9 @@ void Result::release()
|
||||
* texture pool. */
|
||||
reference_count_--;
|
||||
if (reference_count_ == 0) {
|
||||
texture_pool_->release(texture_);
|
||||
if (!is_external_) {
|
||||
texture_pool_->release(texture_);
|
||||
}
|
||||
texture_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -108,9 +108,7 @@ class KeyingScreenOperation : public NodeOperation {
|
||||
KeyingScreen &cached_keying_screen = context().cache_manager().keying_screens.get(
|
||||
context(), get_movie_clip(), movie_tracking_object, get_smoothness());
|
||||
|
||||
const Domain domain = compute_domain();
|
||||
keying_screen.allocate_texture(domain);
|
||||
GPU_texture_copy(keying_screen.texture(), cached_keying_screen.texture());
|
||||
keying_screen.wrap_external(cached_keying_screen.texture());
|
||||
}
|
||||
|
||||
Domain compute_domain() override
|
||||
|
@ -101,8 +101,7 @@ class MaskOperation : public NodeOperation {
|
||||
get_motion_blur_samples(),
|
||||
get_motion_blur_shutter());
|
||||
|
||||
output_mask.allocate_texture(domain);
|
||||
GPU_texture_copy(output_mask.texture(), cached_mask.texture());
|
||||
output_mask.wrap_external(cached_mask.texture());
|
||||
}
|
||||
|
||||
Domain compute_domain() override
|
||||
|
@ -63,13 +63,11 @@ class TextureOperation : public NodeOperation {
|
||||
get_input("Scale").get_vector_value_default(float4(0.0f)).xy());
|
||||
|
||||
if (color_result.should_compute()) {
|
||||
color_result.allocate_texture(domain);
|
||||
GPU_texture_copy(color_result.texture(), cached_texture.color_texture());
|
||||
color_result.wrap_external(cached_texture.color_texture());
|
||||
}
|
||||
|
||||
if (value_result.should_compute()) {
|
||||
value_result.allocate_texture(domain);
|
||||
GPU_texture_copy(value_result.texture(), cached_texture.value_texture());
|
||||
value_result.wrap_external(cached_texture.value_texture());
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user