blob: e42fc8fc142c3cf357e6a4075463c3d060a9343e [file] [log] [blame]
Chris Daltonabed2672021-06-17 16:54:28 -06001/*
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 Daltonc3176002021-07-23 15:33:09 -06008#include "src/gpu/effects/GrModulateAtlasCoverageEffect.h"
Chris Daltonabed2672021-06-17 16:54:28 -06009
10#include "src/gpu/GrDynamicAtlas.h"
11#include "src/gpu/effects/GrTextureEffect.h"
12
Chris Daltonc3176002021-07-23 15:33:09 -060013GrModulateAtlasCoverageEffect::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 Daltonabed2672021-06-17 16:54:28 -060020 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 Daltonc3176002021-07-23 15:33:09 -060029GrModulateAtlasCoverageEffect::GrModulateAtlasCoverageEffect(
30 const GrModulateAtlasCoverageEffect& that)
John Stiles307f8f52021-08-09 15:36:59 -040031 : GrFragmentProcessor(that)
Chris Daltonabed2672021-06-17 16:54:28 -060032 , fFlags(that.fFlags)
John Stiles307f8f52021-08-09 15:36:59 -040033 , fBounds(that.fBounds) {}
Chris Daltonabed2672021-06-17 16:54:28 -060034
Brian Salomon3176e862021-08-09 11:23:04 -040035std::unique_ptr<GrFragmentProcessor::ProgramImpl>
36GrModulateAtlasCoverageEffect::onMakeProgramImpl() const {
37 class Impl : public ProgramImpl {
Chris Daltonabed2672021-06-17 16:54:28 -060038 void emitCode(EmitArgs& args) override {
Chris Daltonc3176002021-07-23 15:33:09 -060039 auto fp = args.fFp.cast<GrModulateAtlasCoverageEffect>();
Chris Daltonabed2672021-06-17 16:54:28 -060040 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 Daltonc3176002021-07-23 15:33:09 -060068 auto fp = processor.cast<GrModulateAtlasCoverageEffect>();
Chris Daltonabed2672021-06-17 16:54:28 -060069 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}