LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/gpu/effects - GrBezierEffect.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 353 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 36 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2013 Google Inc.
       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 "GrBezierEffect.h"
       9             : #include "GrShaderCaps.h"
      10             : #include "glsl/GrGLSLFragmentShaderBuilder.h"
      11             : #include "glsl/GrGLSLGeometryProcessor.h"
      12             : #include "glsl/GrGLSLProgramDataManager.h"
      13             : #include "glsl/GrGLSLUniformHandler.h"
      14             : #include "glsl/GrGLSLUtil.h"
      15             : #include "glsl/GrGLSLVarying.h"
      16             : #include "glsl/GrGLSLVertexShaderBuilder.h"
      17             : 
      18           0 : class GrGLConicEffect : public GrGLSLGeometryProcessor {
      19             : public:
      20             :     GrGLConicEffect(const GrGeometryProcessor&);
      21             : 
      22             :     void onEmitCode(EmitArgs&, GrGPArgs*) override;
      23             : 
      24             :     static inline void GenKey(const GrGeometryProcessor&,
      25             :                               const GrShaderCaps&,
      26             :                               GrProcessorKeyBuilder*);
      27             : 
      28           0 :     void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc,
      29             :                  FPCoordTransformIter&& transformIter) override {
      30           0 :         const GrConicEffect& ce = primProc.cast<GrConicEffect>();
      31             : 
      32           0 :         if (!ce.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(ce.viewMatrix())) {
      33           0 :             fViewMatrix = ce.viewMatrix();
      34             :             float viewMatrix[3 * 3];
      35           0 :             GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix);
      36           0 :             pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
      37             :         }
      38             : 
      39           0 :         if (ce.color() != fColor) {
      40             :             float c[4];
      41           0 :             GrColorToRGBAFloat(ce.color(), c);
      42           0 :             pdman.set4fv(fColorUniform, 1, c);
      43           0 :             fColor = ce.color();
      44             :         }
      45             : 
      46           0 :         if (ce.coverageScale() != 0xff && ce.coverageScale() != fCoverageScale) {
      47           0 :             pdman.set1f(fCoverageScaleUniform, GrNormalizeByteToFloat(ce.coverageScale()));
      48           0 :             fCoverageScale = ce.coverageScale();
      49             :         }
      50           0 :         this->setTransformDataHelper(ce.localMatrix(), pdman, &transformIter);
      51           0 :     }
      52             : 
      53             : private:
      54             :     SkMatrix fViewMatrix;
      55             :     GrColor fColor;
      56             :     uint8_t fCoverageScale;
      57             :     GrPrimitiveEdgeType fEdgeType;
      58             :     UniformHandle fColorUniform;
      59             :     UniformHandle fCoverageScaleUniform;
      60             :     UniformHandle fViewMatrixUniform;
      61             : 
      62             :     typedef GrGLSLGeometryProcessor INHERITED;
      63             : };
      64             : 
      65           0 : GrGLConicEffect::GrGLConicEffect(const GrGeometryProcessor& processor)
      66           0 :     : fViewMatrix(SkMatrix::InvalidMatrix()), fColor(GrColor_ILLEGAL), fCoverageScale(0xff) {
      67           0 :     const GrConicEffect& ce = processor.cast<GrConicEffect>();
      68           0 :     fEdgeType = ce.getEdgeType();
      69           0 : }
      70             : 
      71           0 : void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
      72           0 :     GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
      73           0 :     const GrConicEffect& gp = args.fGP.cast<GrConicEffect>();
      74           0 :     GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
      75           0 :     GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
      76             : 
      77             :     // emit attributes
      78           0 :     varyingHandler->emitAttributes(gp);
      79             : 
      80           0 :     GrGLSLVertToFrag v(kVec4f_GrSLType);
      81           0 :     varyingHandler->addVarying("ConicCoeffs", &v, kHigh_GrSLPrecision);
      82           0 :     vertBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inConicCoeffs()->fName);
      83             : 
      84           0 :     GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
      85             :     // Setup pass through color
      86           0 :     this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor, &fColorUniform);
      87             : 
      88             :     // Setup position
      89           0 :     this->setupPosition(vertBuilder,
      90             :                         uniformHandler,
      91             :                         gpArgs,
      92           0 :                         gp.inPosition()->fName,
      93             :                         gp.viewMatrix(),
      94           0 :                         &fViewMatrixUniform);
      95             : 
      96             :     // emit transforms with position
      97           0 :     this->emitTransforms(vertBuilder,
      98             :                          varyingHandler,
      99             :                          uniformHandler,
     100             :                          gpArgs->fPositionVar,
     101           0 :                          gp.inPosition()->fName,
     102             :                          gp.localMatrix(),
     103           0 :                          args.fFPCoordTransformHandler);
     104             : 
     105             :     // TODO: this precision check should actually be a check on the number of bits
     106             :     // high and medium provide and the selection of the lowest level that suffices.
     107             :     // Additionally we should assert that the upstream code only lets us get here if
     108             :     // either high or medium provides the required number of bits.
     109           0 :     GrSLPrecision precision = kHigh_GrSLPrecision;
     110           0 :     const GrShaderCaps::PrecisionInfo& highP = args.fShaderCaps->getFloatShaderPrecisionInfo(
     111             :                                                              kFragment_GrShaderType,
     112           0 :                                                              kHigh_GrSLPrecision);
     113           0 :     if (!highP.supported()) {
     114           0 :         precision = kMedium_GrSLPrecision;
     115             :     }
     116             : 
     117           0 :     GrShaderVar edgeAlpha("edgeAlpha", kFloat_GrSLType, 0, precision);
     118           0 :     GrShaderVar dklmdx("dklmdx", kVec3f_GrSLType, 0, precision);
     119           0 :     GrShaderVar dklmdy("dklmdy", kVec3f_GrSLType, 0, precision);
     120           0 :     GrShaderVar dfdx("dfdx", kFloat_GrSLType, 0, precision);
     121           0 :     GrShaderVar dfdy("dfdy", kFloat_GrSLType, 0, precision);
     122           0 :     GrShaderVar gF("gF", kVec2f_GrSLType, 0, precision);
     123           0 :     GrShaderVar gFM("gFM", kFloat_GrSLType, 0, precision);
     124           0 :     GrShaderVar func("func", kFloat_GrSLType, 0, precision);
     125             : 
     126           0 :     fragBuilder->declAppend(edgeAlpha);
     127           0 :     fragBuilder->declAppend(dklmdx);
     128           0 :     fragBuilder->declAppend(dklmdy);
     129           0 :     fragBuilder->declAppend(dfdx);
     130           0 :     fragBuilder->declAppend(dfdy);
     131           0 :     fragBuilder->declAppend(gF);
     132           0 :     fragBuilder->declAppend(gFM);
     133           0 :     fragBuilder->declAppend(func);
     134             : 
     135           0 :     switch (fEdgeType) {
     136             :         case kHairlineAA_GrProcessorEdgeType: {
     137           0 :             fragBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
     138           0 :             fragBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
     139           0 :             fragBuilder->codeAppendf("%s = 2.0 * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
     140             :                                      dfdx.c_str(),
     141             :                                      v.fsIn(), dklmdx.c_str(),
     142             :                                      v.fsIn(), dklmdx.c_str(),
     143           0 :                                      v.fsIn(), dklmdx.c_str());
     144           0 :             fragBuilder->codeAppendf("%s = 2.0 * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
     145             :                                      dfdy.c_str(),
     146             :                                      v.fsIn(), dklmdy.c_str(),
     147             :                                      v.fsIn(), dklmdy.c_str(),
     148           0 :                                      v.fsIn(), dklmdy.c_str());
     149           0 :             fragBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
     150           0 :             fragBuilder->codeAppendf("%s = sqrt(dot(%s, %s));",
     151           0 :                                      gFM.c_str(), gF.c_str(), gF.c_str());
     152           0 :             fragBuilder->codeAppendf("%s = %s.x*%s.x - %s.y*%s.z;",
     153           0 :                                      func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
     154           0 :             fragBuilder->codeAppendf("%s = abs(%s);", func.c_str(), func.c_str());
     155           0 :             fragBuilder->codeAppendf("%s = %s / %s;",
     156           0 :                                      edgeAlpha.c_str(), func.c_str(), gFM.c_str());
     157           0 :             fragBuilder->codeAppendf("%s = max(1.0 - %s, 0.0);",
     158           0 :                                      edgeAlpha.c_str(), edgeAlpha.c_str());
     159             :             // Add line below for smooth cubic ramp
     160             :             // fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
     161           0 :             break;
     162             :         }
     163             :         case kFillAA_GrProcessorEdgeType: {
     164           0 :             fragBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
     165           0 :             fragBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
     166           0 :             fragBuilder->codeAppendf("%s ="
     167             :                                      "2.0 * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
     168             :                                      dfdx.c_str(),
     169             :                                      v.fsIn(), dklmdx.c_str(),
     170             :                                      v.fsIn(), dklmdx.c_str(),
     171           0 :                                      v.fsIn(), dklmdx.c_str());
     172           0 :             fragBuilder->codeAppendf("%s ="
     173             :                                      "2.0 * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
     174             :                                      dfdy.c_str(),
     175             :                                      v.fsIn(), dklmdy.c_str(),
     176             :                                      v.fsIn(), dklmdy.c_str(),
     177           0 :                                      v.fsIn(), dklmdy.c_str());
     178           0 :             fragBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
     179           0 :             fragBuilder->codeAppendf("%s = sqrt(dot(%s, %s));",
     180           0 :                                      gFM.c_str(), gF.c_str(), gF.c_str());
     181           0 :             fragBuilder->codeAppendf("%s = %s.x * %s.x - %s.y * %s.z;",
     182           0 :                                      func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
     183           0 :             fragBuilder->codeAppendf("%s = %s / %s;",
     184           0 :                                      edgeAlpha.c_str(), func.c_str(), gFM.c_str());
     185           0 :             fragBuilder->codeAppendf("%s = clamp(0.5 - %s, 0.0, 1.0);",
     186           0 :                                      edgeAlpha.c_str(), edgeAlpha.c_str());
     187             :             // Add line below for smooth cubic ramp
     188             :             // fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
     189           0 :             break;
     190             :         }
     191             :         case kFillBW_GrProcessorEdgeType: {
     192           0 :             fragBuilder->codeAppendf("%s = %s.x * %s.x - %s.y * %s.z;",
     193           0 :                                      edgeAlpha.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
     194           0 :             fragBuilder->codeAppendf("%s = float(%s < 0.0);",
     195           0 :                                      edgeAlpha.c_str(), edgeAlpha.c_str());
     196           0 :             break;
     197             :         }
     198             :         default:
     199           0 :             SkFAIL("Shouldn't get here");
     200             :     }
     201             : 
     202             :     // TODO should we really be doing this?
     203           0 :     if (gp.coverageScale() != 0xff) {
     204             :         const char* coverageScale;
     205             :         fCoverageScaleUniform = uniformHandler->addUniform(kFragment_GrShaderFlag,
     206             :                                                            kFloat_GrSLType,
     207             :                                                            kHigh_GrSLPrecision,
     208             :                                                            "Coverage",
     209           0 :                                                            &coverageScale);
     210           0 :         fragBuilder->codeAppendf("%s = vec4(%s * %s);",
     211           0 :                                  args.fOutputCoverage, coverageScale, edgeAlpha.c_str());
     212             :     } else {
     213           0 :         fragBuilder->codeAppendf("%s = vec4(%s);", args.fOutputCoverage, edgeAlpha.c_str());
     214             :     }
     215           0 : }
     216             : 
     217           0 : void GrGLConicEffect::GenKey(const GrGeometryProcessor& gp,
     218             :                              const GrShaderCaps&,
     219             :                              GrProcessorKeyBuilder* b) {
     220           0 :     const GrConicEffect& ce = gp.cast<GrConicEffect>();
     221           0 :     uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
     222           0 :     key |= 0xff != ce.coverageScale() ? 0x8 : 0x0;
     223           0 :     key |= ce.usesLocalCoords() && ce.localMatrix().hasPerspective() ? 0x10 : 0x0;
     224           0 :     key |= ComputePosKey(ce.viewMatrix()) << 5;
     225           0 :     b->add32(key);
     226           0 : }
     227             : 
     228             : //////////////////////////////////////////////////////////////////////////////
     229             : 
     230           0 : GrConicEffect::~GrConicEffect() {}
     231             : 
     232           0 : void GrConicEffect::getGLSLProcessorKey(const GrShaderCaps& caps,
     233             :                                         GrProcessorKeyBuilder* b) const {
     234           0 :     GrGLConicEffect::GenKey(*this, caps, b);
     235           0 : }
     236             : 
     237           0 : GrGLSLPrimitiveProcessor* GrConicEffect::createGLSLInstance(const GrShaderCaps&) const {
     238           0 :     return new GrGLConicEffect(*this);
     239             : }
     240             : 
     241           0 : GrConicEffect::GrConicEffect(GrColor color, const SkMatrix& viewMatrix, uint8_t coverage,
     242             :                              GrPrimitiveEdgeType edgeType, const SkMatrix& localMatrix,
     243           0 :                              bool usesLocalCoords)
     244             :     : fColor(color)
     245             :     , fViewMatrix(viewMatrix)
     246             :     , fLocalMatrix(viewMatrix)
     247             :     , fUsesLocalCoords(usesLocalCoords)
     248             :     , fCoverageScale(coverage)
     249           0 :     , fEdgeType(edgeType) {
     250           0 :     this->initClassID<GrConicEffect>();
     251           0 :     fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType,
     252           0 :                                          kHigh_GrSLPrecision);
     253           0 :     fInConicCoeffs = &this->addVertexAttrib("inConicCoeffs", kVec4f_GrVertexAttribType);
     254           0 : }
     255             : 
     256             : //////////////////////////////////////////////////////////////////////////////
     257             : 
     258             : GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrConicEffect);
     259             : 
     260             : #if GR_TEST_UTILS
     261           0 : sk_sp<GrGeometryProcessor> GrConicEffect::TestCreate(GrProcessorTestData* d) {
     262           0 :     sk_sp<GrGeometryProcessor> gp;
     263           0 :     do {
     264             :         GrPrimitiveEdgeType edgeType =
     265             :                 static_cast<GrPrimitiveEdgeType>(
     266           0 :                         d->fRandom->nextULessThan(kGrProcessorEdgeTypeCnt));
     267           0 :         gp = GrConicEffect::Make(GrRandomColor(d->fRandom), GrTest::TestMatrix(d->fRandom),
     268           0 :                                  edgeType, *d->caps(), GrTest::TestMatrix(d->fRandom),
     269           0 :                                  d->fRandom->nextBool());
     270             :     } while (nullptr == gp);
     271           0 :     return gp;
     272             : }
     273             : #endif
     274             : 
     275             : //////////////////////////////////////////////////////////////////////////////
     276             : // Quad
     277             : //////////////////////////////////////////////////////////////////////////////
     278             : 
     279           0 : class GrGLQuadEffect : public GrGLSLGeometryProcessor {
     280             : public:
     281             :     GrGLQuadEffect(const GrGeometryProcessor&);
     282             : 
     283             :     void onEmitCode(EmitArgs&, GrGPArgs*) override;
     284             : 
     285             :     static inline void GenKey(const GrGeometryProcessor&,
     286             :                               const GrShaderCaps&,
     287             :                               GrProcessorKeyBuilder*);
     288             : 
     289           0 :     void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc,
     290             :                  FPCoordTransformIter&& transformIter) override {
     291           0 :         const GrQuadEffect& qe = primProc.cast<GrQuadEffect>();
     292             : 
     293           0 :         if (!qe.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(qe.viewMatrix())) {
     294           0 :             fViewMatrix = qe.viewMatrix();
     295             :             float viewMatrix[3 * 3];
     296           0 :             GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix);
     297           0 :             pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
     298             :         }
     299             : 
     300           0 :         if (qe.color() != fColor) {
     301             :             float c[4];
     302           0 :             GrColorToRGBAFloat(qe.color(), c);
     303           0 :             pdman.set4fv(fColorUniform, 1, c);
     304           0 :             fColor = qe.color();
     305             :         }
     306             : 
     307           0 :         if (qe.coverageScale() != 0xff && qe.coverageScale() != fCoverageScale) {
     308           0 :             pdman.set1f(fCoverageScaleUniform, GrNormalizeByteToFloat(qe.coverageScale()));
     309           0 :             fCoverageScale = qe.coverageScale();
     310             :         }
     311           0 :         this->setTransformDataHelper(qe.localMatrix(), pdman, &transformIter);
     312           0 :     }
     313             : 
     314             : private:
     315             :     SkMatrix fViewMatrix;
     316             :     GrColor fColor;
     317             :     uint8_t fCoverageScale;
     318             :     GrPrimitiveEdgeType fEdgeType;
     319             :     UniformHandle fColorUniform;
     320             :     UniformHandle fCoverageScaleUniform;
     321             :     UniformHandle fViewMatrixUniform;
     322             : 
     323             :     typedef GrGLSLGeometryProcessor INHERITED;
     324             : };
     325             : 
     326           0 : GrGLQuadEffect::GrGLQuadEffect(const GrGeometryProcessor& processor)
     327           0 :     : fViewMatrix(SkMatrix::InvalidMatrix()), fColor(GrColor_ILLEGAL), fCoverageScale(0xff) {
     328           0 :     const GrQuadEffect& ce = processor.cast<GrQuadEffect>();
     329           0 :     fEdgeType = ce.getEdgeType();
     330           0 : }
     331             : 
     332           0 : void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
     333           0 :     GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
     334           0 :     const GrQuadEffect& gp = args.fGP.cast<GrQuadEffect>();
     335           0 :     GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
     336           0 :     GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
     337             : 
     338             :     // emit attributes
     339           0 :     varyingHandler->emitAttributes(gp);
     340             : 
     341           0 :     GrGLSLVertToFrag v(kVec4f_GrSLType);
     342           0 :     varyingHandler->addVarying("HairQuadEdge", &v);
     343           0 :     vertBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inHairQuadEdge()->fName);
     344             : 
     345           0 :     GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
     346             :     // Setup pass through color
     347           0 :     this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor, &fColorUniform);
     348             : 
     349             :     // Setup position
     350           0 :     this->setupPosition(vertBuilder,
     351             :                         uniformHandler,
     352             :                         gpArgs,
     353           0 :                         gp.inPosition()->fName,
     354             :                         gp.viewMatrix(),
     355           0 :                         &fViewMatrixUniform);
     356             : 
     357             :     // emit transforms with position
     358           0 :     this->emitTransforms(vertBuilder,
     359             :                          varyingHandler,
     360             :                          uniformHandler,
     361             :                          gpArgs->fPositionVar,
     362           0 :                          gp.inPosition()->fName,
     363             :                          gp.localMatrix(),
     364           0 :                          args.fFPCoordTransformHandler);
     365             : 
     366           0 :     fragBuilder->codeAppendf("float edgeAlpha;");
     367             : 
     368           0 :     switch (fEdgeType) {
     369             :         case kHairlineAA_GrProcessorEdgeType: {
     370           0 :             fragBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn());
     371           0 :             fragBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn());
     372           0 :             fragBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
     373             :                                      "               2.0 * %s.x * duvdy.x - duvdy.y);",
     374           0 :                                      v.fsIn(), v.fsIn());
     375           0 :             fragBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);",
     376           0 :                                      v.fsIn(), v.fsIn(), v.fsIn());
     377           0 :             fragBuilder->codeAppend("edgeAlpha = sqrt(edgeAlpha * edgeAlpha / dot(gF, gF));");
     378           0 :             fragBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
     379             :             // Add line below for smooth cubic ramp
     380             :             // fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
     381           0 :             break;
     382             :         }
     383             :         case kFillAA_GrProcessorEdgeType: {
     384           0 :             fragBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn());
     385           0 :             fragBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn());
     386           0 :             fragBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
     387             :                                      "               2.0 * %s.x * duvdy.x - duvdy.y);",
     388           0 :                                      v.fsIn(), v.fsIn());
     389           0 :             fragBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);",
     390           0 :                                      v.fsIn(), v.fsIn(), v.fsIn());
     391           0 :             fragBuilder->codeAppend("edgeAlpha = edgeAlpha / sqrt(dot(gF, gF));");
     392           0 :             fragBuilder->codeAppend("edgeAlpha = clamp(0.5 - edgeAlpha, 0.0, 1.0);");
     393             :             // Add line below for smooth cubic ramp
     394             :             // fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
     395           0 :             break;
     396             :         }
     397             :         case kFillBW_GrProcessorEdgeType: {
     398           0 :             fragBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);",
     399           0 :                                      v.fsIn(), v.fsIn(), v.fsIn());
     400           0 :             fragBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);");
     401           0 :             break;
     402             :         }
     403             :         default:
     404           0 :             SkFAIL("Shouldn't get here");
     405             :     }
     406             : 
     407           0 :     if (0xff != gp.coverageScale()) {
     408             :         const char* coverageScale;
     409             :         fCoverageScaleUniform = uniformHandler->addUniform(kFragment_GrShaderFlag,
     410             :                                                            kFloat_GrSLType,
     411             :                                                            kDefault_GrSLPrecision,
     412             :                                                            "Coverage",
     413           0 :                                                            &coverageScale);
     414           0 :         fragBuilder->codeAppendf("%s = vec4(%s * edgeAlpha);", args.fOutputCoverage, coverageScale);
     415             :     } else {
     416           0 :         fragBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
     417             :     }
     418           0 : }
     419             : 
     420           0 : void GrGLQuadEffect::GenKey(const GrGeometryProcessor& gp,
     421             :                             const GrShaderCaps&,
     422             :                             GrProcessorKeyBuilder* b) {
     423           0 :     const GrQuadEffect& ce = gp.cast<GrQuadEffect>();
     424           0 :     uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
     425           0 :     key |= ce.coverageScale() != 0xff ? 0x8 : 0x0;
     426           0 :     key |= ce.usesLocalCoords() && ce.localMatrix().hasPerspective() ? 0x10 : 0x0;
     427           0 :     key |= ComputePosKey(ce.viewMatrix()) << 5;
     428           0 :     b->add32(key);
     429           0 : }
     430             : 
     431             : //////////////////////////////////////////////////////////////////////////////
     432             : 
     433           0 : GrQuadEffect::~GrQuadEffect() {}
     434             : 
     435           0 : void GrQuadEffect::getGLSLProcessorKey(const GrShaderCaps& caps,
     436             :                                        GrProcessorKeyBuilder* b) const {
     437           0 :     GrGLQuadEffect::GenKey(*this, caps, b);
     438           0 : }
     439             : 
     440           0 : GrGLSLPrimitiveProcessor* GrQuadEffect::createGLSLInstance(const GrShaderCaps&) const {
     441           0 :     return new GrGLQuadEffect(*this);
     442             : }
     443             : 
     444           0 : GrQuadEffect::GrQuadEffect(GrColor color, const SkMatrix& viewMatrix, uint8_t coverage,
     445             :                            GrPrimitiveEdgeType edgeType, const SkMatrix& localMatrix,
     446           0 :                            bool usesLocalCoords)
     447             :     : fColor(color)
     448             :     , fViewMatrix(viewMatrix)
     449             :     , fLocalMatrix(localMatrix)
     450             :     , fUsesLocalCoords(usesLocalCoords)
     451             :     , fCoverageScale(coverage)
     452           0 :     , fEdgeType(edgeType) {
     453           0 :     this->initClassID<GrQuadEffect>();
     454           0 :     fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType,
     455           0 :                                                    kHigh_GrSLPrecision);
     456           0 :     fInHairQuadEdge = &this->addVertexAttrib("inHairQuadEdge", kVec4f_GrVertexAttribType);
     457           0 : }
     458             : 
     459             : //////////////////////////////////////////////////////////////////////////////
     460             : 
     461             : GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrQuadEffect);
     462             : 
     463             : #if GR_TEST_UTILS
     464           0 : sk_sp<GrGeometryProcessor> GrQuadEffect::TestCreate(GrProcessorTestData* d) {
     465           0 :     sk_sp<GrGeometryProcessor> gp;
     466           0 :     do {
     467             :         GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
     468           0 :                 d->fRandom->nextULessThan(kGrProcessorEdgeTypeCnt));
     469           0 :         gp = GrQuadEffect::Make(GrRandomColor(d->fRandom), GrTest::TestMatrix(d->fRandom), edgeType,
     470           0 :                                 *d->caps(), GrTest::TestMatrix(d->fRandom),
     471           0 :                                 d->fRandom->nextBool());
     472             :     } while (nullptr == gp);
     473           0 :     return gp;
     474             : }
     475             : #endif
     476             : 
     477             : //////////////////////////////////////////////////////////////////////////////
     478             : // Cubic
     479             : //////////////////////////////////////////////////////////////////////////////
     480             : 
     481           0 : class GrGLCubicEffect : public GrGLSLGeometryProcessor {
     482             : public:
     483             :     GrGLCubicEffect(const GrGeometryProcessor&);
     484             : 
     485             :     void onEmitCode(EmitArgs&, GrGPArgs*) override;
     486             : 
     487             :     static inline void GenKey(const GrGeometryProcessor&,
     488             :                               const GrShaderCaps&,
     489             :                               GrProcessorKeyBuilder*);
     490             : 
     491           0 :     void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc,
     492             :                  FPCoordTransformIter&& transformIter) override {
     493           0 :         const GrCubicEffect& ce = primProc.cast<GrCubicEffect>();
     494             : 
     495           0 :         if (!ce.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(ce.viewMatrix())) {
     496           0 :             fViewMatrix = ce.viewMatrix();
     497             :             float viewMatrix[3 * 3];
     498           0 :             GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix);
     499           0 :             pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
     500             :         }
     501             : 
     502           0 :         if (ce.color() != fColor) {
     503             :             float c[4];
     504           0 :             GrColorToRGBAFloat(ce.color(), c);
     505           0 :             pdman.set4fv(fColorUniform, 1, c);
     506           0 :             fColor = ce.color();
     507             :         }
     508           0 :         this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
     509           0 :     }
     510             : 
     511             : private:
     512             :     SkMatrix fViewMatrix;
     513             :     GrColor fColor;
     514             :     GrPrimitiveEdgeType fEdgeType;
     515             :     UniformHandle fColorUniform;
     516             :     UniformHandle fViewMatrixUniform;
     517             : 
     518             :     typedef GrGLSLGeometryProcessor INHERITED;
     519             : };
     520             : 
     521           0 : GrGLCubicEffect::GrGLCubicEffect(const GrGeometryProcessor& processor)
     522           0 :     : fViewMatrix(SkMatrix::InvalidMatrix()), fColor(GrColor_ILLEGAL) {
     523           0 :     const GrCubicEffect& ce = processor.cast<GrCubicEffect>();
     524           0 :     fEdgeType = ce.getEdgeType();
     525           0 : }
     526             : 
     527           0 : void GrGLCubicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
     528           0 :     GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
     529           0 :     const GrCubicEffect& gp = args.fGP.cast<GrCubicEffect>();
     530           0 :     GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
     531           0 :     GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
     532             : 
     533             :     // emit attributes
     534           0 :     varyingHandler->emitAttributes(gp);
     535             : 
     536           0 :     GrGLSLVertToFrag v(kVec4f_GrSLType);
     537           0 :     varyingHandler->addVarying("CubicCoeffs", &v, kHigh_GrSLPrecision);
     538           0 :     vertBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inCubicCoeffs()->fName);
     539             : 
     540           0 :     GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
     541             :     // Setup pass through color
     542           0 :     if (!gp.colorIgnored()) {
     543           0 :         this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor, &fColorUniform);
     544             :     }
     545             : 
     546             :     // Setup position
     547           0 :     this->setupPosition(vertBuilder,
     548             :                         uniformHandler,
     549             :                         gpArgs,
     550           0 :                         gp.inPosition()->fName,
     551             :                         gp.viewMatrix(),
     552           0 :                         &fViewMatrixUniform);
     553             : 
     554             :     // emit transforms with position
     555           0 :     this->emitTransforms(vertBuilder,
     556             :                          varyingHandler,
     557             :                          uniformHandler,
     558             :                          gpArgs->fPositionVar,
     559           0 :                          gp.inPosition()->fName,
     560           0 :                          args.fFPCoordTransformHandler);
     561             : 
     562             : 
     563           0 :     GrShaderVar edgeAlpha("edgeAlpha", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
     564           0 :     GrShaderVar dklmdx("dklmdx", kVec3f_GrSLType, 0, kHigh_GrSLPrecision);
     565           0 :     GrShaderVar dklmdy("dklmdy", kVec3f_GrSLType, 0, kHigh_GrSLPrecision);
     566           0 :     GrShaderVar dfdx("dfdx", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
     567           0 :     GrShaderVar dfdy("dfdy", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
     568           0 :     GrShaderVar gF("gF", kVec2f_GrSLType, 0, kHigh_GrSLPrecision);
     569           0 :     GrShaderVar gFM("gFM", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
     570           0 :     GrShaderVar func("func", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
     571             : 
     572           0 :     fragBuilder->declAppend(edgeAlpha);
     573           0 :     fragBuilder->declAppend(dklmdx);
     574           0 :     fragBuilder->declAppend(dklmdy);
     575           0 :     fragBuilder->declAppend(dfdx);
     576           0 :     fragBuilder->declAppend(dfdy);
     577           0 :     fragBuilder->declAppend(gF);
     578           0 :     fragBuilder->declAppend(gFM);
     579           0 :     fragBuilder->declAppend(func);
     580             : 
     581           0 :     switch (fEdgeType) {
     582             :         case kHairlineAA_GrProcessorEdgeType: {
     583           0 :             fragBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
     584           0 :             fragBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
     585           0 :             fragBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
     586             :                                      dfdx.c_str(), v.fsIn(), v.fsIn(), dklmdx.c_str(), v.fsIn(),
     587           0 :                                      dklmdx.c_str(), v.fsIn(), dklmdx.c_str());
     588           0 :             fragBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
     589             :                                      dfdy.c_str(), v.fsIn(), v.fsIn(), dklmdy.c_str(), v.fsIn(),
     590           0 :                                      dklmdy.c_str(), v.fsIn(), dklmdy.c_str());
     591           0 :             fragBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
     592           0 :             fragBuilder->codeAppendf("%s = sqrt(dot(%s, %s));",
     593           0 :                                      gFM.c_str(), gF.c_str(), gF.c_str());
     594           0 :             fragBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
     595             :                                      func.c_str(), v.fsIn(), v.fsIn(),
     596           0 :                                      v.fsIn(), v.fsIn(), v.fsIn());
     597           0 :             fragBuilder->codeAppendf("%s = abs(%s);", func.c_str(), func.c_str());
     598           0 :             fragBuilder->codeAppendf("%s = %s / %s;",
     599           0 :                                      edgeAlpha.c_str(), func.c_str(), gFM.c_str());
     600           0 :             fragBuilder->codeAppendf("%s = max(1.0 - %s, 0.0);",
     601           0 :                                      edgeAlpha.c_str(), edgeAlpha.c_str());
     602             :             // Add line below for smooth cubic ramp
     603             :             // fragBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);",
     604             :             //                        edgeAlpha.c_str(), edgeAlpha.c_str(), edgeAlpha.c_str(),
     605             :             //                        edgeAlpha.c_str());
     606           0 :             break;
     607             :         }
     608             :         case kFillAA_GrProcessorEdgeType: {
     609           0 :             fragBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
     610           0 :             fragBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
     611           0 :             fragBuilder->codeAppendf("%s ="
     612             :                                      "3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
     613             :                                      dfdx.c_str(), v.fsIn(), v.fsIn(), dklmdx.c_str(), v.fsIn(),
     614           0 :                                      dklmdx.c_str(), v.fsIn(), dklmdx.c_str());
     615           0 :             fragBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
     616             :                                      dfdy.c_str(), v.fsIn(), v.fsIn(), dklmdy.c_str(), v.fsIn(),
     617           0 :                                      dklmdy.c_str(), v.fsIn(), dklmdy.c_str());
     618           0 :             fragBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
     619           0 :             fragBuilder->codeAppendf("%s = sqrt(dot(%s, %s));",
     620           0 :                                      gFM.c_str(), gF.c_str(), gF.c_str());
     621           0 :             fragBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
     622             :                                      func.c_str(),
     623           0 :                                      v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
     624           0 :             fragBuilder->codeAppendf("%s = %s / %s;",
     625           0 :                                      edgeAlpha.c_str(), func.c_str(), gFM.c_str());
     626           0 :             fragBuilder->codeAppendf("%s = clamp(0.5 - %s, 0.0, 1.0);",
     627           0 :                                      edgeAlpha.c_str(), edgeAlpha.c_str());
     628             :             // Add line below for smooth cubic ramp
     629             :             // fragBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);",
     630             :             //                        edgeAlpha.c_str(), edgeAlpha.c_str(), edgeAlpha.c_str(),
     631             :             //                        edgeAlpha.c_str());
     632           0 :             break;
     633             :         }
     634             :         case kFillBW_GrProcessorEdgeType: {
     635           0 :             fragBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
     636             :                                      edgeAlpha.c_str(), v.fsIn(), v.fsIn(),
     637           0 :                                      v.fsIn(), v.fsIn(), v.fsIn());
     638           0 :             fragBuilder->codeAppendf("%s = float(%s < 0.0);", edgeAlpha.c_str(), edgeAlpha.c_str());
     639           0 :             break;
     640             :         }
     641             :         default:
     642           0 :             SkFAIL("Shouldn't get here");
     643             :     }
     644             : 
     645             : 
     646           0 :     fragBuilder->codeAppendf("%s = vec4(%s);", args.fOutputCoverage, edgeAlpha.c_str());
     647           0 : }
     648             : 
     649           0 : void GrGLCubicEffect::GenKey(const GrGeometryProcessor& gp,
     650             :                              const GrShaderCaps&,
     651             :                              GrProcessorKeyBuilder* b) {
     652           0 :     const GrCubicEffect& ce = gp.cast<GrCubicEffect>();
     653           0 :     uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
     654           0 :     key |= ComputePosKey(ce.viewMatrix()) << 5;
     655           0 :     b->add32(key);
     656           0 : }
     657             : 
     658             : //////////////////////////////////////////////////////////////////////////////
     659             : 
     660           0 : GrCubicEffect::~GrCubicEffect() {}
     661             : 
     662           0 : void GrCubicEffect::getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
     663           0 :     GrGLCubicEffect::GenKey(*this, caps, b);
     664           0 : }
     665             : 
     666           0 : GrGLSLPrimitiveProcessor* GrCubicEffect::createGLSLInstance(const GrShaderCaps&) const {
     667           0 :     return new GrGLCubicEffect(*this);
     668             : }
     669             : 
     670           0 : GrCubicEffect::GrCubicEffect(GrColor color, const SkMatrix& viewMatrix,
     671           0 :                              GrPrimitiveEdgeType edgeType)
     672             :     : fColor(color)
     673             :     , fViewMatrix(viewMatrix)
     674           0 :     , fEdgeType(edgeType) {
     675           0 :     this->initClassID<GrCubicEffect>();
     676           0 :     fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType,
     677           0 :                                          kHigh_GrSLPrecision);
     678           0 :     fInCubicCoeffs = &this->addVertexAttrib("inCubicCoeffs", kVec4f_GrVertexAttribType);
     679           0 : }
     680             : 
     681             : //////////////////////////////////////////////////////////////////////////////
     682             : 
     683             : GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrCubicEffect);
     684             : 
     685             : #if GR_TEST_UTILS
     686           0 : sk_sp<GrGeometryProcessor> GrCubicEffect::TestCreate(GrProcessorTestData* d) {
     687           0 :     sk_sp<GrGeometryProcessor> gp;
     688           0 :     do {
     689             :         GrPrimitiveEdgeType edgeType =
     690             :                 static_cast<GrPrimitiveEdgeType>(
     691           0 :                         d->fRandom->nextULessThan(kGrProcessorEdgeTypeCnt));
     692           0 :         gp = GrCubicEffect::Make(GrRandomColor(d->fRandom), GrTest::TestMatrix(d->fRandom),
     693           0 :                                  edgeType, *d->caps());
     694             :     } while (nullptr == gp);
     695           0 :     return gp;
     696             : }
     697             : #endif

Generated by: LCOV version 1.13