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 "gl/builders/GrGLFullProgramBuilder.h" 11#include "gl/GrGLProcessor.h" 12#include "gl/GrGLSL.h" 13#include "gl/GrGLGeometryProcessor.h" 14#include "GrTBackendProcessorFactory.h" 15 16class GrGLConicEffect : public GrGLGeometryProcessor { 17public: 18 GrGLConicEffect(const GrBackendProcessorFactory&, const GrProcessor&); 19 20 virtual void emitCode(GrGLFullProgramBuilder* builder, 21 const GrGeometryProcessor& geometryProcessor, 22 const GrProcessorKey& key, 23 const char* outputColor, 24 const char* inputColor, 25 const TransformedCoordsArray&, 26 const TextureSamplerArray&) SK_OVERRIDE; 27 28 static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*); 29 30 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {} 31 32private: 33 GrPrimitiveEdgeType fEdgeType; 34 35 typedef GrGLGeometryProcessor INHERITED; 36}; 37 38GrGLConicEffect::GrGLConicEffect(const GrBackendProcessorFactory& factory, 39 const GrProcessor& effect) 40 : INHERITED (factory) { 41 const GrConicEffect& ce = effect.cast<GrConicEffect>(); 42 fEdgeType = ce.getEdgeType(); 43} 44 45void GrGLConicEffect::emitCode(GrGLFullProgramBuilder* builder, 46 const GrGeometryProcessor& geometryProcessor, 47 const GrProcessorKey& key, 48 const char* outputColor, 49 const char* inputColor, 50 const TransformedCoordsArray&, 51 const TextureSamplerArray& samplers) { 52 const char *vsName, *fsName; 53 54 builder->addVarying(kVec4f_GrSLType, "ConicCoeffs", 55 &vsName, &fsName); 56 57 const GrShaderVar& inConicCoeffs = geometryProcessor.cast<GrConicEffect>().inConicCoeffs(); 58 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder(); 59 vsBuilder->codeAppendf("%s = %s;", vsName, inConicCoeffs.c_str()); 60 61 GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 62 fsBuilder->codeAppend("float edgeAlpha;"); 63 64 switch (fEdgeType) { 65 case kHairlineAA_GrProcessorEdgeType: { 66 SkAssertResult(fsBuilder->enableFeature( 67 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); 68 fsBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", fsName); 69 fsBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", fsName); 70 fsBuilder->codeAppendf("float dfdx =" 71 "2.0 * %s.x * dklmdx.x - %s.y * dklmdx.z - %s.z * dklmdx.y;", 72 fsName, fsName, fsName); 73 fsBuilder->codeAppendf("float dfdy =" 74 "2.0 * %s.x * dklmdy.x - %s.y * dklmdy.z - %s.z * dklmdy.y;", 75 fsName, fsName, fsName); 76 fsBuilder->codeAppend("vec2 gF = vec2(dfdx, dfdy);"); 77 fsBuilder->codeAppend("float gFM = sqrt(dot(gF, gF));"); 78 fsBuilder->codeAppendf("float func = %s.x*%s.x - %s.y*%s.z;", fsName, fsName, 79 fsName, fsName); 80 fsBuilder->codeAppend("func = abs(func);"); 81 fsBuilder->codeAppend("edgeAlpha = func / gFM;"); 82 fsBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);"); 83 // Add line below for smooth cubic ramp 84 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);"); 85 break; 86 } 87 case kFillAA_GrProcessorEdgeType: { 88 SkAssertResult(fsBuilder->enableFeature( 89 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); 90 fsBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", fsName); 91 fsBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", fsName); 92 fsBuilder->codeAppendf("float dfdx =" 93 "2.0 * %s.x * dklmdx.x - %s.y * dklmdx.z - %s.z * dklmdx.y;", 94 fsName, fsName, fsName); 95 fsBuilder->codeAppendf("float dfdy =" 96 "2.0 * %s.x * dklmdy.x - %s.y * dklmdy.z - %s.z * dklmdy.y;", 97 fsName, fsName, fsName); 98 fsBuilder->codeAppend("vec2 gF = vec2(dfdx, dfdy);"); 99 fsBuilder->codeAppend("float gFM = sqrt(dot(gF, gF));"); 100 fsBuilder->codeAppendf("float func = %s.x * %s.x - %s.y * %s.z;", fsName, fsName, 101 fsName, fsName); 102 fsBuilder->codeAppend("edgeAlpha = func / gFM;"); 103 fsBuilder->codeAppend("edgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);"); 104 // Add line below for smooth cubic ramp 105 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);"); 106 break; 107 } 108 case kFillBW_GrProcessorEdgeType: { 109 fsBuilder->codeAppendf("edgeAlpha = %s.x * %s.x - %s.y * %s.z;", fsName, fsName, 110 fsName, fsName); 111 fsBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);"); 112 break; 113 } 114 default: 115 SkFAIL("Shouldn't get here"); 116 } 117 118 fsBuilder->codeAppendf("%s = %s;", outputColor, 119 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str()); 120} 121 122void GrGLConicEffect::GenKey(const GrProcessor& processor, const GrGLCaps&, 123 GrProcessorKeyBuilder* b) { 124 const GrConicEffect& ce = processor.cast<GrConicEffect>(); 125 uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2; 126 b->add32(key); 127} 128 129////////////////////////////////////////////////////////////////////////////// 130 131GrConicEffect::~GrConicEffect() {} 132 133const GrBackendGeometryProcessorFactory& GrConicEffect::getFactory() const { 134 return GrTBackendGeometryProcessorFactory<GrConicEffect>::getInstance(); 135} 136 137GrConicEffect::GrConicEffect(GrPrimitiveEdgeType edgeType) 138 : fEdgeType(edgeType) 139 , fInConicCoeffs(this->addVertexAttrib(GrShaderVar("inConicCoeffs", 140 kVec4f_GrSLType, 141 GrShaderVar::kAttribute_TypeModifier))) { 142} 143 144bool GrConicEffect::onIsEqual(const GrProcessor& other) const { 145 const GrConicEffect& ce = other.cast<GrConicEffect>(); 146 return (ce.fEdgeType == fEdgeType); 147} 148 149////////////////////////////////////////////////////////////////////////////// 150 151GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrConicEffect); 152 153GrGeometryProcessor* GrConicEffect::TestCreate(SkRandom* random, 154 GrContext*, 155 const GrDrawTargetCaps& caps, 156 GrTexture*[]) { 157 GrGeometryProcessor* gp; 158 do { 159 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>( 160 random->nextULessThan(kGrProcessorEdgeTypeCnt)); 161 gp = GrConicEffect::Create(edgeType, caps); 162 } while (NULL == gp); 163 return gp; 164} 165 166////////////////////////////////////////////////////////////////////////////// 167// Quad 168////////////////////////////////////////////////////////////////////////////// 169 170class GrGLQuadEffect : public GrGLGeometryProcessor { 171public: 172 GrGLQuadEffect(const GrBackendProcessorFactory&, const GrProcessor&); 173 174 virtual void emitCode(GrGLFullProgramBuilder* builder, 175 const GrGeometryProcessor& geometryProcessor, 176 const GrProcessorKey& key, 177 const char* outputColor, 178 const char* inputColor, 179 const TransformedCoordsArray&, 180 const TextureSamplerArray&) SK_OVERRIDE; 181 182 static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*); 183 184 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {} 185 186private: 187 GrPrimitiveEdgeType fEdgeType; 188 189 typedef GrGLGeometryProcessor INHERITED; 190}; 191 192GrGLQuadEffect::GrGLQuadEffect(const GrBackendProcessorFactory& factory, 193 const GrProcessor& effect) 194 : INHERITED (factory) { 195 const GrQuadEffect& ce = effect.cast<GrQuadEffect>(); 196 fEdgeType = ce.getEdgeType(); 197} 198 199void GrGLQuadEffect::emitCode(GrGLFullProgramBuilder* builder, 200 const GrGeometryProcessor& geometryProcessor, 201 const GrProcessorKey& key, 202 const char* outputColor, 203 const char* inputColor, 204 const TransformedCoordsArray&, 205 const TextureSamplerArray& samplers) { 206 const char *vsName, *fsName; 207 builder->addVarying(kVec4f_GrSLType, "HairQuadEdge", &vsName, &fsName); 208 209 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder(); 210 const GrShaderVar& inHairQuadEdge = geometryProcessor.cast<GrQuadEffect>().inHairQuadEdge(); 211 vsBuilder->codeAppendf("%s = %s;", vsName, inHairQuadEdge.c_str()); 212 213 GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 214 fsBuilder->codeAppendf("float edgeAlpha;"); 215 216 switch (fEdgeType) { 217 case kHairlineAA_GrProcessorEdgeType: { 218 SkAssertResult(fsBuilder->enableFeature( 219 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); 220 fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", fsName); 221 fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", fsName); 222 fsBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y," 223 " 2.0 * %s.x * duvdy.x - duvdy.y);", 224 fsName, fsName); 225 fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", fsName, fsName, fsName); 226 fsBuilder->codeAppend("edgeAlpha = sqrt(edgeAlpha * edgeAlpha / dot(gF, gF));"); 227 fsBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);"); 228 // Add line below for smooth cubic ramp 229 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);"); 230 break; 231 } 232 case kFillAA_GrProcessorEdgeType: { 233 SkAssertResult(fsBuilder->enableFeature( 234 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); 235 fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", fsName); 236 fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", fsName); 237 fsBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y," 238 " 2.0 * %s.x * duvdy.x - duvdy.y);", 239 fsName, fsName); 240 fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", fsName, fsName, fsName); 241 fsBuilder->codeAppend("edgeAlpha = edgeAlpha / sqrt(dot(gF, gF));"); 242 fsBuilder->codeAppend("edgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);"); 243 // Add line below for smooth cubic ramp 244 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);"); 245 break; 246 } 247 case kFillBW_GrProcessorEdgeType: { 248 fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", fsName, fsName, fsName); 249 fsBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);"); 250 break; 251 } 252 default: 253 SkFAIL("Shouldn't get here"); 254 } 255 256 fsBuilder->codeAppendf("%s = %s;", outputColor, 257 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str()); 258} 259 260void GrGLQuadEffect::GenKey(const GrProcessor& processor, const GrGLCaps&, 261 GrProcessorKeyBuilder* b) { 262 const GrQuadEffect& ce = processor.cast<GrQuadEffect>(); 263 uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2; 264 b->add32(key); 265} 266 267////////////////////////////////////////////////////////////////////////////// 268 269GrQuadEffect::~GrQuadEffect() {} 270 271const GrBackendGeometryProcessorFactory& GrQuadEffect::getFactory() const { 272 return GrTBackendGeometryProcessorFactory<GrQuadEffect>::getInstance(); 273} 274 275GrQuadEffect::GrQuadEffect(GrPrimitiveEdgeType edgeType) 276 : fEdgeType(edgeType) 277 , fInHairQuadEdge(this->addVertexAttrib(GrShaderVar("inCubicCoeffs", 278 kVec4f_GrSLType, 279 GrShaderVar::kAttribute_TypeModifier))) { 280} 281 282bool GrQuadEffect::onIsEqual(const GrProcessor& other) const { 283 const GrQuadEffect& ce = other.cast<GrQuadEffect>(); 284 return (ce.fEdgeType == fEdgeType); 285} 286 287////////////////////////////////////////////////////////////////////////////// 288 289GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrQuadEffect); 290 291GrGeometryProcessor* GrQuadEffect::TestCreate(SkRandom* random, 292 GrContext*, 293 const GrDrawTargetCaps& caps, 294 GrTexture*[]) { 295 GrGeometryProcessor* gp; 296 do { 297 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>( 298 random->nextULessThan(kGrProcessorEdgeTypeCnt)); 299 gp = GrQuadEffect::Create(edgeType, caps); 300 } while (NULL == gp); 301 return gp; 302} 303 304////////////////////////////////////////////////////////////////////////////// 305// Cubic 306////////////////////////////////////////////////////////////////////////////// 307 308class GrGLCubicEffect : public GrGLGeometryProcessor { 309public: 310 GrGLCubicEffect(const GrBackendProcessorFactory&, const GrProcessor&); 311 312 virtual void emitCode(GrGLFullProgramBuilder* builder, 313 const GrGeometryProcessor& geometryProcessor, 314 const GrProcessorKey& key, 315 const char* outputColor, 316 const char* inputColor, 317 const TransformedCoordsArray&, 318 const TextureSamplerArray&) SK_OVERRIDE; 319 320 static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*); 321 322 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {} 323 324private: 325 GrPrimitiveEdgeType fEdgeType; 326 327 typedef GrGLGeometryProcessor INHERITED; 328}; 329 330GrGLCubicEffect::GrGLCubicEffect(const GrBackendProcessorFactory& factory, 331 const GrProcessor& processor) 332 : INHERITED (factory) { 333 const GrCubicEffect& ce = processor.cast<GrCubicEffect>(); 334 fEdgeType = ce.getEdgeType(); 335} 336 337void GrGLCubicEffect::emitCode(GrGLFullProgramBuilder* builder, 338 const GrGeometryProcessor& geometryProcessor, 339 const GrProcessorKey& key, 340 const char* outputColor, 341 const char* inputColor, 342 const TransformedCoordsArray&, 343 const TextureSamplerArray& samplers) { 344 const char *vsName, *fsName; 345 346 builder->addVarying(kVec4f_GrSLType, "CubicCoeffs", 347 &vsName, &fsName, GrGLShaderVar::kHigh_Precision); 348 349 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder(); 350 const GrShaderVar& inCubicCoeffs = geometryProcessor.cast<GrCubicEffect>().inCubicCoeffs(); 351 vsBuilder->codeAppendf("%s = %s;", vsName, inCubicCoeffs.c_str()); 352 353 GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 354 355 GrGLShaderVar edgeAlpha("edgeAlpha", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision); 356 GrGLShaderVar dklmdx("dklmdx", kVec3f_GrSLType, 0, GrGLShaderVar::kHigh_Precision); 357 GrGLShaderVar dklmdy("dklmdy", kVec3f_GrSLType, 0, GrGLShaderVar::kHigh_Precision); 358 GrGLShaderVar dfdx("dfdx", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision); 359 GrGLShaderVar dfdy("dfdy", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision); 360 GrGLShaderVar gF("gF", kVec2f_GrSLType, 0, GrGLShaderVar::kHigh_Precision); 361 GrGLShaderVar gFM("gFM", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision); 362 GrGLShaderVar func("func", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision); 363 364 fsBuilder->declAppend(edgeAlpha); 365 fsBuilder->declAppend(dklmdx); 366 fsBuilder->declAppend(dklmdy); 367 fsBuilder->declAppend(dfdx); 368 fsBuilder->declAppend(dfdy); 369 fsBuilder->declAppend(gF); 370 fsBuilder->declAppend(gFM); 371 fsBuilder->declAppend(func); 372 373 switch (fEdgeType) { 374 case kHairlineAA_GrProcessorEdgeType: { 375 SkAssertResult(fsBuilder->enableFeature( 376 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); 377 fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), fsName); 378 fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), fsName); 379 fsBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;", 380 dfdx.c_str(), fsName, fsName, dklmdx.c_str(), fsName, 381 dklmdx.c_str(), fsName, dklmdx.c_str()); 382 fsBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;", 383 dfdy.c_str(), fsName, fsName, dklmdy.c_str(), fsName, 384 dklmdy.c_str(), fsName, dklmdy.c_str()); 385 fsBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str()); 386 fsBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", gFM.c_str(), gF.c_str(), gF.c_str()); 387 fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;", 388 func.c_str(), fsName, fsName, fsName, fsName, fsName); 389 fsBuilder->codeAppendf("%s = abs(%s);", func.c_str(), func.c_str()); 390 fsBuilder->codeAppendf("%s = %s / %s;", 391 edgeAlpha.c_str(), func.c_str(), gFM.c_str()); 392 fsBuilder->codeAppendf("%s = max(1.0 - %s, 0.0);", 393 edgeAlpha.c_str(), edgeAlpha.c_str()); 394 // Add line below for smooth cubic ramp 395 // fsBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);", 396 // edgeAlpha.c_str(), edgeAlpha.c_str(), edgeAlpha.c_str(), 397 // edgeAlpha.c_str()); 398 break; 399 } 400 case kFillAA_GrProcessorEdgeType: { 401 SkAssertResult(fsBuilder->enableFeature( 402 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); 403 fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), fsName); 404 fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), fsName); 405 fsBuilder->codeAppendf("%s =" 406 "3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;", 407 dfdx.c_str(), fsName, fsName, dklmdx.c_str(), fsName, 408 dklmdx.c_str(), fsName, dklmdx.c_str()); 409 fsBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;", 410 dfdy.c_str(), fsName, fsName, dklmdy.c_str(), fsName, 411 dklmdy.c_str(), fsName, dklmdy.c_str()); 412 fsBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str()); 413 fsBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", gFM.c_str(), gF.c_str(), gF.c_str()); 414 fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;", 415 func.c_str(), fsName, fsName, fsName, fsName, fsName); 416 fsBuilder->codeAppendf("%s = %s / %s;", 417 edgeAlpha.c_str(), func.c_str(), gFM.c_str()); 418 fsBuilder->codeAppendf("%s = clamp(1.0 - %s, 0.0, 1.0);", 419 edgeAlpha.c_str(), edgeAlpha.c_str()); 420 // Add line below for smooth cubic ramp 421 // fsBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);", 422 // edgeAlpha.c_str(), edgeAlpha.c_str(), edgeAlpha.c_str(), 423 // edgeAlpha.c_str()); 424 break; 425 } 426 case kFillBW_GrProcessorEdgeType: { 427 fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;", 428 edgeAlpha.c_str(), fsName, fsName, fsName, fsName, fsName); 429 fsBuilder->codeAppendf("%s = float(%s < 0.0);", edgeAlpha.c_str(), edgeAlpha.c_str()); 430 break; 431 } 432 default: 433 SkFAIL("Shouldn't get here"); 434 } 435 436 fsBuilder->codeAppendf("%s = %s;", outputColor, 437 (GrGLSLExpr4(inputColor) * GrGLSLExpr1(edgeAlpha.c_str())).c_str()); 438} 439 440void GrGLCubicEffect::GenKey(const GrProcessor& processor, const GrGLCaps&, 441 GrProcessorKeyBuilder* b) { 442 const GrCubicEffect& ce = processor.cast<GrCubicEffect>(); 443 uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2; 444 b->add32(key); 445} 446 447////////////////////////////////////////////////////////////////////////////// 448 449GrCubicEffect::~GrCubicEffect() {} 450 451const GrBackendGeometryProcessorFactory& GrCubicEffect::getFactory() const { 452 return GrTBackendGeometryProcessorFactory<GrCubicEffect>::getInstance(); 453} 454 455GrCubicEffect::GrCubicEffect(GrPrimitiveEdgeType edgeType) 456 : fEdgeType(edgeType) 457 , fInCubicCoeffs(this->addVertexAttrib(GrShaderVar("inCubicCoeffs", 458 kVec4f_GrSLType, 459 GrShaderVar::kAttribute_TypeModifier))) { 460} 461 462bool GrCubicEffect::onIsEqual(const GrProcessor& other) const { 463 const GrCubicEffect& ce = other.cast<GrCubicEffect>(); 464 return (ce.fEdgeType == fEdgeType); 465} 466 467////////////////////////////////////////////////////////////////////////////// 468 469GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrCubicEffect); 470 471GrGeometryProcessor* GrCubicEffect::TestCreate(SkRandom* random, 472 GrContext*, 473 const GrDrawTargetCaps& caps, 474 GrTexture*[]) { 475 GrGeometryProcessor* gp; 476 do { 477 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>( 478 random->nextULessThan(kGrProcessorEdgeTypeCnt)); 479 gp = GrCubicEffect::Create(edgeType, caps); 480 } while (NULL == gp); 481 return gp; 482} 483 484