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/effects/GrTextureEffect.h" 12 13GrModulateAtlasCoverageEffect::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, 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 29GrModulateAtlasCoverageEffect::GrModulateAtlasCoverageEffect( 30 const GrModulateAtlasCoverageEffect& that) 31 : GrFragmentProcessor(that) 32 , fFlags(that.fFlags) 33 , fBounds(that.fBounds) {} 34 35std::unique_ptr<GrFragmentProcessor::ProgramImpl> 36GrModulateAtlasCoverageEffect::onMakeProgramImpl() const { 37 class Impl : public ProgramImpl { 38 void emitCode(EmitArgs& args) override { 39 auto fp = args.fFp.cast<GrModulateAtlasCoverageEffect>(); 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 67 private: 68 void onSetData(const GrGLSLProgramDataManager& pdman, 69 const GrFragmentProcessor& processor) override { 70 auto fp = processor.cast<GrModulateAtlasCoverageEffect>(); 71 if (fp.fFlags & Flags::kCheckBounds) { 72 pdman.set4fv(fBoundsUniform, 1, SkRect::Make(fp.fBounds).asScalars()); 73 } 74 if (fp.fFlags & Flags::kInvertCoverage) { 75 pdman.set2f(fCoverageMaybeInvertUniform, -1, 1); // -1*coverage + 1 = 1 - coverage. 76 } else { 77 pdman.set2f(fCoverageMaybeInvertUniform, 1, 0); // 1*coverage + 0 = coverage. 78 } 79 } 80 UniformHandle fBoundsUniform; 81 UniformHandle fCoverageMaybeInvertUniform; 82 }; 83 84 return std::make_unique<Impl>(); 85} 86