| OLD | NEW | 
|---|
| 1 | 1 | 
| 2 /* | 2 /* | 
| 3  * Copyright 2011 Google Inc. | 3  * Copyright 2011 Google Inc. | 
| 4  * | 4  * | 
| 5  * Use of this source code is governed by a BSD-style license that can be | 5  * Use of this source code is governed by a BSD-style license that can be | 
| 6  * found in the LICENSE file. | 6  * found in the LICENSE file. | 
| 7  */ | 7  */ | 
| 8 | 8 | 
| 9 #include "GrAAHairLinePathRenderer.h" | 9 #include "GrAAHairLinePathRenderer.h" | 
| 10 | 10 | 
| 11 #include "GrContext.h" | 11 #include "GrContext.h" | 
| 12 #include "GrDrawState.h" | 12 #include "GrDrawState.h" | 
| 13 #include "GrDrawTargetCaps.h" | 13 #include "GrDrawTargetCaps.h" | 
|  | 14 #include "GrEffect.h" | 
| 14 #include "GrGpu.h" | 15 #include "GrGpu.h" | 
| 15 #include "GrIndexBuffer.h" | 16 #include "GrIndexBuffer.h" | 
| 16 #include "GrPathUtils.h" | 17 #include "GrPathUtils.h" | 
|  | 18 #include "GrTBackendEffectFactory.h" | 
| 17 #include "SkGeometry.h" | 19 #include "SkGeometry.h" | 
| 18 #include "SkStroke.h" | 20 #include "SkStroke.h" | 
| 19 #include "SkTemplates.h" | 21 #include "SkTemplates.h" | 
| 20 | 22 | 
| 21 #include "effects/GrEdgeEffect.h" | 23 #include "gl/GrGLEffect.h" | 
|  | 24 #include "gl/GrGLSL.h" | 
| 22 | 25 | 
| 23 namespace { | 26 namespace { | 
| 24 // quadratics are rendered as 5-sided polys in order to bound the | 27 // quadratics are rendered as 5-sided polys in order to bound the | 
| 25 // AA stroke around the center-curve. See comments in push_quad_index_buffer and | 28 // AA stroke around the center-curve. See comments in push_quad_index_buffer and | 
| 26 // bloat_quad. | 29 // bloat_quad. | 
| 27 static const int kVertsPerQuad = 5; | 30 static const int kVertsPerQuad = 5; | 
| 28 static const int kIdxsPerQuad = 9; | 31 static const int kIdxsPerQuad = 9; | 
| 29 | 32 | 
| 30 static const int kVertsPerLineSeg = 4; | 33 static const int kVertsPerLineSeg = 4; | 
| 31 static const int kIdxsPerLineSeg = 6; | 34 static const int kIdxsPerLineSeg = 6; | 
| (...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 485         (*vert)[1].fPos.set(SK_ScalarMax, SK_ScalarMax); | 488         (*vert)[1].fPos.set(SK_ScalarMax, SK_ScalarMax); | 
| 486         (*vert)[2].fPos.set(SK_ScalarMax, SK_ScalarMax); | 489         (*vert)[2].fPos.set(SK_ScalarMax, SK_ScalarMax); | 
| 487         (*vert)[3].fPos.set(SK_ScalarMax, SK_ScalarMax); | 490         (*vert)[3].fPos.set(SK_ScalarMax, SK_ScalarMax); | 
| 488     } | 491     } | 
| 489 | 492 | 
| 490     *vert += kVertsPerLineSeg; | 493     *vert += kVertsPerLineSeg; | 
| 491 } | 494 } | 
| 492 | 495 | 
| 493 } | 496 } | 
| 494 | 497 | 
|  | 498 /////////////////////////////////////////////////////////////////////////////// | 
|  | 499 | 
|  | 500 /** | 
|  | 501  * The output of this effect is a hairline edge for quadratics. | 
|  | 502  * Quadratic specified by 0=u^2-v canonical coords. u and v are the first | 
|  | 503  * two components of the vertex attribute. Uses unsigned distance. | 
|  | 504  * Coverage is min(0, 1-distance). 3rd & 4th component unused. | 
|  | 505  * Requires shader derivative instruction support. | 
|  | 506  */ | 
|  | 507 class HairQuadEdgeEffect : public GrEffect { | 
|  | 508 public: | 
|  | 509 | 
|  | 510     static GrEffectRef* Create() { | 
|  | 511         // we go through this so we only have one copy of each effect | 
|  | 512         static GrEffectRef* gHairQuadEdgeEffectRef = | 
|  | 513             CreateEffectRef(AutoEffectUnref(SkNEW(HairQuadEdgeEffect))); | 
|  | 514         static SkAutoTUnref<GrEffectRef> gUnref(gHairQuadEdgeEffectRef); | 
|  | 515 | 
|  | 516         gHairQuadEdgeEffectRef->ref(); | 
|  | 517         return gHairQuadEdgeEffectRef; | 
|  | 518     } | 
|  | 519 | 
|  | 520     virtual ~HairQuadEdgeEffect() {} | 
|  | 521 | 
|  | 522     static const char* Name() { return "HairQuadEdge"; } | 
|  | 523 | 
|  | 524     virtual void getConstantColorComponents(GrColor* color, | 
|  | 525                                             uint32_t* validFlags) const SK_OVERR
     IDE { | 
|  | 526         *validFlags = 0; | 
|  | 527     } | 
|  | 528 | 
|  | 529     virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { | 
|  | 530         return GrTBackendEffectFactory<HairQuadEdgeEffect>::getInstance(); | 
|  | 531     } | 
|  | 532 | 
|  | 533     class GLEffect : public GrGLEffect { | 
|  | 534     public: | 
|  | 535         GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) | 
|  | 536             : INHERITED (factory) {} | 
|  | 537 | 
|  | 538         virtual void emitCode(GrGLShaderBuilder* builder, | 
|  | 539                               const GrDrawEffect& drawEffect, | 
|  | 540                               EffectKey key, | 
|  | 541                               const char* outputColor, | 
|  | 542                               const char* inputColor, | 
|  | 543                               const TextureSamplerArray& samplers) SK_OVERRIDE { | 
|  | 544             const char *vsName, *fsName; | 
|  | 545             const SkString* attrName = | 
|  | 546                 builder->getEffectAttributeName(drawEffect.getVertexAttribIndice
     s()[0]); | 
|  | 547             builder->fsCodeAppendf("\t\tfloat edgeAlpha;\n"); | 
|  | 548 | 
|  | 549             SkAssertResult(builder->enableFeature( | 
|  | 550                                               GrGLShaderBuilder::kStandardDeriva
     tives_GLSLFeature)); | 
|  | 551             builder->addVarying(kVec4f_GrSLType, "HairQuadEdge", &vsName, &fsNam
     e); | 
|  | 552 | 
|  | 553             builder->fsCodeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName); | 
|  | 554             builder->fsCodeAppendf("\t\tvec2 duvdy = dFdy(%s.xy);\n", fsName); | 
|  | 555             builder->fsCodeAppendf("\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.
     y,\n" | 
|  | 556                                    "\t\t               2.0*%s.x*duvdy.x - duvdy.
     y);\n", | 
|  | 557                                    fsName, fsName); | 
|  | 558             builder->fsCodeAppendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsNa
     me, fsName, | 
