aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrFragmentProcessor.cpp
diff options
context:
space:
mode:
authorGravatar Brian Osman <brianosman@google.com>2017-03-22 10:57:00 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-03-22 16:31:39 +0000
commitde1a60534648ca8a6eb3ae32e06a7a9e9c0591f3 (patch)
treeb198af69715b55724ca5e5f1b746db4fc7c11498 /src/gpu/GrFragmentProcessor.cpp
parentca0913ceb9a64d02e6fd6345e71af219f568430e (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.cpp116
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) {