• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
8 #include "src/gpu/effects/GrModulateAtlasCoverageEffect.h"
9 
10 #include "src/gpu/GrDynamicAtlas.h"
11 #include "src/gpu/KeyBuilder.h"
12 #include "src/gpu/effects/GrTextureEffect.h"
13 
GrModulateAtlasCoverageEffect(Flags flags,std::unique_ptr<GrFragmentProcessor> inputFP,GrSurfaceProxyView atlasView,const SkMatrix & devToAtlasMatrix,const SkIRect & devIBounds)14 GrModulateAtlasCoverageEffect::GrModulateAtlasCoverageEffect(
15         Flags flags,
16         std::unique_ptr<GrFragmentProcessor> inputFP,
17         GrSurfaceProxyView atlasView,
18         const SkMatrix& devToAtlasMatrix,
19         const SkIRect& devIBounds)
20         : GrFragmentProcessor(kTessellate_GrModulateAtlasCoverageEffect_ClassID,
21                               kCompatibleWithCoverageAsAlpha_OptimizationFlag)
22         , fFlags(flags)
23         , fBounds((fFlags & Flags::kCheckBounds) ? devIBounds : SkIRect{0,0,0,0}) {
24     this->registerChild(std::move(inputFP));
25     this->registerChild(GrTextureEffect::Make(std::move(atlasView), kUnknown_SkAlphaType,
26                                               devToAtlasMatrix, GrSamplerState::Filter::kNearest),
27                         SkSL::SampleUsage::Explicit());
28 }
29 
GrModulateAtlasCoverageEffect(const GrModulateAtlasCoverageEffect & that)30 GrModulateAtlasCoverageEffect::GrModulateAtlasCoverageEffect(
31         const GrModulateAtlasCoverageEffect& that)
32         : GrFragmentProcessor(that)
33         , fFlags(that.fFlags)
34         , fBounds(that.fBounds) {}
35 
onAddToKey(const GrShaderCaps &,skgpu::KeyBuilder * b) const36 void GrModulateAtlasCoverageEffect::onAddToKey(const GrShaderCaps&,
37                                                skgpu::KeyBuilder* b) const {
38     b->add32(fFlags & Flags::kCheckBounds);
39 }
40 
41 std::unique_ptr<GrFragmentProcessor::ProgramImpl>
onMakeProgramImpl() const42 GrModulateAtlasCoverageEffect::onMakeProgramImpl() const {
43     class Impl : public ProgramImpl {
44         void emitCode(EmitArgs& args) override {
45             auto fp = args.fFp.cast<GrModulateAtlasCoverageEffect>();
46             auto f = args.fFragBuilder;
47             auto uniHandler = args.fUniformHandler;
48             SkString inputColor = this->invokeChild(0, args);
49             f->codeAppend("half coverage = 0;");
50             if (fp.fFlags & Flags::kCheckBounds) {
51                 const char* boundsName;
52                 fBoundsUniform = uniHandler->addUniform(&fp, kFragment_GrShaderFlag,
53                                                         SkSLType::kFloat4, "bounds", &boundsName);
54                 // Are we inside the path's valid atlas bounds?
55                 f->codeAppendf("if (all(greaterThan(sk_FragCoord.xy, %s.xy)) && "
56                                    "all(lessThan(sk_FragCoord.xy, %s.zw))) ",
57                                boundsName, boundsName);
58             }
59             f->codeAppendf("{");
60             SkString atlasCoverage = this->invokeChild(1, args, "sk_FragCoord.xy");
61             f->codeAppendf("coverage = %s.a;", atlasCoverage.c_str());
62             f->codeAppendf("}");
63             const char* coverageMaybeInvertName;
64             fCoverageMaybeInvertUniform = uniHandler->addUniform(&fp, kFragment_GrShaderFlag,
65                                                                  SkSLType::kHalf2, "coverageInvert",
66                                                                  &coverageMaybeInvertName);
67             // Invert coverage, if needed.
68             f->codeAppendf("coverage = coverage * %s.x + %s.y;",
69                            coverageMaybeInvertName, coverageMaybeInvertName);
70             f->codeAppendf("return %s * coverage;", inputColor.c_str());
71         }
72 
73     private:
74         void onSetData(const GrGLSLProgramDataManager& pdman,
75                        const GrFragmentProcessor& processor) override {
76             auto fp = processor.cast<GrModulateAtlasCoverageEffect>();
77             if (fp.fFlags & Flags::kCheckBounds) {
78                 pdman.set4fv(fBoundsUniform, 1, SkRect::Make(fp.fBounds).asScalars());
79             }
80             if (fp.fFlags & Flags::kInvertCoverage) {
81                 pdman.set2f(fCoverageMaybeInvertUniform, -1, 1);  // -1*coverage + 1 = 1 - coverage.
82             } else {
83                 pdman.set2f(fCoverageMaybeInvertUniform, 1, 0);  // 1*coverage + 0 = coverage.
84             }
85         }
86         UniformHandle fBoundsUniform;
87         UniformHandle fCoverageMaybeInvertUniform;
88     };
89 
90     return std::make_unique<Impl>();
91 }
92