|  | 559                                    fsName); | 
|  | 560             builder->fsCodeAppend("\t\tedgeAlpha = sqrt(edgeAlpha*edgeAlpha / do
     t(gF, gF));\n"); | 
|  | 561             builder->fsCodeAppend("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n"
     ); | 
|  | 562 | 
|  | 563             SkString modulate; | 
|  | 564             GrGLSLModulate4f(&modulate, inputColor, "edgeAlpha"); | 
|  | 565             builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str()
     ); | 
|  | 566 | 
|  | 567             builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str()); | 
|  | 568         } | 
|  | 569 | 
|  | 570         static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrG
     LCaps&) { | 
|  | 571             return 0x0; | 
|  | 572         } | 
|  | 573 | 
|  | 574         virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_
     OVERRIDE {} | 
|  | 575 | 
|  | 576     private: | 
|  | 577         typedef GrGLEffect INHERITED; | 
|  | 578     }; | 
|  | 579 | 
|  | 580 private: | 
|  | 581     HairQuadEdgeEffect() { | 
|  | 582         this->addVertexAttrib(kVec4f_GrSLType); | 
|  | 583     } | 
|  | 584 | 
|  | 585     virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { | 
|  | 586         return true; | 
|  | 587     } | 
|  | 588 | 
|  | 589     GR_DECLARE_EFFECT_TEST; | 
|  | 590 | 
|  | 591     typedef GrEffect INHERITED; | 
|  | 592 }; | 
|  | 593 | 
|  | 594 GR_DEFINE_EFFECT_TEST(HairQuadEdgeEffect); | 
|  | 595 | 
|  | 596 GrEffectRef* HairQuadEdgeEffect::TestCreate(SkMWCRandom* random, | 
|  | 597                                             GrContext*, | 
|  | 598                                             const GrDrawTargetCaps& caps, | 
|  | 599                                             GrTexture*[]) { | 
|  | 600     // Doesn't work without derivative instructions. | 
|  | 601     return caps.shaderDerivativeSupport() ? HairQuadEdgeEffect::Create() : NULL;
     } | 
