diff --git a/app/render/renderer.cpp b/app/render/renderer.cpp index acd9885eb..83107935b 100644 --- a/app/render/renderer.cpp +++ b/app/render/renderer.cpp @@ -56,14 +56,14 @@ TexturePtr Renderer::CreateTexture(const VideoParams ¶ms, const void *data, return CreateTexture(params, Texture::k2D, Texture::kRGBA, data, linesize); } -void Renderer::BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, Texture *destination, const QMatrix4x4 &matrix) +void Renderer::BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, bool source_is_premultiplied, Texture *destination, const QMatrix4x4 &matrix) { - BlitColorManagedInternal(color_processor, source, destination, destination->params(), matrix); + BlitColorManagedInternal(color_processor, source, source_is_premultiplied, destination, destination->params(), matrix); } -void Renderer::BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, VideoParams params, const QMatrix4x4& matrix) +void Renderer::BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, bool source_is_premultiplied, VideoParams params, const QMatrix4x4& matrix) { - BlitColorManagedInternal(color_processor, source, nullptr, params, matrix); + BlitColorManagedInternal(color_processor, source, source_is_premultiplied, nullptr, params, matrix); } void Renderer::Destroy() @@ -101,6 +101,12 @@ bool Renderer::GetColorContext(ColorProcessorPtr color_processor, Renderer::Colo "\n" "// Main texture input\n" "uniform sampler2D ove_maintex;\n" + "uniform int ove_maintex_alpha;\n" + "\n" + "// Macros defining `ove_maintex_alpha` state\n" + "#define ALPHA_NONE 0\n" + "#define ALPHA_UNASSOC 1\n" + "#define ALPHA_ASSOC 2\n" "\n" "// Macros so OCIO's shaders work on this GLSL version\n" "#define texture2D texture\n" @@ -113,8 +119,38 @@ bool Renderer::GetColorContext(ColorProcessorPtr color_processor, Renderer::Colo "out vec4 fragColor;\n")); shader_frag.append(shader_desc->getShaderText()); shader_frag.append(QStringLiteral("\n" + "// Alpha association functions\n" + "vec4 assoc(vec4 c) {\n" + " return vec4(c.rgb * c.a, c.a);\n" + "}\n" + "\n" + "vec4 reassoc(vec4 c) {\n" + " return (c.a == 0.0) ? c : assoc(c);\n" + "}\n" + "\n" + "vec4 deassoc(vec4 c) {\n" + " return (c.a == 0.0) ? c : vec4(c.rgb / c.a, c.a);\n" + "}\n" + "\n" "void main() {\n" - " fragColor = %1(texture(ove_maintex, ove_texcoord));\n" + " vec4 col = texture(ove_maintex, ove_texcoord);\n" + "\n" + " // If alpha is associated, de-associate now\n" + " if (ove_maintex_alpha == ALPHA_ASSOC) {\n" + " col = deassoc(col);\n" + " }\n" + "\n" + " // Perform color conversion\n" + " col = %1(col);\n" + "\n" + " // Associate or re-associate here\n" + " if (ove_maintex_alpha == ALPHA_ASSOC) {\n" + " col = reassoc(col);\n" + " } else if (ove_maintex_alpha == ALPHA_UNASSOC) {\n" + " col = assoc(col);\n" + " }\n" + "\n" + " fragColor = col;\n" "}\n").arg(ocio_func_name)); // Try to compile shader @@ -194,7 +230,9 @@ bool Renderer::GetColorContext(ColorProcessorPtr color_processor, Renderer::Colo } } -void Renderer::BlitColorManagedInternal(ColorProcessorPtr color_processor, TexturePtr source, Texture *destination, VideoParams params, const QMatrix4x4& matrix) +void Renderer::BlitColorManagedInternal(ColorProcessorPtr color_processor, TexturePtr source, + bool source_is_premultiplied, Texture *destination, + VideoParams params, const QMatrix4x4& matrix) { ColorContext color_ctx; if (!GetColorContext(color_processor, &color_ctx)) { diff --git a/app/render/renderer.h b/app/render/renderer.h index bee5dc21b..fdea3da57 100644 --- a/app/render/renderer.h +++ b/app/render/renderer.h @@ -60,8 +60,8 @@ public: Blit(shader, job, nullptr, params); } - void BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, Texture* destination, const QMatrix4x4& matrix = QMatrix4x4()); - void BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, VideoParams params, const QMatrix4x4& matrix = QMatrix4x4()); + void BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, bool source_is_premultiplied, Texture* destination, const QMatrix4x4& matrix = QMatrix4x4()); + void BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, bool source_is_premultiplied, VideoParams params, const QMatrix4x4& matrix = QMatrix4x4()); void Destroy(); @@ -108,6 +108,7 @@ private: bool GetColorContext(ColorProcessorPtr color_processor, ColorContext* ctx); void BlitColorManagedInternal(ColorProcessorPtr color_processor, TexturePtr source, + bool source_is_premultiplied, Texture* destination, VideoParams params, const QMatrix4x4 &matrix); QHash color_cache_; diff --git a/app/render/renderprocessor.cpp b/app/render/renderprocessor.cpp index 146cb5d7a..a9bdca01a 100644 --- a/app/render/renderprocessor.cpp +++ b/app/render/renderprocessor.cpp @@ -95,7 +95,7 @@ void RenderProcessor::Run() if (output_color_transform) { // Yes color transform, blit color managed - render_ctx_->BlitColorManaged(output_color_transform, texture, blit_tex.get(), matrix); + render_ctx_->BlitColorManaged(output_color_transform, texture, true, blit_tex.get(), matrix); } else { // No color transform, just blit ShaderJob job; @@ -326,13 +326,15 @@ QVariant RenderProcessor::ProcessVideoFootage(StreamPtr stream, const rational & managed_params.set_format(video_params.format()); value = render_ctx_->CreateTexture(managed_params); - qDebug() << "FIXME: Accessing video_stream->colorspace() may cause race conditions"; + qDebug() << "FIXME: Accessing video_stream->colorspace() and video_stream->premultiplied_alpha() may cause race conditions"; ColorProcessorPtr processor = ColorProcessor::Create(color_manager, video_stream->colorspace(), color_manager->GetReferenceColorSpace()); - render_ctx_->BlitColorManaged(processor, unmanaged_texture, value.get()); + render_ctx_->BlitColorManaged(processor, unmanaged_texture, + video_stream->premultiplied_alpha(), + value.get()); still_image_cache_->mutex()->lock(); diff --git a/app/widget/scope/scopebase/scopebase.cpp b/app/widget/scope/scopebase/scopebase.cpp index 76a717112..9cf864a24 100644 --- a/app/widget/scope/scopebase/scopebase.cpp +++ b/app/widget/scope/scopebase/scopebase.cpp @@ -102,7 +102,7 @@ void ScopeBase::OnPaint() if (buffer_) { // Convert reference frame to display space - renderer()->BlitColorManaged(color_service(), texture_, managed_tex_.get()); + renderer()->BlitColorManaged(color_service(), texture_, true, managed_tex_.get()); DrawScope(managed_tex_, pipeline_); } diff --git a/app/widget/viewer/viewerdisplay.cpp b/app/widget/viewer/viewerdisplay.cpp index 9832f9727..84e9487bf 100644 --- a/app/widget/viewer/viewerdisplay.cpp +++ b/app/widget/viewer/viewerdisplay.cpp @@ -298,7 +298,7 @@ void ViewerDisplayWidget::OnPaint() } // Draw texture through color transform - renderer()->BlitColorManaged(color_service(), texture_, + renderer()->BlitColorManaged(color_service(), texture_, true, VideoParams(width(), height(), PixelFormat::PIX_FMT_RGBA16F), GetCompleteMatrixFlippedYTranslation()); }