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