From 2d2da4f9ee4932720c71348d0aff0cd75ebd956b Mon Sep 17 00:00:00 2001 From: Brian Osman Date: Wed, 12 Apr 2017 17:07:22 -0400 Subject: [PATCH] Do sRGB premul/unpremul on the GPU Previously, the early check would decide that sRGB pixel configs were okay (because they're 8888-unorm). Then we'd go to make the effect and decide that we didn't want them to work. This led to the software fallback. The software fallback was obviously slower, but also doing non-linear premul/unpremul operations. Eventually, whether or not the premul is linear should be dictated by the destination color space, but for now, this is an improvement (and only affects the one GM that tests this feature). Bug: skia: Change-Id: I0cf1ad5a7f552135ac1da728c6db2977652a433b Reviewed-on: https://skia-review.googlesource.com/13321 Reviewed-by: Robert Phillips Commit-Queue: Brian Osman --- src/gpu/GrContext.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 31f1787..7ea4abd 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -919,16 +919,20 @@ sk_sp GrContext::createPMToUPMEffect(sk_sptestPMConversionsIfNecessary(). SkASSERT(fDidTestPMConversions); - if (kRGBA_half_GrPixelConfig == config) { - return GrFragmentProcessor::UnpremulOutput(std::move(fp)); - } else if (kRGBA_8888_GrPixelConfig == config || kBGRA_8888_GrPixelConfig == config) { + // We have specialized effects that guarantee round-trip conversion for these formats + if (kRGBA_8888_GrPixelConfig == config || kBGRA_8888_GrPixelConfig == config) { GrConfigConversionEffect::PMConversion pmToUPM = static_cast(fPMToUPMConversion); if (GrConfigConversionEffect::kPMConversionCnt != pmToUPM) { return GrConfigConversionEffect::Make(std::move(fp), pmToUPM); + } else { + return nullptr; } + } else { + // For everything else (sRGB, half-float, etc...), it doesn't make sense to try and + // explicitly round the results. Just do the obvious, naive thing in the shader. + return GrFragmentProcessor::UnpremulOutput(std::move(fp)); } - return nullptr; } sk_sp GrContext::createUPMToPMEffect(sk_sp fp, @@ -936,16 +940,20 @@ sk_sp GrContext::createUPMToPMEffect(sk_sptestPMConversionsIfNecessary(). SkASSERT(fDidTestPMConversions); - if (kRGBA_half_GrPixelConfig == config) { - return GrFragmentProcessor::PremulOutput(std::move(fp)); - } else if (kRGBA_8888_GrPixelConfig == config || kBGRA_8888_GrPixelConfig == config) { + // We have specialized effects that guarantee round-trip conversion for these formats + if (kRGBA_8888_GrPixelConfig == config || kBGRA_8888_GrPixelConfig == config) { GrConfigConversionEffect::PMConversion upmToPM = static_cast(fUPMToPMConversion); if (GrConfigConversionEffect::kPMConversionCnt != upmToPM) { return GrConfigConversionEffect::Make(std::move(fp), upmToPM); + } else { + return nullptr; } + } else { + // For everything else (sRGB, half-float, etc...), it doesn't make sense to try and + // explicitly round the results. Just do the obvious, naive thing in the shader. + return GrFragmentProcessor::PremulOutput(std::move(fp)); } - return nullptr; } bool GrContext::validPMUPMConversionExists(GrPixelConfig config) const { -- 2.7.4