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