|  | 602 | 
|  | 603 /////////////////////////////////////////////////////////////////////////////// | 
|  | 604 | 
|  | 605 /** | 
|  | 606  * The output of this effect is a 1-pixel wide line. | 
|  | 607  * Input is 2D implicit device coord line eq (a*x + b*y +c = 0). 4th component u
     nused. | 
|  | 608  */ | 
|  | 609 class HairLineEdgeEffect : public GrEffect { | 
|  | 610 public: | 
|  | 611 | 
|  | 612     static GrEffectRef* Create() { | 
|  | 613         // we go through this so we only have one copy of each effect | 
|  | 614         static GrEffectRef* gHairLineEdgeEffectRef = | 
|  | 615             CreateEffectRef(AutoEffectUnref(SkNEW(HairLineEdgeEffect))); | 
|  | 616         static SkAutoTUnref<GrEffectRef> gUnref(gHairLineEdgeEffectRef); | 
|  | 617 | 
|  | 618         gHairLineEdgeEffectRef->ref(); | 
|  | 619         return gHairLineEdgeEffectRef; | 
|  | 620     } | 
|  | 621 | 
|  | 622     virtual ~HairLineEdgeEffect() {} | 
|  | 623 | 
|  | 624     static const char* Name() { return "HairLineEdge"; } | 
|  | 625 | 
|  | 626     virtual void getConstantColorComponents(GrColor* color, | 
|  | 627                                             uint32_t* validFlags) const SK_OVERR
     IDE { | 
|  | 628         *validFlags = 0; | 
|  | 629     } | 
|  | 630 | 
|  | 631     virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { | 
|  | 632         return GrTBackendEffectFactory<HairLineEdgeEffect>::getInstance(); | 
|  | 633     } | 
|  | 634 | 
|  | 635     class GLEffect : public GrGLEffect { | 
|  | 636     public: | 
|  | 637         GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) | 
|  | 638             : INHERITED (factory) {} | 
|  | 639 | 
|  | 640         virtual void emitCode(GrGLShaderBuilder* builder, | 
|  | 641                               const GrDrawEffect& drawEffect, | 
|  | 642                               EffectKey key, | 
|  | 643                               const char* outputColor, | 
|  | 644                               const char* inputColor, | 
|  | 645                               const TextureSamplerArray& samplers) SK_OVERRIDE { | 
|  | 646             const char *vsName, *fsName; | 
|  | 647             const SkString* attrName = | 
|  | 648                 builder->getEffectAttributeName(drawEffect.getVertexAttribIndice
     s()[0]); | 
|  | 649             builder->fsCodeAppendf("\t\tfloat edgeAlpha;\n"); | 
|  | 650 | 
|  | 651             builder->addVarying(kVec4f_GrSLType, "HairLineEdge", &vsName, &fsNam
     e); | 
|  | 652 | 
|  | 653             builder->fsCodeAppendf("\t\tedgeAlpha = abs(dot(vec3(%s.xy,1), %s.xy
     z));\n", | 
|  | 654                                    builder->fragmentPosition(), fsName); | 
|  | 655             builder->fsCodeAppendf("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n
     "); | 
|  | 656 | 
|  | 657             SkString modulate; | 
|  | 658             GrGLSLModulate4f(&modulate, inputColor, "edgeAlpha"); | 
|  | 659             builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str()
     ); | 
|  | 660 | 
|  | 661             builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str()); | 
|  | 662         } | 
|  | 663 | 
|  | 664         static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrG
     LCaps&) { | 
|  | 665             return 0x0; | 
|  | 666         } | 
|  | 667 | 
|  | 668         virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_
     OVERRIDE {} | 
