1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2013 Google Inc. 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/GrShaderCaps.h" 9cb93a386Sopenharmony_ci#include "src/gpu/effects/GrBezierEffect.h" 10cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h" 11cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLProgramDataManager.h" 12cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLUniformHandler.h" 13cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLVarying.h" 14cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h" 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_ciclass GrConicEffect::Impl : public ProgramImpl { 17cb93a386Sopenharmony_cipublic: 18cb93a386Sopenharmony_ci void setData(const GrGLSLProgramDataManager& pdman, 19cb93a386Sopenharmony_ci const GrShaderCaps& shaderCaps, 20cb93a386Sopenharmony_ci const GrGeometryProcessor& geomProc) override { 21cb93a386Sopenharmony_ci const GrConicEffect& ce = geomProc.cast<GrConicEffect>(); 22cb93a386Sopenharmony_ci 23cb93a386Sopenharmony_ci SetTransform(pdman, shaderCaps, fViewMatrixUniform, ce.fViewMatrix, &fViewMatrix); 24cb93a386Sopenharmony_ci SetTransform(pdman, shaderCaps, fLocalMatrixUniform, ce.fLocalMatrix, &fLocalMatrix); 25cb93a386Sopenharmony_ci 26cb93a386Sopenharmony_ci if (fColor != ce.fColor) { 27cb93a386Sopenharmony_ci pdman.set4fv(fColorUniform, 1, ce.fColor.vec()); 28cb93a386Sopenharmony_ci fColor = ce.fColor; 29cb93a386Sopenharmony_ci } 30cb93a386Sopenharmony_ci 31cb93a386Sopenharmony_ci if (ce.fCoverageScale != 0xff && ce.fCoverageScale != fCoverageScale) { 32cb93a386Sopenharmony_ci pdman.set1f(fCoverageScaleUniform, GrNormalizeByteToFloat(ce.fCoverageScale)); 33cb93a386Sopenharmony_ci fCoverageScale = ce.fCoverageScale; 34cb93a386Sopenharmony_ci } 35cb93a386Sopenharmony_ci } 36cb93a386Sopenharmony_ci 37cb93a386Sopenharmony_ciprivate: 38cb93a386Sopenharmony_ci void onEmitCode(EmitArgs&, GrGPArgs*) override; 39cb93a386Sopenharmony_ci 40cb93a386Sopenharmony_ci SkMatrix fViewMatrix = SkMatrix::InvalidMatrix(); 41cb93a386Sopenharmony_ci SkMatrix fLocalMatrix = SkMatrix::InvalidMatrix(); 42cb93a386Sopenharmony_ci SkPMColor4f fColor = SK_PMColor4fILLEGAL; 43cb93a386Sopenharmony_ci uint8_t fCoverageScale = 0xFF; 44cb93a386Sopenharmony_ci 45cb93a386Sopenharmony_ci UniformHandle fColorUniform; 46cb93a386Sopenharmony_ci UniformHandle fCoverageScaleUniform; 47cb93a386Sopenharmony_ci UniformHandle fViewMatrixUniform; 48cb93a386Sopenharmony_ci UniformHandle fLocalMatrixUniform; 49cb93a386Sopenharmony_ci}; 50cb93a386Sopenharmony_ci 51cb93a386Sopenharmony_civoid GrConicEffect::Impl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { 52cb93a386Sopenharmony_ci GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; 53cb93a386Sopenharmony_ci const GrConicEffect& gp = args.fGeomProc.cast<GrConicEffect>(); 54cb93a386Sopenharmony_ci GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; 55cb93a386Sopenharmony_ci GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; 56cb93a386Sopenharmony_ci 57cb93a386Sopenharmony_ci // emit attributes 58cb93a386Sopenharmony_ci varyingHandler->emitAttributes(gp); 59cb93a386Sopenharmony_ci 60cb93a386Sopenharmony_ci GrGLSLVarying v(kFloat4_GrSLType); 61cb93a386Sopenharmony_ci varyingHandler->addVarying("ConicCoeffs", &v); 62cb93a386Sopenharmony_ci vertBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inConicCoeffs().name()); 63cb93a386Sopenharmony_ci 64cb93a386Sopenharmony_ci GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; 65cb93a386Sopenharmony_ci // Setup pass through color 66cb93a386Sopenharmony_ci fragBuilder->codeAppendf("half4 %s;", args.fOutputColor); 67cb93a386Sopenharmony_ci this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor, &fColorUniform); 68cb93a386Sopenharmony_ci 69cb93a386Sopenharmony_ci // Setup position 70cb93a386Sopenharmony_ci WriteOutputPosition(vertBuilder, 71cb93a386Sopenharmony_ci uniformHandler, 72cb93a386Sopenharmony_ci *args.fShaderCaps, 73cb93a386Sopenharmony_ci gpArgs, 74cb93a386Sopenharmony_ci gp.inPosition().name(), 75cb93a386Sopenharmony_ci gp.fViewMatrix, 76cb93a386Sopenharmony_ci &fViewMatrixUniform); 77cb93a386Sopenharmony_ci if (gp.fUsesLocalCoords) { 78cb93a386Sopenharmony_ci WriteLocalCoord(vertBuilder, 79cb93a386Sopenharmony_ci uniformHandler, 80cb93a386Sopenharmony_ci *args.fShaderCaps, 81cb93a386Sopenharmony_ci gpArgs, 82cb93a386Sopenharmony_ci gp.inPosition().asShaderVar(), 83cb93a386Sopenharmony_ci gp.fLocalMatrix, 84cb93a386Sopenharmony_ci &fLocalMatrixUniform); 85cb93a386Sopenharmony_ci } 86cb93a386Sopenharmony_ci 87cb93a386Sopenharmony_ci // TODO: we should check on the number of bits float and half provide and use the smallest one 88cb93a386Sopenharmony_ci // that suffices. Additionally we should assert that the upstream code only lets us get here if 89cb93a386Sopenharmony_ci // either float or half provides the required number of bits. 90cb93a386Sopenharmony_ci 91cb93a386Sopenharmony_ci GrShaderVar edgeAlpha("edgeAlpha", kHalf_GrSLType, 0); 92cb93a386Sopenharmony_ci GrShaderVar dklmdx("dklmdx", kFloat3_GrSLType, 0); 93cb93a386Sopenharmony_ci GrShaderVar dklmdy("dklmdy", kFloat3_GrSLType, 0); 94cb93a386Sopenharmony_ci GrShaderVar dfdx("dfdx", kFloat_GrSLType, 0); 95cb93a386Sopenharmony_ci GrShaderVar dfdy("dfdy", kFloat_GrSLType, 0); 96cb93a386Sopenharmony_ci GrShaderVar gF("gF", kFloat2_GrSLType, 0); 97cb93a386Sopenharmony_ci GrShaderVar gFM("gFM", kFloat_GrSLType, 0); 98cb93a386Sopenharmony_ci GrShaderVar func("func", kFloat_GrSLType, 0); 99cb93a386Sopenharmony_ci 100cb93a386Sopenharmony_ci fragBuilder->declAppend(edgeAlpha); 101cb93a386Sopenharmony_ci fragBuilder->declAppend(dklmdx); 102cb93a386Sopenharmony_ci fragBuilder->declAppend(dklmdy); 103cb93a386Sopenharmony_ci fragBuilder->declAppend(dfdx); 104cb93a386Sopenharmony_ci fragBuilder->declAppend(dfdy); 105cb93a386Sopenharmony_ci fragBuilder->declAppend(gF); 106cb93a386Sopenharmony_ci fragBuilder->declAppend(gFM); 107cb93a386Sopenharmony_ci fragBuilder->declAppend(func); 108cb93a386Sopenharmony_ci 109cb93a386Sopenharmony_ci fragBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn()); 110cb93a386Sopenharmony_ci fragBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn()); 111cb93a386Sopenharmony_ci fragBuilder->codeAppendf("%s = 2.0 * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;", 112cb93a386Sopenharmony_ci dfdx.c_str(), 113cb93a386Sopenharmony_ci v.fsIn(), dklmdx.c_str(), 114cb93a386Sopenharmony_ci v.fsIn(), dklmdx.c_str(), 115cb93a386Sopenharmony_ci v.fsIn(), dklmdx.c_str()); 116cb93a386Sopenharmony_ci fragBuilder->codeAppendf("%s = 2.0 * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;", 117cb93a386Sopenharmony_ci dfdy.c_str(), 118cb93a386Sopenharmony_ci v.fsIn(), dklmdy.c_str(), 119cb93a386Sopenharmony_ci v.fsIn(), dklmdy.c_str(), 120cb93a386Sopenharmony_ci v.fsIn(), dklmdy.c_str()); 121cb93a386Sopenharmony_ci fragBuilder->codeAppendf("%s = float2(%s, %s);", gF.c_str(), dfdx.c_str(), 122cb93a386Sopenharmony_ci dfdy.c_str()); 123cb93a386Sopenharmony_ci fragBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", 124cb93a386Sopenharmony_ci gFM.c_str(), gF.c_str(), gF.c_str()); 125cb93a386Sopenharmony_ci fragBuilder->codeAppendf("%s = %s.x*%s.x - %s.y*%s.z;", 126cb93a386Sopenharmony_ci func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn()); 127cb93a386Sopenharmony_ci fragBuilder->codeAppendf("%s = abs(%s);", func.c_str(), func.c_str()); 128cb93a386Sopenharmony_ci fragBuilder->codeAppendf("%s = half(%s / %s);", 129cb93a386Sopenharmony_ci edgeAlpha.c_str(), func.c_str(), gFM.c_str()); 130cb93a386Sopenharmony_ci fragBuilder->codeAppendf("%s = max(1.0 - %s, 0.0);", 131cb93a386Sopenharmony_ci edgeAlpha.c_str(), edgeAlpha.c_str()); 132cb93a386Sopenharmony_ci // Add line below for smooth cubic ramp 133cb93a386Sopenharmony_ci // fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);"); 134cb93a386Sopenharmony_ci 135cb93a386Sopenharmony_ci // TODO should we really be doing this? 136cb93a386Sopenharmony_ci if (gp.fCoverageScale != 0xff) { 137cb93a386Sopenharmony_ci const char* coverageScale; 138cb93a386Sopenharmony_ci fCoverageScaleUniform = uniformHandler->addUniform(nullptr, 139cb93a386Sopenharmony_ci kFragment_GrShaderFlag, 140cb93a386Sopenharmony_ci kFloat_GrSLType, 141cb93a386Sopenharmony_ci "Coverage", 142cb93a386Sopenharmony_ci &coverageScale); 143cb93a386Sopenharmony_ci fragBuilder->codeAppendf("half4 %s = half4(half(%s) * %s);", 144cb93a386Sopenharmony_ci args.fOutputCoverage, coverageScale, edgeAlpha.c_str()); 145cb93a386Sopenharmony_ci } else { 146cb93a386Sopenharmony_ci fragBuilder->codeAppendf("half4 %s = half4(%s);", args.fOutputCoverage, edgeAlpha.c_str()); 147cb93a386Sopenharmony_ci } 148cb93a386Sopenharmony_ci} 149cb93a386Sopenharmony_ci 150cb93a386Sopenharmony_ci////////////////////////////////////////////////////////////////////////////// 151cb93a386Sopenharmony_ci 152cb93a386Sopenharmony_ciGrConicEffect::~GrConicEffect() = default; 153cb93a386Sopenharmony_ci 154cb93a386Sopenharmony_ciSkString GrConicEffect::getShaderDfxInfo() const 155cb93a386Sopenharmony_ci{ 156cb93a386Sopenharmony_ci SkString format; 157cb93a386Sopenharmony_ci format.printf("ShaderDfx_GrConicEffect_%d_%d_%d_%d_%d_%d_%d_%d", fCoverageScale, fUsesLocalCoords, 158cb93a386Sopenharmony_ci fViewMatrix.isIdentity(), fViewMatrix.isScaleTranslate(), fViewMatrix.hasPerspective(), 159cb93a386Sopenharmony_ci fLocalMatrix.isIdentity(), fLocalMatrix.isScaleTranslate(), fLocalMatrix.hasPerspective()); 160cb93a386Sopenharmony_ci return format; 161cb93a386Sopenharmony_ci} 162cb93a386Sopenharmony_ci 163cb93a386Sopenharmony_civoid GrConicEffect::addToKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const { 164cb93a386Sopenharmony_ci uint32_t key = 0; 165cb93a386Sopenharmony_ci key |= fCoverageScale == 0xff ? 0x8 : 0x0; 166cb93a386Sopenharmony_ci key |= fUsesLocalCoords ? 0x10 : 0x0; 167cb93a386Sopenharmony_ci key = ProgramImpl::AddMatrixKeys(caps, 168cb93a386Sopenharmony_ci key, 169cb93a386Sopenharmony_ci fViewMatrix, 170cb93a386Sopenharmony_ci fUsesLocalCoords ? fLocalMatrix : SkMatrix::I()); 171cb93a386Sopenharmony_ci b->add32(key); 172cb93a386Sopenharmony_ci} 173cb93a386Sopenharmony_ci 174cb93a386Sopenharmony_cistd::unique_ptr<GrGeometryProcessor::ProgramImpl> GrConicEffect::makeProgramImpl( 175cb93a386Sopenharmony_ci const GrShaderCaps&) const { 176cb93a386Sopenharmony_ci return std::make_unique<Impl>(); 177cb93a386Sopenharmony_ci} 178cb93a386Sopenharmony_ci 179cb93a386Sopenharmony_ciGrConicEffect::GrConicEffect(const SkPMColor4f& color, const SkMatrix& viewMatrix, uint8_t coverage, 180cb93a386Sopenharmony_ci const SkMatrix& localMatrix, bool usesLocalCoords) 181cb93a386Sopenharmony_ci : INHERITED(kGrConicEffect_ClassID) 182cb93a386Sopenharmony_ci , fColor(color) 183cb93a386Sopenharmony_ci , fViewMatrix(viewMatrix) 184cb93a386Sopenharmony_ci , fLocalMatrix(viewMatrix) 185cb93a386Sopenharmony_ci , fUsesLocalCoords(usesLocalCoords) 186cb93a386Sopenharmony_ci , fCoverageScale(coverage) { 187cb93a386Sopenharmony_ci this->setVertexAttributes(kAttributes, SK_ARRAY_COUNT(kAttributes)); 188cb93a386Sopenharmony_ci} 189cb93a386Sopenharmony_ci 190cb93a386Sopenharmony_ci////////////////////////////////////////////////////////////////////////////// 191cb93a386Sopenharmony_ci 192cb93a386Sopenharmony_ciGR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrConicEffect); 193cb93a386Sopenharmony_ci 194cb93a386Sopenharmony_ci#if GR_TEST_UTILS 195cb93a386Sopenharmony_ciGrGeometryProcessor* GrConicEffect::TestCreate(GrProcessorTestData* d) { 196cb93a386Sopenharmony_ci GrColor color = GrTest::RandomColor(d->fRandom); 197cb93a386Sopenharmony_ci SkMatrix viewMatrix = GrTest::TestMatrix(d->fRandom); 198cb93a386Sopenharmony_ci SkMatrix localMatrix = GrTest::TestMatrix(d->fRandom); 199cb93a386Sopenharmony_ci bool usesLocalCoords = d->fRandom->nextBool(); 200cb93a386Sopenharmony_ci return GrConicEffect::Make(d->allocator(), 201cb93a386Sopenharmony_ci SkPMColor4f::FromBytes_RGBA(color), 202cb93a386Sopenharmony_ci viewMatrix, 203cb93a386Sopenharmony_ci *d->caps(), 204cb93a386Sopenharmony_ci localMatrix, 205cb93a386Sopenharmony_ci usesLocalCoords); 206cb93a386Sopenharmony_ci} 207cb93a386Sopenharmony_ci#endif 208cb93a386Sopenharmony_ci 209cb93a386Sopenharmony_ci////////////////////////////////////////////////////////////////////////////// 210cb93a386Sopenharmony_ci// Quad 211cb93a386Sopenharmony_ci////////////////////////////////////////////////////////////////////////////// 212cb93a386Sopenharmony_ci 213cb93a386Sopenharmony_ciclass GrQuadEffect::Impl : public ProgramImpl { 214cb93a386Sopenharmony_cipublic: 215cb93a386Sopenharmony_ci void setData(const GrGLSLProgramDataManager& pdman, 216cb93a386Sopenharmony_ci const GrShaderCaps& shaderCaps, 217cb93a386Sopenharmony_ci const GrGeometryProcessor& geomProc) override { 218cb93a386Sopenharmony_ci const GrQuadEffect& qe = geomProc.cast<GrQuadEffect>(); 219cb93a386Sopenharmony_ci 220cb93a386Sopenharmony_ci SetTransform(pdman, shaderCaps, fViewMatrixUniform, qe.fViewMatrix, &fViewMatrix); 221cb93a386Sopenharmony_ci SetTransform(pdman, shaderCaps, fLocalMatrixUniform, qe.fLocalMatrix, &fLocalMatrix); 222cb93a386Sopenharmony_ci 223cb93a386Sopenharmony_ci if (qe.fColor != fColor) { 224cb93a386Sopenharmony_ci pdman.set4fv(fColorUniform, 1, qe.fColor.vec()); 225cb93a386Sopenharmony_ci fColor = qe.fColor; 226cb93a386Sopenharmony_ci } 227cb93a386Sopenharmony_ci 228cb93a386Sopenharmony_ci if (qe.fCoverageScale != 0xff && qe.fCoverageScale != fCoverageScale) { 229cb93a386Sopenharmony_ci pdman.set1f(fCoverageScaleUniform, GrNormalizeByteToFloat(qe.fCoverageScale)); 230cb93a386Sopenharmony_ci fCoverageScale = qe.fCoverageScale; 231cb93a386Sopenharmony_ci } 232cb93a386Sopenharmony_ci } 233cb93a386Sopenharmony_ci 234cb93a386Sopenharmony_ciprivate: 235cb93a386Sopenharmony_ci void onEmitCode(EmitArgs&, GrGPArgs*) override; 236cb93a386Sopenharmony_ci 237cb93a386Sopenharmony_ci SkMatrix fViewMatrix = SkMatrix::InvalidMatrix(); 238cb93a386Sopenharmony_ci SkMatrix fLocalMatrix = SkMatrix::InvalidMatrix(); 239cb93a386Sopenharmony_ci SkPMColor4f fColor = SK_PMColor4fILLEGAL; 240cb93a386Sopenharmony_ci uint8_t fCoverageScale = 0xFF; 241cb93a386Sopenharmony_ci 242cb93a386Sopenharmony_ci UniformHandle fColorUniform; 243cb93a386Sopenharmony_ci UniformHandle fCoverageScaleUniform; 244cb93a386Sopenharmony_ci UniformHandle fViewMatrixUniform; 245cb93a386Sopenharmony_ci UniformHandle fLocalMatrixUniform; 246cb93a386Sopenharmony_ci}; 247cb93a386Sopenharmony_ci 248cb93a386Sopenharmony_civoid GrQuadEffect::Impl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { 249cb93a386Sopenharmony_ci GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; 250cb93a386Sopenharmony_ci const GrQuadEffect& gp = args.fGeomProc.cast<GrQuadEffect>(); 251cb93a386Sopenharmony_ci GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; 252cb93a386Sopenharmony_ci GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; 253cb93a386Sopenharmony_ci 254cb93a386Sopenharmony_ci // emit attributes 255cb93a386Sopenharmony_ci varyingHandler->emitAttributes(gp); 256cb93a386Sopenharmony_ci 257cb93a386Sopenharmony_ci GrGLSLVarying v(kHalf4_GrSLType); 258cb93a386Sopenharmony_ci varyingHandler->addVarying("HairQuadEdge", &v); 259cb93a386Sopenharmony_ci vertBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inHairQuadEdge().name()); 260cb93a386Sopenharmony_ci 261cb93a386Sopenharmony_ci GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; 262cb93a386Sopenharmony_ci // Setup pass through color 263cb93a386Sopenharmony_ci fragBuilder->codeAppendf("half4 %s;", args.fOutputColor); 264cb93a386Sopenharmony_ci this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor, &fColorUniform); 265cb93a386Sopenharmony_ci 266cb93a386Sopenharmony_ci // Setup position 267cb93a386Sopenharmony_ci WriteOutputPosition(vertBuilder, 268cb93a386Sopenharmony_ci uniformHandler, 269cb93a386Sopenharmony_ci *args.fShaderCaps, 270cb93a386Sopenharmony_ci gpArgs, 271cb93a386Sopenharmony_ci gp.inPosition().name(), 272cb93a386Sopenharmony_ci gp.fViewMatrix, 273cb93a386Sopenharmony_ci &fViewMatrixUniform); 274cb93a386Sopenharmony_ci if (gp.fUsesLocalCoords) { 275cb93a386Sopenharmony_ci WriteLocalCoord(vertBuilder, 276cb93a386Sopenharmony_ci uniformHandler, 277cb93a386Sopenharmony_ci *args.fShaderCaps, 278cb93a386Sopenharmony_ci gpArgs, 279cb93a386Sopenharmony_ci gp.inPosition().asShaderVar(), 280cb93a386Sopenharmony_ci gp.fLocalMatrix, 281cb93a386Sopenharmony_ci &fLocalMatrixUniform); 282cb93a386Sopenharmony_ci } 283cb93a386Sopenharmony_ci 284cb93a386Sopenharmony_ci fragBuilder->codeAppendf("half edgeAlpha;"); 285cb93a386Sopenharmony_ci 286cb93a386Sopenharmony_ci fragBuilder->codeAppendf("half2 duvdx = half2(dFdx(%s.xy));", v.fsIn()); 287cb93a386Sopenharmony_ci fragBuilder->codeAppendf("half2 duvdy = half2(dFdy(%s.xy));", v.fsIn()); 288cb93a386Sopenharmony_ci fragBuilder->codeAppendf("half2 gF = half2(2.0 * %s.x * duvdx.x - duvdx.y," 289cb93a386Sopenharmony_ci " 2.0 * %s.x * duvdy.x - duvdy.y);", 290cb93a386Sopenharmony_ci v.fsIn(), v.fsIn()); 291cb93a386Sopenharmony_ci fragBuilder->codeAppendf("edgeAlpha = half(%s.x * %s.x - %s.y);", 292cb93a386Sopenharmony_ci v.fsIn(), v.fsIn(), v.fsIn()); 293cb93a386Sopenharmony_ci fragBuilder->codeAppend("edgeAlpha = sqrt(edgeAlpha * edgeAlpha / dot(gF, gF));"); 294cb93a386Sopenharmony_ci fragBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);"); 295cb93a386Sopenharmony_ci // Add line below for smooth cubic ramp 296cb93a386Sopenharmony_ci // fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);"); 297cb93a386Sopenharmony_ci 298cb93a386Sopenharmony_ci if (gp.fCoverageScale != 0xFF) { 299cb93a386Sopenharmony_ci const char* coverageScale; 300cb93a386Sopenharmony_ci fCoverageScaleUniform = uniformHandler->addUniform(nullptr, 301cb93a386Sopenharmony_ci kFragment_GrShaderFlag, 302cb93a386Sopenharmony_ci kHalf_GrSLType, 303cb93a386Sopenharmony_ci "Coverage", 304cb93a386Sopenharmony_ci &coverageScale); 305cb93a386Sopenharmony_ci fragBuilder->codeAppendf("half4 %s = half4(%s * edgeAlpha);", args.fOutputCoverage, 306cb93a386Sopenharmony_ci coverageScale); 307cb93a386Sopenharmony_ci } else { 308cb93a386Sopenharmony_ci fragBuilder->codeAppendf("half4 %s = half4(edgeAlpha);", args.fOutputCoverage); 309cb93a386Sopenharmony_ci } 310cb93a386Sopenharmony_ci} 311cb93a386Sopenharmony_ci 312cb93a386Sopenharmony_ci////////////////////////////////////////////////////////////////////////////// 313cb93a386Sopenharmony_ci 314cb93a386Sopenharmony_ciGrQuadEffect::~GrQuadEffect() = default; 315cb93a386Sopenharmony_ci 316cb93a386Sopenharmony_ciSkString GrQuadEffect::getShaderDfxInfo() const 317cb93a386Sopenharmony_ci{ 318cb93a386Sopenharmony_ci SkString format; 319cb93a386Sopenharmony_ci format.printf("ShaderDfx_GrQuadEffect_%d_%d_%d_%d_%d_%d_%d_%d", fCoverageScale, fUsesLocalCoords, 320cb93a386Sopenharmony_ci fViewMatrix.isIdentity(), fViewMatrix.isScaleTranslate(), fViewMatrix.hasPerspective(), 321cb93a386Sopenharmony_ci fLocalMatrix.isIdentity(), fLocalMatrix.isScaleTranslate(), fLocalMatrix.hasPerspective()); 322cb93a386Sopenharmony_ci return format; 323cb93a386Sopenharmony_ci} 324cb93a386Sopenharmony_ci 325cb93a386Sopenharmony_civoid GrQuadEffect::addToKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const { 326cb93a386Sopenharmony_ci uint32_t key = 0; 327cb93a386Sopenharmony_ci key |= fCoverageScale != 0xff ? 0x8 : 0x0; 328cb93a386Sopenharmony_ci key |= fUsesLocalCoords ? 0x10 : 0x0; 329cb93a386Sopenharmony_ci key = ProgramImpl::AddMatrixKeys(caps, 330cb93a386Sopenharmony_ci key, 331cb93a386Sopenharmony_ci fViewMatrix, 332cb93a386Sopenharmony_ci fUsesLocalCoords ? fLocalMatrix : SkMatrix::I()); 333cb93a386Sopenharmony_ci b->add32(key); 334cb93a386Sopenharmony_ci} 335cb93a386Sopenharmony_ci 336cb93a386Sopenharmony_cistd::unique_ptr<GrGeometryProcessor::ProgramImpl> GrQuadEffect::makeProgramImpl( 337cb93a386Sopenharmony_ci const GrShaderCaps&) const { 338cb93a386Sopenharmony_ci return std::make_unique<Impl>(); 339cb93a386Sopenharmony_ci} 340cb93a386Sopenharmony_ci 341cb93a386Sopenharmony_ciGrQuadEffect::GrQuadEffect(const SkPMColor4f& color, const SkMatrix& viewMatrix, uint8_t coverage, 342cb93a386Sopenharmony_ci const SkMatrix& localMatrix, bool usesLocalCoords) 343cb93a386Sopenharmony_ci : INHERITED(kGrQuadEffect_ClassID) 344cb93a386Sopenharmony_ci , fColor(color) 345cb93a386Sopenharmony_ci , fViewMatrix(viewMatrix) 346cb93a386Sopenharmony_ci , fLocalMatrix(localMatrix) 347cb93a386Sopenharmony_ci , fUsesLocalCoords(usesLocalCoords) 348cb93a386Sopenharmony_ci , fCoverageScale(coverage) { 349cb93a386Sopenharmony_ci this->setVertexAttributes(kAttributes, SK_ARRAY_COUNT(kAttributes)); 350cb93a386Sopenharmony_ci} 351cb93a386Sopenharmony_ci 352cb93a386Sopenharmony_ci////////////////////////////////////////////////////////////////////////////// 353cb93a386Sopenharmony_ci 354cb93a386Sopenharmony_ciGR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrQuadEffect); 355cb93a386Sopenharmony_ci 356cb93a386Sopenharmony_ci#if GR_TEST_UTILS 357cb93a386Sopenharmony_ciGrGeometryProcessor* GrQuadEffect::TestCreate(GrProcessorTestData* d) { 358cb93a386Sopenharmony_ci GrColor color = GrTest::RandomColor(d->fRandom); 359cb93a386Sopenharmony_ci SkMatrix viewMatrix = GrTest::TestMatrix(d->fRandom); 360cb93a386Sopenharmony_ci SkMatrix localMatrix = GrTest::TestMatrix(d->fRandom); 361cb93a386Sopenharmony_ci bool usesLocalCoords = d->fRandom->nextBool(); 362cb93a386Sopenharmony_ci return GrQuadEffect::Make(d->allocator(), 363cb93a386Sopenharmony_ci SkPMColor4f::FromBytes_RGBA(color), 364cb93a386Sopenharmony_ci viewMatrix, 365cb93a386Sopenharmony_ci *d->caps(), 366cb93a386Sopenharmony_ci localMatrix, 367cb93a386Sopenharmony_ci usesLocalCoords); 368cb93a386Sopenharmony_ci} 369cb93a386Sopenharmony_ci#endif 370