| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "GrDashingEffect.h" | 8 #include "GrDashingEffect.h" |
| 9 | 9 |
| 10 #include "../GrAARectRenderer.h" | 10 #include "../GrAARectRenderer.h" |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 SkPaint::Cap cap = strokeInfo.getStrokeRec().getCap(); | 58 SkPaint::Cap cap = strokeInfo.getStrokeRec().getCap(); |
| 59 // Current we do don't handle Round or Square cap dashes | 59 // Current we do don't handle Round or Square cap dashes |
| 60 if (SkPaint::kRound_Cap == cap && info.fIntervals[0] != 0.f) { | 60 if (SkPaint::kRound_Cap == cap && info.fIntervals[0] != 0.f) { |
| 61 return false; | 61 return false; |
| 62 } | 62 } |
| 63 | 63 |
| 64 return true; | 64 return true; |
| 65 } | 65 } |
| 66 | 66 |
| 67 namespace { | 67 namespace { |
| 68 | |
| 69 struct DashLineVertex { | 68 struct DashLineVertex { |
| 70 SkPoint fPos; | 69 SkPoint fPos; |
| 71 SkPoint fDashPos; | 70 SkPoint fDashPos; |
| 72 }; | 71 }; |
| 73 | |
| 74 extern const GrVertexAttrib gDashLineVertexAttribs[] = { | |
| 75 { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBind
ing }, | |
| 76 { kVec2f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexA
ttribBinding }, | |
| 77 }; | 72 }; |
| 78 | 73 |
| 79 }; | |
| 80 static void calc_dash_scaling(SkScalar* parallelScale, SkScalar* perpScale, | 74 static void calc_dash_scaling(SkScalar* parallelScale, SkScalar* perpScale, |
| 81 const SkMatrix& viewMatrix, const SkPoint pts[2]) { | 75 const SkMatrix& viewMatrix, const SkPoint pts[2]) { |
| 82 SkVector vecSrc = pts[1] - pts[0]; | 76 SkVector vecSrc = pts[1] - pts[0]; |
| 83 SkScalar magSrc = vecSrc.length(); | 77 SkScalar magSrc = vecSrc.length(); |
| 84 SkScalar invSrc = magSrc ? SkScalarInvert(magSrc) : 0; | 78 SkScalar invSrc = magSrc ? SkScalarInvert(magSrc) : 0; |
| 85 vecSrc.scale(invSrc); | 79 vecSrc.scale(invSrc); |
| 86 | 80 |
| 87 SkVector vecSrcPerp; | 81 SkVector vecSrcPerp; |
| 88 vecSrc.rotateCW(&vecSrcPerp); | 82 vecSrc.rotateCW(&vecSrcPerp); |
| 89 viewMatrix.mapVectors(&vecSrc, 1); | 83 viewMatrix.mapVectors(&vecSrc, 1); |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 lineDone = true; | 328 lineDone = true; |
| 335 | 329 |
| 336 SkPoint devicePts[2]; | 330 SkPoint devicePts[2]; |
| 337 vm.mapPoints(devicePts, ptsRot, 2); | 331 vm.mapPoints(devicePts, ptsRot, 2); |
| 338 SkScalar lineLength = SkPoint::Distance(devicePts[0], devicePts[1]); | 332 SkScalar lineLength = SkPoint::Distance(devicePts[0], devicePts[1]); |
| 339 if (hasCap) { | 333 if (hasCap) { |
| 340 lineLength += 2.f * halfDevStroke; | 334 lineLength += 2.f * halfDevStroke; |
| 341 } | 335 } |
| 342 devIntervals[0] = lineLength; | 336 devIntervals[0] = lineLength; |
| 343 } | 337 } |
| 338 |
| 339 const GrGeometryProcessor* gp; |
| 344 bool fullDash = devIntervals[1] > 0.f || useAA; | 340 bool fullDash = devIntervals[1] > 0.f || useAA; |
| 345 if (fullDash) { | 341 if (fullDash) { |
| 346 SkPathEffect::DashInfo devInfo; | 342 SkPathEffect::DashInfo devInfo; |
| 347 devInfo.fPhase = devPhase; | 343 devInfo.fPhase = devPhase; |
| 348 devInfo.fCount = 2; | 344 devInfo.fCount = 2; |
| 349 devInfo.fIntervals = devIntervals; | 345 devInfo.fIntervals = devIntervals; |
| 350 GrPrimitiveEdgeType edgeType= useAA ? kFillAA_GrProcessorEdgeType : | 346 GrPrimitiveEdgeType edgeType= useAA ? kFillAA_GrProcessorEdgeType : |
| 351 kFillBW_GrProcessorEdgeType; | 347 kFillBW_GrProcessorEdgeType; |
| 352 bool isRoundCap = SkPaint::kRound_Cap == cap; | 348 bool isRoundCap = SkPaint::kRound_Cap == cap; |
| 353 GrDashingEffect::DashCap capType = isRoundCap ? GrDashingEffect::kRound_
DashCap : | 349 GrDashingEffect::DashCap capType = isRoundCap ? GrDashingEffect::kRound_
DashCap : |
| 354 GrDashingEffect::kNonRou
nd_DashCap; | 350 GrDashingEffect::kNonRou
nd_DashCap; |
| 355 drawState->setGeometryProcessor( | 351 gp = GrDashingEffect::Create(edgeType, devInfo, strokeWidth, capType); |
| 356 GrDashingEffect::Create(edgeType, devInfo, strokeWidth, capType)
)->unref(); | |
| 357 | |
| 358 // Set up the vertex data for the line and start/end dashes | |
| 359 drawState->setVertexAttribs<gDashLineVertexAttribs>(SK_ARRAY_COUNT(gDash
LineVertexAttribs), | |
| 360 sizeof(DashLineVerte
x)); | |
| 361 } else { | 352 } else { |
| 362 // Set up the vertex data for the line and start/end dashes | 353 // Set up the vertex data for the line and start/end dashes |
| 363 drawState->setGeometryProcessor( | 354 gp = GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPosition_
GPType); |
| 364 GrDefaultGeoProcFactory::CreateAndSetAttribs( | |
| 365 drawState, | |
| 366 GrDefaultGeoProcFactory::kPosition_GPType))->unref(); | |
| 367 } | 355 } |
| 368 | 356 |
| 357 drawState->setGeometryProcessor(gp)->unref(); |
| 358 |
| 369 int totalRectCnt = 0; | 359 int totalRectCnt = 0; |
| 370 | 360 |
| 371 totalRectCnt += !lineDone ? 1 : 0; | 361 totalRectCnt += !lineDone ? 1 : 0; |
| 372 totalRectCnt += hasStartRect ? 1 : 0; | 362 totalRectCnt += hasStartRect ? 1 : 0; |
| 373 totalRectCnt += hasEndRect ? 1 : 0; | 363 totalRectCnt += hasEndRect ? 1 : 0; |
| 374 | 364 |
| 375 GrDrawTarget::AutoReleaseGeometry geo(target, | 365 GrDrawTarget::AutoReleaseGeometry geo(target, |
| 376 totalRectCnt * 4, | 366 totalRectCnt * 4, |
| 377 drawState->getVertexStride(), 0); | 367 gp->getVertexStride(), 0); |
| 378 if (!geo.succeeded()) { | 368 if (!geo.succeeded()) { |
| 379 SkDebugf("Failed to get space for vertices!\n"); | 369 SkDebugf("Failed to get space for vertices!\n"); |
| 380 return false; | 370 return false; |
| 381 } | 371 } |
| 382 | 372 |
| 383 int curVIdx = 0; | 373 int curVIdx = 0; |
| 384 | 374 |
| 385 if (SkPaint::kRound_Cap == cap && 0 != srcStrokeWidth) { | 375 if (SkPaint::kRound_Cap == cap && 0 != srcStrokeWidth) { |
| 386 // need to adjust this for round caps to correctly set the dashPos attri
b on vertices | 376 // need to adjust this for round caps to correctly set the dashPos attri
b on vertices |
| 387 startOffset -= halfDevStroke; | 377 startOffset -= halfDevStroke; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 typedef SkPathEffect::DashInfo DashInfo; | 452 typedef SkPathEffect::DashInfo DashInfo; |
| 463 | 453 |
| 464 static GrGeometryProcessor* Create(GrPrimitiveEdgeType edgeType, | 454 static GrGeometryProcessor* Create(GrPrimitiveEdgeType edgeType, |
| 465 const DashInfo& info, | 455 const DashInfo& info, |
| 466 SkScalar radius); | 456 SkScalar radius); |
| 467 | 457 |
| 468 virtual ~DashingCircleEffect(); | 458 virtual ~DashingCircleEffect(); |
| 469 | 459 |
| 470 static const char* Name() { return "DashingCircleEffect"; } | 460 static const char* Name() { return "DashingCircleEffect"; } |
| 471 | 461 |
| 472 const GrShaderVar& inCoord() const { return fInCoord; } | 462 const GrAttribute* inPosition() const { return fInPosition; } |
| 463 |
| 464 const GrAttribute* inCoord() const { return fInCoord; } |
| 473 | 465 |
| 474 GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; } | 466 GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; } |
| 475 | 467 |
| 476 SkScalar getRadius() const { return fRadius; } | 468 SkScalar getRadius() const { return fRadius; } |
| 477 | 469 |
| 478 SkScalar getCenterX() const { return fCenterX; } | 470 SkScalar getCenterX() const { return fCenterX; } |
| 479 | 471 |
| 480 SkScalar getIntervalLength() const { return fIntervalLength; } | 472 SkScalar getIntervalLength() const { return fIntervalLength; } |
| 481 | 473 |
| 482 typedef GLDashingCircleEffect GLProcessor; | 474 typedef GLDashingCircleEffect GLProcessor; |
| 483 | 475 |
| 484 virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERR
IDE; | 476 virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERR
IDE; |
| 485 | 477 |
| 486 private: | 478 private: |
| 487 DashingCircleEffect(GrPrimitiveEdgeType edgeType, const DashInfo& info, SkSc
alar radius); | 479 DashingCircleEffect(GrPrimitiveEdgeType edgeType, const DashInfo& info, SkSc
alar radius); |
| 488 | 480 |
| 489 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE; | 481 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE; |
| 490 | 482 |
| 491 virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVE
RRIDE; | 483 virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVE
RRIDE; |
| 492 | 484 |
| 493 GrPrimitiveEdgeType fEdgeType; | 485 GrPrimitiveEdgeType fEdgeType; |
| 494 const GrShaderVar& fInCoord; | 486 const GrAttribute* fInPosition; |
| 487 const GrAttribute* fInCoord; |
| 495 SkScalar fIntervalLength; | 488 SkScalar fIntervalLength; |
| 496 SkScalar fRadius; | 489 SkScalar fRadius; |
| 497 SkScalar fCenterX; | 490 SkScalar fCenterX; |
| 498 | 491 |
| 499 GR_DECLARE_GEOMETRY_PROCESSOR_TEST; | 492 GR_DECLARE_GEOMETRY_PROCESSOR_TEST; |
| 500 | 493 |
| 501 typedef GrGeometryProcessor INHERITED; | 494 typedef GrGeometryProcessor INHERITED; |
| 502 }; | 495 }; |
| 503 | 496 |
| 504 ////////////////////////////////////////////////////////////////////////////// | 497 ////////////////////////////////////////////////////////////////////////////// |
| (...skipping 27 matching lines...) Expand all Loading... |
| 532 void GLDashingCircleEffect::emitCode(const EmitArgs& args) { | 525 void GLDashingCircleEffect::emitCode(const EmitArgs& args) { |
| 533 const DashingCircleEffect& dce = args.fGP.cast<DashingCircleEffect>(); | 526 const DashingCircleEffect& dce = args.fGP.cast<DashingCircleEffect>(); |
| 534 const char *paramName; | 527 const char *paramName; |
| 535 // The param uniforms, xyz, refer to circle radius - 0.5, cicles center x co
ord, and | 528 // The param uniforms, xyz, refer to circle radius - 0.5, cicles center x co
ord, and |
| 536 // the total interval length of the dash. | 529 // the total interval length of the dash. |
| 537 fParamUniform = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibilit
y, | 530 fParamUniform = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibilit
y, |
| 538 kVec3f_GrSLType, | 531 kVec3f_GrSLType, |
| 539 "params", | 532 "params", |
| 540 ¶mName); | 533 ¶mName); |
| 541 | 534 |
| 535 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); |
| 536 |
| 542 GrGLVertToFrag v(kVec2f_GrSLType); | 537 GrGLVertToFrag v(kVec2f_GrSLType); |
| 543 args.fPB->addVarying("Coord", &v); | 538 args.fPB->addVarying("Coord", &v); |
| 539 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dce.inCoord()->fName); |
| 544 | 540 |
| 545 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); | 541 // setup coord outputs |
| 546 vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), dce.inCoord().c_str()); | 542 vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), dce.inPositi
on()->fName); |
| 543 vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), dce.inPosition(
)->fName); |
| 547 | 544 |
| 548 // setup position varying | 545 // setup position varying |
| 549 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vs
Builder->uViewM(), | 546 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vs
Builder->uViewM(), |
| 550 vsBuilder->inPosition()); | 547 dce.inPosition()->fName); |
| 551 | 548 |
| 552 // transforms all points so that we can compare them to our test circle | 549 // transforms all points so that we can compare them to our test circle |
| 553 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); | 550 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); |
| 554 fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s.z) * %s.
z;\n", | 551 fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s.z) * %s.
z;\n", |
| 555 v.fsIn(), v.fsIn(), paramName, paramName); | 552 v.fsIn(), v.fsIn(), paramName, paramName); |
| 556 fsBuilder->codeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n",
v.fsIn()); | 553 fsBuilder->codeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n",
v.fsIn()); |
| 557 fsBuilder->codeAppendf("\t\tvec2 center = vec2(%s.y, 0.0);\n", paramName); | 554 fsBuilder->codeAppendf("\t\tvec2 center = vec2(%s.y, 0.0);\n", paramName); |
| 558 fsBuilder->codeAppend("\t\tfloat dist = length(center - fragPosShifted);\n")
; | 555 fsBuilder->codeAppend("\t\tfloat dist = length(center - fragPosShifted);\n")
; |
| 559 if (GrProcessorEdgeTypeIsAA(dce.getEdgeType())) { | 556 if (GrProcessorEdgeTypeIsAA(dce.getEdgeType())) { |
| 560 fsBuilder->codeAppendf("\t\tfloat diff = dist - %s.x;\n", paramName); | 557 fsBuilder->codeAppendf("\t\tfloat diff = dist - %s.x;\n", paramName); |
| 561 fsBuilder->codeAppend("\t\tdiff = 1.0 - diff;\n"); | 558 fsBuilder->codeAppend("\t\tdiff = 1.0 - diff;\n"); |
| 562 fsBuilder->codeAppend("\t\tfloat alpha = clamp(diff, 0.0, 1.0);\n"); | 559 fsBuilder->codeAppend("\t\tfloat alpha = clamp(diff, 0.0, 1.0);\n"); |
| 563 } else { | 560 } else { |
| 564 fsBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n"); | 561 fsBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n"); |
| 565 fsBuilder->codeAppendf("\t\talpha *= dist < %s.x + 0.5 ? 1.0 : 0.0;\n",
paramName); | 562 fsBuilder->codeAppendf("\t\talpha *= dist < %s.x + 0.5 ? 1.0 : 0.0;\n",
paramName); |
| 566 } | 563 } |
| 567 fsBuilder->codeAppendf("\t\t%s = %s;\n", args.fOutput, | 564 fsBuilder->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage); |
| 568 (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("alpha")).c_s
tr()); | |
| 569 } | 565 } |
| 570 | 566 |
| 571 void GLDashingCircleEffect::setData(const GrGLProgramDataManager& pdman | 567 void GLDashingCircleEffect::setData(const GrGLProgramDataManager& pdman |
| 572 , const GrProcessor& processor) { | 568 , const GrProcessor& processor) { |
| 573 const DashingCircleEffect& dce = processor.cast<DashingCircleEffect>(); | 569 const DashingCircleEffect& dce = processor.cast<DashingCircleEffect>(); |
| 574 SkScalar radius = dce.getRadius(); | 570 SkScalar radius = dce.getRadius(); |
| 575 SkScalar centerX = dce.getCenterX(); | 571 SkScalar centerX = dce.getCenterX(); |
| 576 SkScalar intervalLength = dce.getIntervalLength(); | 572 SkScalar intervalLength = dce.getIntervalLength(); |
| 577 if (radius != fPrevRadius || centerX != fPrevCenterX || intervalLength != fP
revIntervalLength) { | 573 if (radius != fPrevRadius || centerX != fPrevCenterX || intervalLength != fP
revIntervalLength) { |
| 578 pdman.set3f(fParamUniform, radius - 0.5f, centerX, intervalLength); | 574 pdman.set3f(fParamUniform, radius - 0.5f, centerX, intervalLength); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 604 void DashingCircleEffect::onComputeInvariantOutput(GrInvariantOutput* inout) con
st { | 600 void DashingCircleEffect::onComputeInvariantOutput(GrInvariantOutput* inout) con
st { |
| 605 inout->mulByUnknownAlpha(); | 601 inout->mulByUnknownAlpha(); |
| 606 } | 602 } |
| 607 | 603 |
| 608 const GrBackendGeometryProcessorFactory& DashingCircleEffect::getFactory() const
{ | 604 const GrBackendGeometryProcessorFactory& DashingCircleEffect::getFactory() const
{ |
| 609 return GrTBackendGeometryProcessorFactory<DashingCircleEffect>::getInstance(
); | 605 return GrTBackendGeometryProcessorFactory<DashingCircleEffect>::getInstance(
); |
| 610 } | 606 } |
| 611 | 607 |
| 612 DashingCircleEffect::DashingCircleEffect(GrPrimitiveEdgeType edgeType, const Das
hInfo& info, | 608 DashingCircleEffect::DashingCircleEffect(GrPrimitiveEdgeType edgeType, const Das
hInfo& info, |
| 613 SkScalar radius) | 609 SkScalar radius) |
| 614 : fEdgeType(edgeType) | 610 : fEdgeType(edgeType) { |
| 615 , fInCoord(this->addVertexAttrib(GrShaderVar("inCoord", | 611 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVert
exAttribType)); |
| 616 kVec2f_GrSLType, | 612 fInCoord = &this->addVertexAttrib(GrAttribute("inCoord", kVec2f_GrVertexAttr
ibType)); |
| 617 GrShaderVar::kAttribute_TypeMod
ifier))) { | |
| 618 SkScalar onLen = info.fIntervals[0]; | 613 SkScalar onLen = info.fIntervals[0]; |
| 619 SkScalar offLen = info.fIntervals[1]; | 614 SkScalar offLen = info.fIntervals[1]; |
| 620 fIntervalLength = onLen + offLen; | 615 fIntervalLength = onLen + offLen; |
| 621 fRadius = radius; | 616 fRadius = radius; |
| 622 fCenterX = SkScalarHalf(offLen); | 617 fCenterX = SkScalarHalf(offLen); |
| 623 } | 618 } |
| 624 | 619 |
| 625 bool DashingCircleEffect::onIsEqual(const GrGeometryProcessor& other) const { | 620 bool DashingCircleEffect::onIsEqual(const GrGeometryProcessor& other) const { |
| 626 const DashingCircleEffect& dce = other.cast<DashingCircleEffect>(); | 621 const DashingCircleEffect& dce = other.cast<DashingCircleEffect>(); |
| 627 return (fEdgeType == dce.fEdgeType && | 622 return (fEdgeType == dce.fEdgeType && |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 668 typedef SkPathEffect::DashInfo DashInfo; | 663 typedef SkPathEffect::DashInfo DashInfo; |
| 669 | 664 |
| 670 static GrGeometryProcessor* Create(GrPrimitiveEdgeType edgeType, | 665 static GrGeometryProcessor* Create(GrPrimitiveEdgeType edgeType, |
| 671 const DashInfo& info, | 666 const DashInfo& info, |
| 672 SkScalar strokeWidth); | 667 SkScalar strokeWidth); |
| 673 | 668 |
| 674 virtual ~DashingLineEffect(); | 669 virtual ~DashingLineEffect(); |
| 675 | 670 |
| 676 static const char* Name() { return "DashingEffect"; } | 671 static const char* Name() { return "DashingEffect"; } |
| 677 | 672 |
| 678 const GrShaderVar& inCoord() const { return fInCoord; } | 673 const GrAttribute* inPosition() const { return fInPosition; } |
| 674 |
| 675 const GrAttribute* inCoord() const { return fInCoord; } |
| 679 | 676 |
| 680 GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; } | 677 GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; } |
| 681 | 678 |
| 682 const SkRect& getRect() const { return fRect; } | 679 const SkRect& getRect() const { return fRect; } |
| 683 | 680 |
| 684 SkScalar getIntervalLength() const { return fIntervalLength; } | 681 SkScalar getIntervalLength() const { return fIntervalLength; } |
| 685 | 682 |
| 686 typedef GLDashingLineEffect GLProcessor; | 683 typedef GLDashingLineEffect GLProcessor; |
| 687 | 684 |
| 688 virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERR
IDE; | 685 virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERR
IDE; |
| 689 | 686 |
| 690 private: | 687 private: |
| 691 DashingLineEffect(GrPrimitiveEdgeType edgeType, const DashInfo& info, SkScal
ar strokeWidth); | 688 DashingLineEffect(GrPrimitiveEdgeType edgeType, const DashInfo& info, SkScal
ar strokeWidth); |
| 692 | 689 |
| 693 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE; | 690 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE; |
| 694 | 691 |
| 695 virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVE
RRIDE; | 692 virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVE
RRIDE; |
| 696 | 693 |
| 697 GrPrimitiveEdgeType fEdgeType; | 694 GrPrimitiveEdgeType fEdgeType; |
| 698 const GrShaderVar& fInCoord; | 695 const GrAttribute* fInPosition; |
| 696 const GrAttribute* fInCoord; |
| 699 SkRect fRect; | 697 SkRect fRect; |
| 700 SkScalar fIntervalLength; | 698 SkScalar fIntervalLength; |
| 701 | 699 |
| 702 GR_DECLARE_GEOMETRY_PROCESSOR_TEST; | 700 GR_DECLARE_GEOMETRY_PROCESSOR_TEST; |
| 703 | 701 |
| 704 typedef GrGeometryProcessor INHERITED; | 702 typedef GrGeometryProcessor INHERITED; |
| 705 }; | 703 }; |
| 706 | 704 |
| 707 ////////////////////////////////////////////////////////////////////////////// | 705 ////////////////////////////////////////////////////////////////////////////// |
| 708 | 706 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 740 kVec4f_GrSLType, | 738 kVec4f_GrSLType, |
| 741 "rect", | 739 "rect", |
| 742 &rectName); | 740 &rectName); |
| 743 const char *intervalName; | 741 const char *intervalName; |
| 744 // The interval uniform's refers to the total length of the interval (on + o
ff) | 742 // The interval uniform's refers to the total length of the interval (on + o
ff) |
| 745 fIntervalUniform = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, | 743 fIntervalUniform = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, |
| 746 kFloat_GrSLType, | 744 kFloat_GrSLType, |
| 747 "interval", | 745 "interval", |
| 748 &intervalName); | 746 &intervalName); |
| 749 | 747 |
| 748 |
| 749 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); |
| 750 |
| 750 GrGLVertToFrag v(kVec2f_GrSLType); | 751 GrGLVertToFrag v(kVec2f_GrSLType); |
| 751 args.fPB->addVarying("Coord", &v); | 752 args.fPB->addVarying("Coord", &v); |
| 752 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); | 753 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), de.inCoord()->fName); |
| 753 vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), de.inCoord().c_str()); | 754 |
| 755 // setup coord outputs |
| 756 vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), de.inPositio
n()->fName); |
| 757 vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), de.inPosition()
->fName); |
| 754 | 758 |
| 755 // setup position varying | 759 // setup position varying |
| 756 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vs
Builder->uViewM(), | 760 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vs
Builder->uViewM(), |
| 757 vsBuilder->inPosition()); | 761 de.inPosition()->fName); |
| 758 | 762 |
| 759 // transforms all points so that we can compare them to our test rect | 763 // transforms all points so that we can compare them to our test rect |
| 760 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); | 764 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); |
| 761 fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s) * %s;\n
", | 765 fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s) * %s;\n
", |
| 762 v.fsIn(), v.fsIn(), intervalName, intervalName); | 766 v.fsIn(), v.fsIn(), intervalName, intervalName); |
| 763 fsBuilder->codeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n",
v.fsIn()); | 767 fsBuilder->codeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n",
v.fsIn()); |
| 764 if (GrProcessorEdgeTypeIsAA(de.getEdgeType())) { | 768 if (GrProcessorEdgeTypeIsAA(de.getEdgeType())) { |
| 765 // The amount of coverage removed in x and y by the edges is computed as
a pair of negative | 769 // The amount of coverage removed in x and y by the edges is computed as
a pair of negative |
| 766 // numbers, xSub and ySub. | 770 // numbers, xSub and ySub. |
| 767 fsBuilder->codeAppend("\t\tfloat xSub, ySub;\n"); | 771 fsBuilder->codeAppend("\t\tfloat xSub, ySub;\n"); |
| 768 fsBuilder->codeAppendf("\t\txSub = min(fragPosShifted.x - %s.x, 0.0);\n"
, rectName); | 772 fsBuilder->codeAppendf("\t\txSub = min(fragPosShifted.x - %s.x, 0.0);\n"
, rectName); |
| 769 fsBuilder->codeAppendf("\t\txSub += min(%s.z - fragPosShifted.x, 0.0);\n
", rectName); | 773 fsBuilder->codeAppendf("\t\txSub += min(%s.z - fragPosShifted.x, 0.0);\n
", rectName); |
| 770 fsBuilder->codeAppendf("\t\tySub = min(fragPosShifted.y - %s.y, 0.0);\n"
, rectName); | 774 fsBuilder->codeAppendf("\t\tySub = min(fragPosShifted.y - %s.y, 0.0);\n"
, rectName); |
| 771 fsBuilder->codeAppendf("\t\tySub += min(%s.w - fragPosShifted.y, 0.0);\n
", rectName); | 775 fsBuilder->codeAppendf("\t\tySub += min(%s.w - fragPosShifted.y, 0.0);\n
", rectName); |
| 772 // Now compute coverage in x and y and multiply them to get the fraction
of the pixel | 776 // Now compute coverage in x and y and multiply them to get the fraction
of the pixel |
| 773 // covered. | 777 // covered. |
| 774 fsBuilder->codeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0
+ max(ySub, -1.0));\n"); | 778 fsBuilder->codeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0
+ max(ySub, -1.0));\n"); |
| 775 } else { | 779 } else { |
| 776 // Assuming the bounding geometry is tight so no need to check y values | 780 // Assuming the bounding geometry is tight so no need to check y values |
| 777 fsBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n"); | 781 fsBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n"); |
| 778 fsBuilder->codeAppendf("\t\talpha *= (fragPosShifted.x - %s.x) > -0.5 ?
1.0 : 0.0;\n", rectName); | 782 fsBuilder->codeAppendf("\t\talpha *= (fragPosShifted.x - %s.x) > -0.5 ?
1.0 : 0.0;\n", rectName); |
| 779 fsBuilder->codeAppendf("\t\talpha *= (%s.z - fragPosShifted.x) >= -0.5 ?
1.0 : 0.0;\n", rectName); | 783 fsBuilder->codeAppendf("\t\talpha *= (%s.z - fragPosShifted.x) >= -0.5 ?
1.0 : 0.0;\n", rectName); |
| 780 } | 784 } |
| 781 fsBuilder->codeAppendf("\t\t%s = %s;\n", args.fOutput, | 785 fsBuilder->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage); |
| 782 (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("alpha")).c_s
tr()); | |
| 783 } | 786 } |
| 784 | 787 |
| 785 void GLDashingLineEffect::setData(const GrGLProgramDataManager& pdman, | 788 void GLDashingLineEffect::setData(const GrGLProgramDataManager& pdman, |
| 786 const GrProcessor& processor) { | 789 const GrProcessor& processor) { |
| 787 const DashingLineEffect& de = processor.cast<DashingLineEffect>(); | 790 const DashingLineEffect& de = processor.cast<DashingLineEffect>(); |
| 788 const SkRect& rect = de.getRect(); | 791 const SkRect& rect = de.getRect(); |
| 789 SkScalar intervalLength = de.getIntervalLength(); | 792 SkScalar intervalLength = de.getIntervalLength(); |
| 790 if (rect != fPrevRect || intervalLength != fPrevIntervalLength) { | 793 if (rect != fPrevRect || intervalLength != fPrevIntervalLength) { |
| 791 pdman.set4f(fRectUniform, rect.fLeft + 0.5f, rect.fTop + 0.5f, | 794 pdman.set4f(fRectUniform, rect.fLeft + 0.5f, rect.fTop + 0.5f, |
| 792 rect.fRight - 0.5f, rect.fBottom - 0.5f); | 795 rect.fRight - 0.5f, rect.fBottom - 0.5f); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 819 void DashingLineEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const
{ | 822 void DashingLineEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const
{ |
| 820 inout->mulByUnknownAlpha(); | 823 inout->mulByUnknownAlpha(); |
| 821 } | 824 } |
| 822 | 825 |
| 823 const GrBackendGeometryProcessorFactory& DashingLineEffect::getFactory() const { | 826 const GrBackendGeometryProcessorFactory& DashingLineEffect::getFactory() const { |
| 824 return GrTBackendGeometryProcessorFactory<DashingLineEffect>::getInstance(); | 827 return GrTBackendGeometryProcessorFactory<DashingLineEffect>::getInstance(); |
| 825 } | 828 } |
| 826 | 829 |
| 827 DashingLineEffect::DashingLineEffect(GrPrimitiveEdgeType edgeType, const DashInf
o& info, | 830 DashingLineEffect::DashingLineEffect(GrPrimitiveEdgeType edgeType, const DashInf
o& info, |
| 828 SkScalar strokeWidth) | 831 SkScalar strokeWidth) |
| 829 : fEdgeType(edgeType) | 832 : fEdgeType(edgeType) { |
| 830 , fInCoord(this->addVertexAttrib(GrShaderVar("inCoord", | 833 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVert
exAttribType)); |
| 831 kVec2f_GrSLType, | 834 fInCoord = &this->addVertexAttrib(GrAttribute("inCoord", kVec2f_GrVertexAttr
ibType)); |
| 832 GrShaderVar::kAttribute_TypeMod
ifier))) { | |
| 833 SkScalar onLen = info.fIntervals[0]; | 835 SkScalar onLen = info.fIntervals[0]; |
| 834 SkScalar offLen = info.fIntervals[1]; | 836 SkScalar offLen = info.fIntervals[1]; |
| 835 SkScalar halfOffLen = SkScalarHalf(offLen); | 837 SkScalar halfOffLen = SkScalarHalf(offLen); |
| 836 SkScalar halfStroke = SkScalarHalf(strokeWidth); | 838 SkScalar halfStroke = SkScalarHalf(strokeWidth); |
| 837 fIntervalLength = onLen + offLen; | 839 fIntervalLength = onLen + offLen; |
| 838 fRect.set(halfOffLen, -halfStroke, halfOffLen + onLen, halfStroke); | 840 fRect.set(halfOffLen, -halfStroke, halfOffLen + onLen, halfStroke); |
| 839 } | 841 } |
| 840 | 842 |
| 841 bool DashingLineEffect::onIsEqual(const GrGeometryProcessor& other) const { | 843 bool DashingLineEffect::onIsEqual(const GrGeometryProcessor& other) const { |
| 842 const DashingLineEffect& de = other.cast<DashingLineEffect>(); | 844 const DashingLineEffect& de = other.cast<DashingLineEffect>(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 874 switch (cap) { | 876 switch (cap) { |
| 875 case GrDashingEffect::kRound_DashCap: | 877 case GrDashingEffect::kRound_DashCap: |
| 876 return DashingCircleEffect::Create(edgeType, info, SkScalarHalf(stro
keWidth)); | 878 return DashingCircleEffect::Create(edgeType, info, SkScalarHalf(stro
keWidth)); |
| 877 case GrDashingEffect::kNonRound_DashCap: | 879 case GrDashingEffect::kNonRound_DashCap: |
| 878 return DashingLineEffect::Create(edgeType, info, strokeWidth); | 880 return DashingLineEffect::Create(edgeType, info, strokeWidth); |
| 879 default: | 881 default: |
| 880 SkFAIL("Unexpected dashed cap."); | 882 SkFAIL("Unexpected dashed cap."); |
| 881 } | 883 } |
| 882 return NULL; | 884 return NULL; |
| 883 } | 885 } |
| OLD | NEW |