|  | 669 | 
|  | 670     private: | 
|  | 671         typedef GrGLEffect INHERITED; | 
|  | 672     }; | 
|  | 673 | 
|  | 674 private: | 
|  | 675     HairLineEdgeEffect() { | 
|  | 676         this->addVertexAttrib(kVec4f_GrSLType); | 
|  | 677     } | 
|  | 678 | 
|  | 679     virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { | 
|  | 680         return true; | 
|  | 681     } | 
|  | 682 | 
|  | 683     GR_DECLARE_EFFECT_TEST; | 
|  | 684 | 
|  | 685     typedef GrEffect INHERITED; | 
|  | 686 }; | 
|  | 687 | 
|  | 688 GR_DEFINE_EFFECT_TEST(HairLineEdgeEffect); | 
|  | 689 | 
|  | 690 GrEffectRef* HairLineEdgeEffect::TestCreate(SkMWCRandom* random, | 
|  | 691                                             GrContext*, | 
|  | 692                                             const GrDrawTargetCaps& caps, | 
|  | 693                                             GrTexture*[]) { | 
|  | 694     return HairLineEdgeEffect::Create(); | 
|  | 695 } | 
|  | 696 | 
|  | 697 /////////////////////////////////////////////////////////////////////////////// | 
|  | 698 | 
| 495 bool GrAAHairLinePathRenderer::createGeom( | 699 bool GrAAHairLinePathRenderer::createGeom( | 
| 496             const SkPath& path, | 700             const SkPath& path, | 
| 497             GrDrawTarget* target, | 701             GrDrawTarget* target, | 
| 498             int* lineCnt, | 702             int* lineCnt, | 
| 499             int* quadCnt, | 703             int* quadCnt, | 
| 500             GrDrawTarget::AutoReleaseGeometry* arg) { | 704             GrDrawTarget::AutoReleaseGeometry* arg) { | 
| 501     GrDrawState* drawState = target->drawState(); | 705     GrDrawState* drawState = target->drawState(); | 
| 502     int rtHeight = drawState->getRenderTarget()->height(); | 706     int rtHeight = drawState->getRenderTarget()->height(); | 
| 503 | 707 | 
| 504     GrIRect devClipBounds; | 708     GrIRect devClipBounds; | 
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 604     // when we have a mix | 808     // when we have a mix | 
| 605 | 809 | 
| 606     enum { | 810     enum { | 
| 607         // the edge effects share this stage with glyph rendering | 811         // the edge effects share this stage with glyph rendering | 
| 608         // (kGlyphMaskStage in GrTextContext) && SW path rendering | 812         // (kGlyphMaskStage in GrTextContext) && SW path rendering | 
| 609         // (kPathMaskStage in GrSWMaskHelper) | 813         // (kPathMaskStage in GrSWMaskHelper) | 
| 610         kEdgeEffectStage = GrPaint::kTotalStages, | 814         kEdgeEffectStage = GrPaint::kTotalStages, | 
| 611     }; | 815     }; | 
| 612     static const int kEdgeAttrIndex = 1; | 816     static const int kEdgeAttrIndex = 1; | 
| 613 | 817 | 
| 614     GrEffectRef* hairLineEffect = GrEdgeEffect::Create(GrEdgeEffect::kHairLine_E
     dgeType); | 818     GrEffectRef* hairLineEffect = HairLineEdgeEffect::Create(); | 
| 615     GrEffectRef* hairQuadEffect = GrEdgeEffect::Create(GrEdgeEffect::kHairQuad_E
     dgeType); | 819     GrEffectRef* hairQuadEffect = HairQuadEdgeEffect::Create(); | 
| 616 | 820 | 
| 617     target->setIndexSourceToBuffer(fLinesIndexBuffer); | 821     target->setIndexSourceToBuffer(fLinesIndexBuffer); | 
| 618     int lines = 0; | 822     int lines = 0; | 
| 619     int nBufLines = fLinesIndexBuffer->maxQuads(); | 823     int nBufLines = fLinesIndexBuffer->maxQuads(); | 
| 620     drawState->setEffect(kEdgeEffectStage, hairLineEffect, kEdgeAttrIndex)->unre
     f(); | 824     drawState->setEffect(kEdgeEffectStage, hairLineEffect, kEdgeAttrIndex)->unre
     f(); | 
| 621     while (lines < lineCnt) { | 825     while (lines < lineCnt) { | 
| 622         int n = GrMin(lineCnt - lines, nBufLines); | 826         int n = GrMin(lineCnt - lines, nBufLines); | 
| 623         target->drawIndexed(kTriangles_GrPrimitiveType, | 827         target->drawIndexed(kTriangles_GrPrimitiveType, | 
| 624                             kVertsPerLineSeg*lines,    // startV | 828                             kVertsPerLineSeg*lines,    // startV | 
| 625                             0,                         // startI | 829                             0,                         // startI | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 636         target->drawIndexed(kTriangles_GrPrimitiveType, | 840         target->drawIndexed(kTriangles_GrPrimitiveType, | 
| 637                             4 * lineCnt + kVertsPerQuad*quads, // startV | 841                             4 * lineCnt + kVertsPerQuad*quads, // startV | 
| 638                             0,                                 // startI | 842                             0,                                 // startI | 
| 639                             kVertsPerQuad*n,                   // vCount | 843                             kVertsPerQuad*n,                   // vCount | 
| 640                             kIdxsPerQuad*n);                   // iCount | 844                             kIdxsPerQuad*n);                   // iCount | 
| 641         quads += n; | 845         quads += n; | 
| 642     } | 846     } | 
| 643 | 847 | 
| 644     return true; | 848     return true; | 
| 645 } | 849 } | 
| OLD | NEW | 
|---|