diff options
author | Brian Osman <brianosman@google.com> | 2017-03-22 10:57:00 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-03-22 16:31:39 +0000 |
commit | de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3 (patch) | |
tree | b198af69715b55724ca5e5f1b746db4fc7c11498 /src/gpu/GrFragmentProcessor.cpp | |
parent | ca0913ceb9a64d02e6fd6345e71af219f568430e (diff) |
Support premul/unpremul of F16 during read/writePixels
Added PremulOutput and UnpremulOutput FP helpers. These are used
(rather than GrConfigConversionEffect) when working with FP16
textures (and will also be used for other configs that can't be
round-tripped via rounding).
BUG=skia:5853
Change-Id: I101592c26c4f0b379d5e5a8678ef7b2f08e6ad56
Reviewed-on: https://skia-review.googlesource.com/9980
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Diffstat (limited to 'src/gpu/GrFragmentProcessor.cpp')
-rw-r--r-- | src/gpu/GrFragmentProcessor.cpp | 116 |
1 files changed, 87 insertions, 29 deletions
diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp index 30b3061144..27d0bcdf31 100644 --- a/src/gpu/GrFragmentProcessor.cpp +++ b/src/gpu/GrFragmentProcessor.cpp @@ -106,42 +106,84 @@ sk_sp<GrFragmentProcessor> GrFragmentProcessor::MulOutputByInputAlpha( return GrXfermodeFragmentProcessor::MakeFromDstProcessor(std::move(fp), SkBlendMode::kDstIn); } -sk_sp<GrFragmentProcessor> GrFragmentProcessor::PremulInput(sk_sp<GrFragmentProcessor> fp) { +namespace { + +class PremulInputFragmentProcessor : public GrFragmentProcessor { +public: + PremulInputFragmentProcessor() + : INHERITED(kPreservesOpaqueInput_OptimizationFlag | + kConstantOutputForConstantInput_OptimizationFlag) { + this->initClassID<PremulInputFragmentProcessor>(); + } - class PremulInputFragmentProcessor : public GrFragmentProcessor { - public: - PremulInputFragmentProcessor() - : INHERITED(kPreservesOpaqueInput_OptimizationFlag | - kConstantOutputForConstantInput_OptimizationFlag) { - this->initClassID<PremulInputFragmentProcessor>(); - } + const char* name() const override { return "PremultiplyInput"; } - const char* name() const override { return "PremultiplyInput"; } - private: - GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { - class GLFP : public GrGLSLFragmentProcessor { - public: - void emitCode(EmitArgs& args) override { - GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; +private: + GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { + class GLFP : public GrGLSLFragmentProcessor { + public: + void emitCode(EmitArgs& args) override { + GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; - fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, args.fInputColor); - fragBuilder->codeAppendf("%s.rgb *= %s.a;", - args.fOutputColor, args.fInputColor); - } - }; - return new GLFP; - } + fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, args.fInputColor); + fragBuilder->codeAppendf("%s.rgb *= %s.a;", + args.fOutputColor, args.fInputColor); + } + }; + return new GLFP; + } - void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {} + void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {} - bool onIsEqual(const GrFragmentProcessor&) const override { return true; } + bool onIsEqual(const GrFragmentProcessor&) const override { return true; } - GrColor4f constantOutputForConstantInput(GrColor4f input) const override { - return input.premul(); - } + GrColor4f constantOutputForConstantInput(GrColor4f input) const override { + return input.premul(); + } - typedef GrFragmentProcessor INHERITED; - }; + typedef GrFragmentProcessor INHERITED; +}; + +class UnpremulInputFragmentProcessor : public GrFragmentProcessor { +public: + UnpremulInputFragmentProcessor() + : INHERITED(kPreservesOpaqueInput_OptimizationFlag | + kConstantOutputForConstantInput_OptimizationFlag) { + this->initClassID<UnpremulInputFragmentProcessor>(); + } + + const char* name() const override { return "UnpremultiplyInput"; } + +private: + GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { + class GLFP : public GrGLSLFragmentProcessor { + public: + void emitCode(EmitArgs& args) override { + GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; + + fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, args.fInputColor); + fragBuilder->codeAppendf("float invAlpha = %s.a <= 0.0 ? 0.0 : 1.0 / %s.a;", + args.fInputColor, args.fInputColor); + fragBuilder->codeAppendf("%s.rgb *= invAlpha;", args.fOutputColor); + } + }; + return new GLFP; + } + + void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {} + + bool onIsEqual(const GrFragmentProcessor&) const override { return true; } + + GrColor4f constantOutputForConstantInput(GrColor4f input) const override { + return input.unpremul(); + } + + typedef GrFragmentProcessor INHERITED; +}; + +} + +sk_sp<GrFragmentProcessor> GrFragmentProcessor::PremulInput(sk_sp<GrFragmentProcessor> fp) { if (!fp) { return nullptr; } @@ -149,6 +191,22 @@ sk_sp<GrFragmentProcessor> GrFragmentProcessor::PremulInput(sk_sp<GrFragmentProc return GrFragmentProcessor::RunInSeries(fpPipeline, 2); } +sk_sp<GrFragmentProcessor> GrFragmentProcessor::PremulOutput(sk_sp<GrFragmentProcessor> fp) { + if (!fp) { + return nullptr; + } + sk_sp<GrFragmentProcessor> fpPipeline[] = { fp, sk_make_sp<PremulInputFragmentProcessor>() }; + return GrFragmentProcessor::RunInSeries(fpPipeline, 2); +} + +sk_sp<GrFragmentProcessor> GrFragmentProcessor::UnpremulOutput(sk_sp<GrFragmentProcessor> fp) { + if (!fp) { + return nullptr; + } + sk_sp<GrFragmentProcessor> fpPipeline[] = { fp, sk_make_sp<UnpremulInputFragmentProcessor>() }; + return GrFragmentProcessor::RunInSeries(fpPipeline, 2); +} + sk_sp<GrFragmentProcessor> GrFragmentProcessor::MakeInputPremulAndMulByOutput( sk_sp<GrFragmentProcessor> fp) { |