| 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 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 | 524 |
| 525 typedef GrGeometryProcessor INHERITED; | 525 typedef GrGeometryProcessor INHERITED; |
| 526 }; | 526 }; |
| 527 | 527 |
| 528 ////////////////////////////////////////////////////////////////////////////// | 528 ////////////////////////////////////////////////////////////////////////////// |
| 529 | 529 |
| 530 class GLDashingCircleEffect : public GrGLGeometryProcessor { | 530 class GLDashingCircleEffect : public GrGLGeometryProcessor { |
| 531 public: | 531 public: |
| 532 GLDashingCircleEffect(const GrGeometryProcessor&, const GrBatchTracker&); | 532 GLDashingCircleEffect(const GrGeometryProcessor&, const GrBatchTracker&); |
| 533 | 533 |
| 534 void onEmitCode(EmitArgs&) SK_OVERRIDE; | 534 void onEmitCode(EmitArgs&, GrGPArgs*) SK_OVERRIDE; |
| 535 | 535 |
| 536 static inline void GenKey(const GrGeometryProcessor&, | 536 static inline void GenKey(const GrGeometryProcessor&, |
| 537 const GrBatchTracker&, | 537 const GrBatchTracker&, |
| 538 const GrGLCaps&, | 538 const GrGLCaps&, |
| 539 GrProcessorKeyBuilder*); | 539 GrProcessorKeyBuilder*); |
| 540 | 540 |
| 541 virtual void setData(const GrGLProgramDataManager&, | 541 virtual void setData(const GrGLProgramDataManager&, |
| 542 const GrPrimitiveProcessor&, | 542 const GrPrimitiveProcessor&, |
| 543 const GrBatchTracker&) SK_OVERRIDE; | 543 const GrBatchTracker&) SK_OVERRIDE; |
| 544 | 544 |
| 545 private: | 545 private: |
| 546 UniformHandle fParamUniform; | 546 UniformHandle fParamUniform; |
| 547 UniformHandle fColorUniform; | 547 UniformHandle fColorUniform; |
| 548 GrColor fColor; | 548 GrColor fColor; |
| 549 SkScalar fPrevRadius; | 549 SkScalar fPrevRadius; |
| 550 SkScalar fPrevCenterX; | 550 SkScalar fPrevCenterX; |
| 551 SkScalar fPrevIntervalLength; | 551 SkScalar fPrevIntervalLength; |
| 552 typedef GrGLGeometryProcessor INHERITED; | 552 typedef GrGLGeometryProcessor INHERITED; |
| 553 }; | 553 }; |
| 554 | 554 |
| 555 GLDashingCircleEffect::GLDashingCircleEffect(const GrGeometryProcessor&, | 555 GLDashingCircleEffect::GLDashingCircleEffect(const GrGeometryProcessor&, |
| 556 const GrBatchTracker&) { | 556 const GrBatchTracker&) { |
| 557 fColor = GrColor_ILLEGAL; | 557 fColor = GrColor_ILLEGAL; |
| 558 fPrevRadius = SK_ScalarMin; | 558 fPrevRadius = SK_ScalarMin; |
| 559 fPrevCenterX = SK_ScalarMin; | 559 fPrevCenterX = SK_ScalarMin; |
| 560 fPrevIntervalLength = SK_ScalarMax; | 560 fPrevIntervalLength = SK_ScalarMax; |
| 561 } | 561 } |
| 562 | 562 |
| 563 void GLDashingCircleEffect::onEmitCode(EmitArgs& args) { | 563 void GLDashingCircleEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { |
| 564 const DashingCircleEffect& dce = args.fGP.cast<DashingCircleEffect>(); | 564 const DashingCircleEffect& dce = args.fGP.cast<DashingCircleEffect>(); |
| 565 const DashingCircleBatchTracker local = args.fBT.cast<DashingCircleBatchTrac
ker>(); | 565 const DashingCircleBatchTracker local = args.fBT.cast<DashingCircleBatchTrac
ker>(); |
| 566 GrGLGPBuilder* pb = args.fPB; | 566 GrGLGPBuilder* pb = args.fPB; |
| 567 const char *paramName; | 567 const char *paramName; |
| 568 // The param uniforms, xyz, refer to circle radius - 0.5, cicles center x co
ord, and | 568 // The param uniforms, xyz, refer to circle radius - 0.5, cicles center x co
ord, and |
| 569 // the total interval length of the dash. | 569 // the total interval length of the dash. |
| 570 fParamUniform = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibilit
y, | 570 fParamUniform = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibilit
y, |
| 571 kVec3f_GrSLType, kDefault_GrSLPrecision
, | 571 kVec3f_GrSLType, kDefault_GrSLPrecision
, |
| 572 "params", ¶mName); | 572 "params", ¶mName); |
| 573 | 573 |
| 574 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); | 574 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); |
| 575 | 575 |
| 576 // emit attributes | 576 // emit attributes |
| 577 vsBuilder->emitAttributes(dce); | 577 vsBuilder->emitAttributes(dce); |
| 578 | 578 |
| 579 GrGLVertToFrag v(kVec2f_GrSLType); | 579 GrGLVertToFrag v(kVec2f_GrSLType); |
| 580 args.fPB->addVarying("Coord", &v); | 580 args.fPB->addVarying("Coord", &v); |
| 581 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dce.inCoord()->fName); | 581 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dce.inCoord()->fName); |
| 582 | 582 |
| 583 // Setup pass through color | 583 // Setup pass through color |
| 584 this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NU
LL, &fColorUniform); | 584 this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NU
LL, &fColorUniform); |
| 585 | 585 |
| 586 // setup uniform viewMatrix | 586 // setup uniform viewMatrix |
| 587 this->addUniformViewMatrix(pb); | 587 this->addUniformViewMatrix(pb); |
| 588 | 588 |
| 589 // Setup position | 589 // Setup position |
| 590 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", this->position(), this->uV
iewM(), | 590 SetupPosition(vsBuilder, gpArgs, dce.inPosition()->fName, dce.viewMatrix(),
this->uViewM()); |
| 591 dce.inPosition()->fName); | |
| 592 | 591 |
| 593 // emit transforms | 592 // emit transforms |
| 594 this->emitTransforms(args.fPB, this->position(), dce.inPosition()->fName, d
ce.localMatrix(), | 593 this->emitTransforms(args.fPB, gpArgs->fPositionVar, dce.inPosition()->fName
, dce.localMatrix(), |
| 595 args.fTransformsIn, args.fTransformsOut); | 594 args.fTransformsIn, args.fTransformsOut); |
| 596 | 595 |
| 597 // transforms all points so that we can compare them to our test circle | 596 // transforms all points so that we can compare them to our test circle |
| 598 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); | 597 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); |
| 599 fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s.z) * %s.
z;\n", | 598 fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s.z) * %s.
z;\n", |
| 600 v.fsIn(), v.fsIn(), paramName, paramName); | 599 v.fsIn(), v.fsIn(), paramName, paramName); |
| 601 fsBuilder->codeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n",
v.fsIn()); | 600 fsBuilder->codeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n",
v.fsIn()); |
| 602 fsBuilder->codeAppendf("\t\tvec2 center = vec2(%s.y, 0.0);\n", paramName); | 601 fsBuilder->codeAppendf("\t\tvec2 center = vec2(%s.y, 0.0);\n", paramName); |
| 603 fsBuilder->codeAppend("\t\tfloat dist = length(center - fragPosShifted);\n")
; | 602 fsBuilder->codeAppend("\t\tfloat dist = length(center - fragPosShifted);\n")
; |
| 604 if (GrProcessorEdgeTypeIsAA(dce.getEdgeType())) { | 603 if (GrProcessorEdgeTypeIsAA(dce.getEdgeType())) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 630 | 629 |
| 631 const DashingCircleBatchTracker& local = bt.cast<DashingCircleBatchTracker>(
); | 630 const DashingCircleBatchTracker& local = bt.cast<DashingCircleBatchTracker>(
); |
| 632 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { | 631 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { |
| 633 GrGLfloat c[4]; | 632 GrGLfloat c[4]; |
| 634 GrColorToRGBAFloat(local.fColor, c); | 633 GrColorToRGBAFloat(local.fColor, c); |
| 635 pdman.set4fv(fColorUniform, 1, c); | 634 pdman.set4fv(fColorUniform, 1, c); |
| 636 fColor = local.fColor; | 635 fColor = local.fColor; |
| 637 } | 636 } |
| 638 } | 637 } |
| 639 | 638 |
| 640 void GLDashingCircleEffect::GenKey(const GrGeometryProcessor& processor, | 639 void GLDashingCircleEffect::GenKey(const GrGeometryProcessor& gp, |
| 641 const GrBatchTracker& bt, | 640 const GrBatchTracker& bt, |
| 642 const GrGLCaps&, | 641 const GrGLCaps&, |
| 643 GrProcessorKeyBuilder* b) { | 642 GrProcessorKeyBuilder* b) { |
| 644 const DashingCircleBatchTracker& local = bt.cast<DashingCircleBatchTracker>(
); | 643 const DashingCircleBatchTracker& local = bt.cast<DashingCircleBatchTracker>(
); |
| 645 const DashingCircleEffect& dce = processor.cast<DashingCircleEffect>(); | 644 const DashingCircleEffect& dce = gp.cast<DashingCircleEffect>(); |
| 646 b->add32(local.fUsesLocalCoords && processor.localMatrix().hasPerspective())
; | 645 uint32_t key = 0; |
| 647 b->add32(dce.getEdgeType() << 16 | local.fInputColorType); | 646 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 : 0
x0; |
| 647 key |= ComputePosKey(gp.viewMatrix()) << 1; |
| 648 key |= dce.getEdgeType() << 8; |
| 649 b->add32(key << 16 | local.fInputColorType); |
| 648 } | 650 } |
| 649 | 651 |
| 650 ////////////////////////////////////////////////////////////////////////////// | 652 ////////////////////////////////////////////////////////////////////////////// |
| 651 | 653 |
| 652 GrGeometryProcessor* DashingCircleEffect::Create(GrColor color, | 654 GrGeometryProcessor* DashingCircleEffect::Create(GrColor color, |
| 653 GrPrimitiveEdgeType edgeType, | 655 GrPrimitiveEdgeType edgeType, |
| 654 const DashInfo& info, | 656 const DashInfo& info, |
| 655 SkScalar radius, | 657 SkScalar radius, |
| 656 const SkMatrix& localMatrix) { | 658 const SkMatrix& localMatrix) { |
| 657 if (info.fCount != 2 || info.fIntervals[0] != 0) { | 659 if (info.fCount != 2 || info.fIntervals[0] != 0) { |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 815 | 817 |
| 816 typedef GrGeometryProcessor INHERITED; | 818 typedef GrGeometryProcessor INHERITED; |
| 817 }; | 819 }; |
| 818 | 820 |
| 819 ////////////////////////////////////////////////////////////////////////////// | 821 ////////////////////////////////////////////////////////////////////////////// |
| 820 | 822 |
| 821 class GLDashingLineEffect : public GrGLGeometryProcessor { | 823 class GLDashingLineEffect : public GrGLGeometryProcessor { |
| 822 public: | 824 public: |
| 823 GLDashingLineEffect(const GrGeometryProcessor&, const GrBatchTracker&); | 825 GLDashingLineEffect(const GrGeometryProcessor&, const GrBatchTracker&); |
| 824 | 826 |
| 825 void onEmitCode(EmitArgs&) SK_OVERRIDE; | 827 void onEmitCode(EmitArgs&, GrGPArgs*) SK_OVERRIDE; |
| 826 | 828 |
| 827 static inline void GenKey(const GrGeometryProcessor&, | 829 static inline void GenKey(const GrGeometryProcessor&, |
| 828 const GrBatchTracker&, | 830 const GrBatchTracker&, |
| 829 const GrGLCaps&, | 831 const GrGLCaps&, |
| 830 GrProcessorKeyBuilder*); | 832 GrProcessorKeyBuilder*); |
| 831 | 833 |
| 832 virtual void setData(const GrGLProgramDataManager&, | 834 virtual void setData(const GrGLProgramDataManager&, |
| 833 const GrPrimitiveProcessor&, | 835 const GrPrimitiveProcessor&, |
| 834 const GrBatchTracker&) SK_OVERRIDE; | 836 const GrBatchTracker&) SK_OVERRIDE; |
| 835 | 837 |
| 836 private: | 838 private: |
| 837 GrColor fColor; | 839 GrColor fColor; |
| 838 UniformHandle fRectUniform; | 840 UniformHandle fRectUniform; |
| 839 UniformHandle fIntervalUniform; | 841 UniformHandle fIntervalUniform; |
| 840 UniformHandle fColorUniform; | 842 UniformHandle fColorUniform; |
| 841 SkRect fPrevRect; | 843 SkRect fPrevRect; |
| 842 SkScalar fPrevIntervalLength; | 844 SkScalar fPrevIntervalLength; |
| 843 typedef GrGLGeometryProcessor INHERITED; | 845 typedef GrGLGeometryProcessor INHERITED; |
| 844 }; | 846 }; |
| 845 | 847 |
| 846 GLDashingLineEffect::GLDashingLineEffect(const GrGeometryProcessor&, | 848 GLDashingLineEffect::GLDashingLineEffect(const GrGeometryProcessor&, |
| 847 const GrBatchTracker&) { | 849 const GrBatchTracker&) { |
| 848 fColor = GrColor_ILLEGAL; | 850 fColor = GrColor_ILLEGAL; |
| 849 fPrevRect.fLeft = SK_ScalarNaN; | 851 fPrevRect.fLeft = SK_ScalarNaN; |
| 850 fPrevIntervalLength = SK_ScalarMax; | 852 fPrevIntervalLength = SK_ScalarMax; |
| 851 } | 853 } |
| 852 | 854 |
| 853 void GLDashingLineEffect::onEmitCode(EmitArgs& args) { | 855 void GLDashingLineEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { |
| 854 const DashingLineEffect& de = args.fGP.cast<DashingLineEffect>(); | 856 const DashingLineEffect& de = args.fGP.cast<DashingLineEffect>(); |
| 855 const DashingLineBatchTracker& local = args.fBT.cast<DashingLineBatchTracker
>(); | 857 const DashingLineBatchTracker& local = args.fBT.cast<DashingLineBatchTracker
>(); |
| 856 GrGLGPBuilder* pb = args.fPB; | 858 GrGLGPBuilder* pb = args.fPB; |
| 857 const char *rectName; | 859 const char *rectName; |
| 858 // The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bot
tom - 0.5), | 860 // The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bot
tom - 0.5), |
| 859 // respectively. | 861 // respectively. |
| 860 fRectUniform = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility
, | 862 fRectUniform = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility
, |
| 861 kVec4f_GrSLType, kDefault_GrSLPrecision, | 863 kVec4f_GrSLType, kDefault_GrSLPrecision, |
| 862 "rect", | 864 "rect", |
| 863 &rectName); | 865 &rectName); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 878 args.fPB->addVarying("Coord", &v); | 880 args.fPB->addVarying("Coord", &v); |
| 879 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), de.inCoord()->fName); | 881 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), de.inCoord()->fName); |
| 880 | 882 |
| 881 // Setup pass through color | 883 // Setup pass through color |
| 882 this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NU
LL, &fColorUniform); | 884 this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NU
LL, &fColorUniform); |
| 883 | 885 |
| 884 // setup uniform viewMatrix | 886 // setup uniform viewMatrix |
| 885 this->addUniformViewMatrix(pb); | 887 this->addUniformViewMatrix(pb); |
| 886 | 888 |
| 887 // Setup position | 889 // Setup position |
| 888 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", this->position(), this->uV
iewM(), | 890 SetupPosition(vsBuilder, gpArgs, de.inPosition()->fName, de.viewMatrix(), th
is->uViewM()); |
| 889 de.inPosition()->fName); | |
| 890 | 891 |
| 891 // emit transforms | 892 // emit transforms |
| 892 this->emitTransforms(args.fPB, this->position(), de.inPosition()->fName, de
.localMatrix(), | 893 this->emitTransforms(args.fPB, gpArgs->fPositionVar, de.inPosition()->fName,
de.localMatrix(), |
| 893 args.fTransformsIn, args.fTransformsOut); | 894 args.fTransformsIn, args.fTransformsOut); |
| 894 | 895 |
| 895 // transforms all points so that we can compare them to our test rect | 896 // transforms all points so that we can compare them to our test rect |
| 896 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); | 897 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); |
| 897 fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s) * %s;\n
", | 898 fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s) * %s;\n
", |
| 898 v.fsIn(), v.fsIn(), intervalName, intervalName); | 899 v.fsIn(), v.fsIn(), intervalName, intervalName); |
| 899 fsBuilder->codeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n",
v.fsIn()); | 900 fsBuilder->codeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n",
v.fsIn()); |
| 900 if (GrProcessorEdgeTypeIsAA(de.getEdgeType())) { | 901 if (GrProcessorEdgeTypeIsAA(de.getEdgeType())) { |
| 901 // The amount of coverage removed in x and y by the edges is computed as
a pair of negative | 902 // The amount of coverage removed in x and y by the edges is computed as
a pair of negative |
| 902 // numbers, xSub and ySub. | 903 // numbers, xSub and ySub. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 935 | 936 |
| 936 const DashingLineBatchTracker& local = bt.cast<DashingLineBatchTracker>(); | 937 const DashingLineBatchTracker& local = bt.cast<DashingLineBatchTracker>(); |
| 937 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { | 938 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { |
| 938 GrGLfloat c[4]; | 939 GrGLfloat c[4]; |
| 939 GrColorToRGBAFloat(local.fColor, c); | 940 GrColorToRGBAFloat(local.fColor, c); |
| 940 pdman.set4fv(fColorUniform, 1, c); | 941 pdman.set4fv(fColorUniform, 1, c); |
| 941 fColor = local.fColor; | 942 fColor = local.fColor; |
| 942 } | 943 } |
| 943 } | 944 } |
| 944 | 945 |
| 945 void GLDashingLineEffect::GenKey(const GrGeometryProcessor& processor, | 946 void GLDashingLineEffect::GenKey(const GrGeometryProcessor& gp, |
| 946 const GrBatchTracker& bt, | 947 const GrBatchTracker& bt, |
| 947 const GrGLCaps&, | 948 const GrGLCaps&, |
| 948 GrProcessorKeyBuilder* b) { | 949 GrProcessorKeyBuilder* b) { |
| 949 const DashingLineBatchTracker& local = bt.cast<DashingLineBatchTracker>(); | 950 const DashingLineBatchTracker& local = bt.cast<DashingLineBatchTracker>(); |
| 950 const DashingLineEffect& de = processor.cast<DashingLineEffect>(); | 951 const DashingLineEffect& de = gp.cast<DashingLineEffect>(); |
| 951 b->add32(local.fUsesLocalCoords && processor.localMatrix().hasPerspective())
; | 952 uint32_t key = 0; |
| 952 b->add32(de.getEdgeType() << 16 | local.fInputColorType); | 953 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 : 0
x0; |
| 954 key |= ComputePosKey(gp.viewMatrix()) << 1; |
| 955 key |= de.getEdgeType() << 8; |
| 956 b->add32(key << 16 | local.fInputColorType); |
| 953 } | 957 } |
| 954 | 958 |
| 955 ////////////////////////////////////////////////////////////////////////////// | 959 ////////////////////////////////////////////////////////////////////////////// |
| 956 | 960 |
| 957 GrGeometryProcessor* DashingLineEffect::Create(GrColor color, | 961 GrGeometryProcessor* DashingLineEffect::Create(GrColor color, |
| 958 GrPrimitiveEdgeType edgeType, | 962 GrPrimitiveEdgeType edgeType, |
| 959 const DashInfo& info, | 963 const DashInfo& info, |
| 960 SkScalar strokeWidth, | 964 SkScalar strokeWidth, |
| 961 const SkMatrix& localMatrix) { | 965 const SkMatrix& localMatrix) { |
| 962 if (info.fCount != 2) { | 966 if (info.fCount != 2) { |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1059 return DashingCircleEffect::Create(color, edgeType, info, | 1063 return DashingCircleEffect::Create(color, edgeType, info, |
| 1060 SkScalarHalf(strokeWidth), | 1064 SkScalarHalf(strokeWidth), |
| 1061 localMatrix); | 1065 localMatrix); |
| 1062 case GrDashingEffect::kNonRound_DashCap: | 1066 case GrDashingEffect::kNonRound_DashCap: |
| 1063 return DashingLineEffect::Create(color, edgeType, info, strokeWidth,
localMatrix); | 1067 return DashingLineEffect::Create(color, edgeType, info, strokeWidth,
localMatrix); |
| 1064 default: | 1068 default: |
| 1065 SkFAIL("Unexpected dashed cap."); | 1069 SkFAIL("Unexpected dashed cap."); |
| 1066 } | 1070 } |
| 1067 return NULL; | 1071 return NULL; |
| 1068 } | 1072 } |
| OLD | NEW |