Chris Dalton | abed267 | 2021-06-17 16:54:28 -0600 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2021 Google LLC. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. |
| 6 | */ |
| 7 | |
Chris Dalton | c317600 | 2021-07-23 15:33:09 -0600 | [diff] [blame] | 8 | #include "src/gpu/effects/GrModulateAtlasCoverageEffect.h" |
Chris Dalton | abed267 | 2021-06-17 16:54:28 -0600 | [diff] [blame] | 9 | |
| 10 | #include "src/gpu/GrDynamicAtlas.h" |
| 11 | #include "src/gpu/effects/GrTextureEffect.h" |
| 12 | |
Chris Dalton | c317600 | 2021-07-23 15:33:09 -0600 | [diff] [blame] | 13 | GrModulateAtlasCoverageEffect::GrModulateAtlasCoverageEffect( |
| 14 | Flags flags, |
| 15 | std::unique_ptr<GrFragmentProcessor> inputFP, |
| 16 | GrSurfaceProxyView atlasView, |
| 17 | const SkMatrix& devToAtlasMatrix, |
| 18 | const SkIRect& devIBounds) |
| 19 | : GrFragmentProcessor(kTessellate_GrModulateAtlasCoverageEffect_ClassID, |
Chris Dalton | abed267 | 2021-06-17 16:54:28 -0600 | [diff] [blame] | 20 | kCompatibleWithCoverageAsAlpha_OptimizationFlag) |
| 21 | , fFlags(flags) |
| 22 | , fBounds((fFlags & Flags::kCheckBounds) ? devIBounds : SkIRect{0,0,0,0}) { |
| 23 | this->registerChild(std::move(inputFP)); |
| 24 | this->registerChild(GrTextureEffect::Make(std::move(atlasView), kUnknown_SkAlphaType, |
| 25 | devToAtlasMatrix, GrSamplerState::Filter::kNearest), |
| 26 | SkSL::SampleUsage::Explicit()); |
| 27 | } |
| 28 | |
Chris Dalton | c317600 | 2021-07-23 15:33:09 -0600 | [diff] [blame] | 29 | GrModulateAtlasCoverageEffect::GrModulateAtlasCoverageEffect( |
| 30 | const GrModulateAtlasCoverageEffect& that) |
John Stiles | 307f8f5 | 2021-08-09 15:36:59 -0400 | [diff] [blame] | 31 | : GrFragmentProcessor(that) |
Chris Dalton | abed267 | 2021-06-17 16:54:28 -0600 | [diff] [blame] | 32 | , fFlags(that.fFlags) |
John Stiles | 307f8f5 | 2021-08-09 15:36:59 -0400 | [diff] [blame] | 33 | , fBounds(that.fBounds) {} |
Chris Dalton | abed267 | 2021-06-17 16:54:28 -0600 | [diff] [blame] | 34 | |
Brian Salomon | 3176e86 | 2021-08-09 11:23:04 -0400 | [diff] [blame] | 35 | std::unique_ptr<GrFragmentProcessor::ProgramImpl> |
| 36 | GrModulateAtlasCoverageEffect::onMakeProgramImpl() const { |
| 37 | class Impl : public ProgramImpl { |
Chris Dalton | abed267 | 2021-06-17 16:54:28 -0600 | [diff] [blame] | 38 | void emitCode(EmitArgs& args) override { |
Chris Dalton | c317600 | 2021-07-23 15:33:09 -0600 | [diff] [blame] | 39 | auto fp = args.fFp.cast<GrModulateAtlasCoverageEffect>(); |
Chris Dalton | abed267 | 2021-06-17 16:54:28 -0600 | [diff] [blame] | 40 | auto f = args.fFragBuilder; |
| 41 | auto uniHandler = args.fUniformHandler; |
| 42 | SkString inputColor = this->invokeChild(0, args); |
| 43 | f->codeAppend("half coverage = 0;"); |
| 44 | if (fp.fFlags & Flags::kCheckBounds) { |
| 45 | const char* boundsName; |
| 46 | fBoundsUniform = uniHandler->addUniform(&fp, kFragment_GrShaderFlag, |
| 47 | kFloat4_GrSLType, "bounds", &boundsName); |
| 48 | // Are we inside the path's valid atlas bounds? |
| 49 | f->codeAppendf("if (all(greaterThan(sk_FragCoord.xy, %s.xy)) && " |
| 50 | "all(lessThan(sk_FragCoord.xy, %s.zw))) ", |
| 51 | boundsName, boundsName); |
| 52 | } |
| 53 | f->codeAppendf("{"); |
| 54 | SkString atlasCoverage = this->invokeChild(1, args, "sk_FragCoord.xy"); |
| 55 | f->codeAppendf("coverage = %s.a;", atlasCoverage.c_str()); |
| 56 | f->codeAppendf("}"); |
| 57 | const char* coverageMaybeInvertName; |
| 58 | fCoverageMaybeInvertUniform = uniHandler->addUniform(&fp, kFragment_GrShaderFlag, |
| 59 | kHalf2_GrSLType, "coverageInvert", |
| 60 | &coverageMaybeInvertName); |
| 61 | // Invert coverage, if needed. |
| 62 | f->codeAppendf("coverage = coverage * %s.x + %s.y;", |
| 63 | coverageMaybeInvertName, coverageMaybeInvertName); |
| 64 | f->codeAppendf("return %s * coverage;", inputColor.c_str()); |
| 65 | } |
| 66 | void onSetData(const GrGLSLProgramDataManager& pdman, |
| 67 | const GrFragmentProcessor& processor) override { |
Chris Dalton | c317600 | 2021-07-23 15:33:09 -0600 | [diff] [blame] | 68 | auto fp = processor.cast<GrModulateAtlasCoverageEffect>(); |
Chris Dalton | abed267 | 2021-06-17 16:54:28 -0600 | [diff] [blame] | 69 | if (fp.fFlags & Flags::kCheckBounds) { |
| 70 | pdman.set4fv(fBoundsUniform, 1, SkRect::Make(fp.fBounds).asScalars()); |
| 71 | } |
| 72 | if (fp.fFlags & Flags::kInvertCoverage) { |
| 73 | pdman.set2f(fCoverageMaybeInvertUniform, -1, 1); // -1*coverage + 1 = 1 - coverage. |
| 74 | } else { |
| 75 | pdman.set2f(fCoverageMaybeInvertUniform, 1, 0); // 1*coverage + 0 = coverage. |
| 76 | } |
| 77 | } |
| 78 | UniformHandle fBoundsUniform; |
| 79 | UniformHandle fCoverageMaybeInvertUniform; |
| 80 | }; |
| 81 | return std::make_unique<Impl>(); |
| 82 | } |