From 98308fb081687970278dce2a7631005f9cb424a8 Mon Sep 17 00:00:00 2001 From: Mike Reed Date: Fri, 7 Jul 2017 08:28:13 -0400 Subject: Plumb through need for unpremul/premul Update unittest to build test image with legal premul pixels. Bug: skia: Change-Id: Iebd1d2f81cac77f8913bd79f6ac25983ed710641 Reviewed-on: https://skia-review.googlesource.com/21735 Reviewed-by: Brian Osman Commit-Queue: Mike Reed --- src/gpu/GrYUVProvider.cpp | 3 ++- src/gpu/effects/GrSRGBEffect.cpp | 52 ++++++++++++++++++++++++---------------- src/gpu/effects/GrSRGBEffect.h | 13 +++++++--- 3 files changed, 44 insertions(+), 24 deletions(-) (limited to 'src/gpu') diff --git a/src/gpu/GrYUVProvider.cpp b/src/gpu/GrYUVProvider.cpp index 5ab926be35..df7113911f 100644 --- a/src/gpu/GrYUVProvider.cpp +++ b/src/gpu/GrYUVProvider.cpp @@ -148,7 +148,8 @@ sk_sp GrYUVProvider::refAsTextureProxy(GrContext* ctx, if (ctx->caps()->srgbWriteControl()) { paint.setDisableOutputConversionToSRGB(true); } else { - paint.addColorFragmentProcessor(GrSRGBEffect::Make(GrSRGBEffect::Mode::kSRGBToLinear)); + paint.addColorFragmentProcessor(GrSRGBEffect::Make(GrSRGBEffect::Mode::kSRGBToLinear, + GrSRGBEffect::Alpha::kOpaque)); } } diff --git a/src/gpu/effects/GrSRGBEffect.cpp b/src/gpu/effects/GrSRGBEffect.cpp index c9a48b3d84..294e7f4551 100644 --- a/src/gpu/effects/GrSRGBEffect.cpp +++ b/src/gpu/effects/GrSRGBEffect.cpp @@ -47,18 +47,26 @@ public: args.fInputColor = "vec4(1)"; } - fragBuilder->codeAppendf("%s = vec4(%s(%s.r), %s(%s.g), %s(%s.b), %s.a);", - args.fOutputColor, - srgbFuncName.c_str(), args.fInputColor, - srgbFuncName.c_str(), args.fInputColor, - srgbFuncName.c_str(), args.fInputColor, - args.fInputColor); + fragBuilder->codeAppendf("vec4 color = %s;", args.fInputColor); + if (srgbe.alpha() == GrSRGBEffect::Alpha::kPremul) { + fragBuilder->codeAppendf("float nonZeroAlpha = max(color.a, 0.00001);"); + fragBuilder->codeAppendf("color = vec4(color.rgb / nonZeroAlpha, color.a);"); + } + fragBuilder->codeAppendf("color = vec4(%s(color.r), %s(color.g), %s(color.b), color.a);", + srgbFuncName.c_str(), + srgbFuncName.c_str(), + srgbFuncName.c_str()); + if (srgbe.alpha() == GrSRGBEffect::Alpha::kPremul) { + fragBuilder->codeAppendf("color = vec4(color.rgb, 1) * color.a;"); + } + fragBuilder->codeAppendf("%s = color;", args.fOutputColor); } static inline void GenKey(const GrProcessor& processor, const GrShaderCaps&, GrProcessorKeyBuilder* b) { const GrSRGBEffect& srgbe = processor.cast(); - uint32_t key = static_cast(srgbe.mode()); + uint32_t key = static_cast(srgbe.mode()) | + (static_cast(srgbe.alpha()) << 1); b->add32(key); } @@ -68,10 +76,12 @@ private: /////////////////////////////////////////////////////////////////////////////// -GrSRGBEffect::GrSRGBEffect(Mode mode) - : INHERITED(kPreservesOpaqueInput_OptimizationFlag | - kConstantOutputForConstantInput_OptimizationFlag) - , fMode(mode) { +GrSRGBEffect::GrSRGBEffect(Mode mode, Alpha alpha) + : INHERITED(kPreservesOpaqueInput_OptimizationFlag | + kConstantOutputForConstantInput_OptimizationFlag) + , fMode(mode) + , fAlpha(alpha) +{ this->initClassID(); } @@ -87,17 +97,19 @@ static inline float linear_to_srgb(float linear) { return (linear <= 0.0031308) ? linear * 12.92f : 1.055f * powf(linear, 1.f / 2.4f) - 0.055f; } -GrColor4f GrSRGBEffect::constantOutputForConstantInput(GrColor4f input) const { +GrColor4f GrSRGBEffect::constantOutputForConstantInput(GrColor4f color) const { + color = color.unpremul(); switch (fMode) { case Mode::kLinearToSRGB: - return GrColor4f(linear_to_srgb(input.fRGBA[0]), linear_to_srgb(input.fRGBA[1]), - linear_to_srgb(input.fRGBA[2]), input.fRGBA[3]); + color = GrColor4f(linear_to_srgb(color.fRGBA[0]), linear_to_srgb(color.fRGBA[1]), + linear_to_srgb(color.fRGBA[2]), color.fRGBA[3]); + break; case Mode::kSRGBToLinear: - return GrColor4f(srgb_to_linear(input.fRGBA[0]), srgb_to_linear(input.fRGBA[1]), - srgb_to_linear(input.fRGBA[2]), input.fRGBA[3]); + color = GrColor4f(srgb_to_linear(color.fRGBA[0]), srgb_to_linear(color.fRGBA[1]), + srgb_to_linear(color.fRGBA[2]), color.fRGBA[3]); + break; } - SkFAIL("Unexpected mode"); - return GrColor4f::TransparentBlack(); + return color.premul(); } /////////////////////////////////////////////////////////////////////////////// @@ -107,7 +119,7 @@ GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrSRGBEffect); #if GR_TEST_UTILS sk_sp GrSRGBEffect::TestCreate(GrProcessorTestData* d) { Mode testMode = static_cast(d->fRandom->nextRangeU(0, 1)); - return GrSRGBEffect::Make(testMode); + return GrSRGBEffect::Make(testMode, Alpha::kPremul); } #endif @@ -119,6 +131,6 @@ void GrSRGBEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps, } GrGLSLFragmentProcessor* GrSRGBEffect::onCreateGLSLInstance() const { - return new GrGLSRGBEffect(); + return new GrGLSRGBEffect; } diff --git a/src/gpu/effects/GrSRGBEffect.h b/src/gpu/effects/GrSRGBEffect.h index f91224e56d..13d8bc3cb9 100644 --- a/src/gpu/effects/GrSRGBEffect.h +++ b/src/gpu/effects/GrSRGBEffect.h @@ -17,19 +17,25 @@ public: kSRGBToLinear, }; + enum class Alpha { + kPremul, + kOpaque, + }; + /** * Creates an effect that applies the sRGB transfer function (or its inverse) */ - static sk_sp Make(Mode mode) { - return sk_sp(new GrSRGBEffect(mode)); + static sk_sp Make(Mode mode, Alpha alpha) { + return sk_sp(new GrSRGBEffect(mode, alpha)); } const char* name() const override { return "sRGB"; } Mode mode() const { return fMode; } + Alpha alpha() const { return fAlpha; } private: - GrSRGBEffect(Mode mode); + GrSRGBEffect(Mode mode, Alpha); GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; @@ -38,6 +44,7 @@ private: GrColor4f constantOutputForConstantInput(GrColor4f input) const override; Mode fMode; + Alpha fAlpha; GR_DECLARE_FRAGMENT_PROCESSOR_TEST -- cgit v1.2.3