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