| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 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 "GrAAHairLinePathRenderer.h" | 8 #include "GrAAHairLinePathRenderer.h" |
| 9 | 9 |
| 10 #include "GrContext.h" | 10 #include "GrContext.h" |
| 11 #include "GrDrawState.h" | 11 #include "GrDrawState.h" |
| 12 #include "GrDrawTargetCaps.h" | 12 #include "GrDrawTargetCaps.h" |
| 13 #include "GrEffect.h" | 13 #include "GrEffect.h" |
| 14 #include "GrGpu.h" | 14 #include "GrGpu.h" |
| 15 #include "GrIndexBuffer.h" | 15 #include "GrIndexBuffer.h" |
| 16 #include "GrPathUtils.h" | 16 #include "GrPathUtils.h" |
| 17 #include "GrTBackendEffectFactory.h" | 17 #include "GrTBackendEffectFactory.h" |
| 18 #include "SkGeometry.h" | 18 #include "SkGeometry.h" |
| 19 #include "SkStroke.h" | 19 #include "SkStroke.h" |
| 20 #include "SkTemplates.h" | 20 #include "SkTemplates.h" |
| 21 | 21 |
| 22 #include "gl/GrGLEffect.h" | 22 #include "effects/GrBezierEffect.h" |
| 23 #include "gl/GrGLSL.h" | |
| 24 | 23 |
| 25 namespace { | 24 namespace { |
| 26 // quadratics are rendered as 5-sided polys in order to bound the | 25 // quadratics are rendered as 5-sided polys in order to bound the |
| 27 // AA stroke around the center-curve. See comments in push_quad_index_buffer and | 26 // AA stroke around the center-curve. See comments in push_quad_index_buffer and |
| 28 // bloat_quad. Quadratics and conics share an index buffer | 27 // bloat_quad. Quadratics and conics share an index buffer |
| 29 static const int kVertsPerQuad = 5; | 28 static const int kVertsPerQuad = 5; |
| 30 static const int kIdxsPerQuad = 9; | 29 static const int kIdxsPerQuad = 9; |
| 31 | 30 |
| 32 static const int kVertsPerLineSeg = 6; | 31 static const int kVertsPerLineSeg = 6; |
| 33 static const int kIdxsPerLineSeg = 12; | 32 static const int kIdxsPerLineSeg = 12; |
| (...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 687 for (int i = 0; i < kVertsPerLineSeg; ++i) { | 686 for (int i = 0; i < kVertsPerLineSeg; ++i) { |
| 688 (*vert)[i].fPos.set(SK_ScalarMax, SK_ScalarMax); | 687 (*vert)[i].fPos.set(SK_ScalarMax, SK_ScalarMax); |
| 689 } | 688 } |
| 690 } | 689 } |
| 691 | 690 |
| 692 *vert += kVertsPerLineSeg; | 691 *vert += kVertsPerLineSeg; |
| 693 } | 692 } |
| 694 | 693 |
| 695 } | 694 } |
| 696 | 695 |
| 697 /** | |
| 698 * Shader is based off of "Resolution Independent Curve Rendering using | |
| 699 * Programmable Graphics Hardware" by Loop and Blinn. | |
| 700 * The output of this effect is a hairline edge for non rational cubics. | |
| 701 * Cubics are specified by implicit equation K^3 - LM. | |
| 702 * K, L, and M, are the first three values of the vertex attribute, | |
| 703 * the fourth value is not used. Distance is calculated using a | |
| 704 * first order approximation from the taylor series. | |
| 705 * Coverage is max(0, 1-distance). | |
| 706 */ | |
| 707 class HairCubicEdgeEffect : public GrEffect { | |
| 708 public: | |
| 709 static GrEffectRef* Create() { | |
| 710 GR_CREATE_STATIC_EFFECT(gHairCubicEdgeEffect, HairCubicEdgeEffect, ()); | |
| 711 gHairCubicEdgeEffect->ref(); | |
| 712 return gHairCubicEdgeEffect; | |
| 713 } | |
| 714 | |
| 715 virtual ~HairCubicEdgeEffect() {} | |
| 716 | |
| 717 static const char* Name() { return "HairCubicEdge"; } | |
| 718 | |
| 719 virtual void getConstantColorComponents(GrColor* color, | |
| 720 uint32_t* validFlags) const SK_OVERR
IDE { | |
| 721 *validFlags = 0; | |
| 722 } | |
| 723 | |
| 724 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { | |
| 725 return GrTBackendEffectFactory<HairCubicEdgeEffect>::getInstance(); | |
| 726 } | |
| 727 | |
| 728 class GLEffect : public GrGLEffect { | |
| 729 public: | |
| 730 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) | |
| 731 : INHERITED (factory) {} | |
| 732 | |
| 733 virtual void emitCode(GrGLShaderBuilder* builder, | |
| 734 const GrDrawEffect& drawEffect, | |
| 735 EffectKey key, | |
| 736 const char* outputColor, | |
| 737 const char* inputColor, | |
| 738 const TextureSamplerArray& samplers) SK_OVERRIDE { | |
| 739 const char *vsName, *fsName; | |
| 740 | |
| 741 SkAssertResult(builder->enableFeature( | |
| 742 GrGLShaderBuilder::kStandardDerivatives_GLSLFeature)); | |
| 743 builder->addVarying(kVec4f_GrSLType, "CubicCoeffs", | |
| 744 &vsName, &fsName); | |
| 745 const SkString* attr0Name = | |
| 746 builder->getEffectAttributeName(drawEffect.getVertexAttribIndice
s()[0]); | |
| 747 builder->vsCodeAppendf("\t%s = %s;\n", vsName, attr0Name->c_str()); | |
| 748 | |
| 749 builder->fsCodeAppend("\t\tfloat edgeAlpha;\n"); | |
| 750 | |
| 751 builder->fsCodeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName); | |
| 752 builder->fsCodeAppendf("\t\tvec3 dklmdy = dFdy(%s.xyz);\n", fsName); | |
| 753 builder->fsCodeAppendf("\t\tfloat dfdx =\n" | |
| 754 "\t\t3.0*%s.x*%s.x*dklmdx.x - %s.y*dklmdx.z -
%s.z*dklmdx.y;\n", | |
| 755 fsName, fsName, fsName, fsName); | |
| 756 builder->fsCodeAppendf("\t\tfloat dfdy =\n" | |
| 757 "\t\t3.0*%s.x*%s.x*dklmdy.x - %s.y*dklmdy.z -
%s.z*dklmdy.y;\n", | |
| 758 fsName, fsName, fsName, fsName); | |
| 759 builder->fsCodeAppend("\t\tvec2 gF = vec2(dfdx, dfdy);\n"); | |
| 760 builder->fsCodeAppend("\t\tfloat gFM = sqrt(dot(gF, gF));\n"); | |
| 761 builder->fsCodeAppendf("\t\tfloat func = abs(%s.x*%s.x*%s.x - %s.y*%
s.z);\n", | |
| 762 fsName, fsName, fsName, fsName, fsName); | |
| 763 builder->fsCodeAppend("\t\tedgeAlpha = func / gFM;\n"); | |
| 764 builder->fsCodeAppend("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n"
); | |
| 765 // Add line below for smooth cubic ramp | |
| 766 // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2
.0*edgeAlpha);\n"); | |
| 767 | |
| 768 SkString modulate; | |
| 769 GrGLSLModulatef<4>(&modulate, inputColor, "edgeAlpha"); | |
| 770 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str()
); | |
| 771 } | |
| 772 | |
| 773 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrG
LCaps&) { | |
| 774 return 0x0; | |
| 775 } | |
| 776 | |
| 777 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_
OVERRIDE {} | |
| 778 | |
| 779 private: | |
| 780 typedef GrGLEffect INHERITED; | |
| 781 }; | |
| 782 private: | |
| 783 HairCubicEdgeEffect() { | |
| 784 this->addVertexAttrib(kVec4f_GrSLType); | |
| 785 } | |
| 786 | |
| 787 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { | |
| 788 return true; | |
| 789 } | |
| 790 | |
| 791 GR_DECLARE_EFFECT_TEST; | |
| 792 | |
| 793 typedef GrEffect INHERITED; | |
| 794 }; | |
| 795 | |
| 796 /** | |
| 797 * Shader is based off of Loop-Blinn Quadratic GPU Rendering | |
| 798 * The output of this effect is a hairline edge for conics. | |
| 799 * Conics specified by implicit equation K^2 - LM. | |
| 800 * K, L, and M, are the first three values of the vertex attribute, | |
| 801 * the fourth value is not used. Distance is calculated using a | |
| 802 * first order approximation from the taylor series. | |
| 803 * Coverage is max(0, 1-distance). | |
| 804 */ | |
| 805 | |
| 806 /** | |
| 807 * Test were also run using a second order distance approximation. | |
| 808 * There were two versions of the second order approx. The first version | |
| 809 * is of roughly the form: | |
| 810 * f(q) = |f(p)| - ||f'(p)||*||q-p|| - ||f''(p)||*||q-p||^2. | |
| 811 * The second is similar: | |
| 812 * f(q) = |f(p)| + ||f'(p)||*||q-p|| + ||f''(p)||*||q-p||^2. | |
| 813 * The exact version of the equations can be found in the paper | |
| 814 * "Distance Approximations for Rasterizing Implicit Curves" by Gabriel Taubin | |
| 815 * | |
| 816 * In both versions we solve the quadratic for ||q-p||. | |
| 817 * Version 1: | |
| 818 * gFM is magnitude of first partials and gFM2 is magnitude of 2nd partials (as
derived from paper) | |
| 819 * builder->fsCodeAppend("\t\tedgeAlpha = (sqrt(gFM*gFM+4.0*func*gF2M) - gFM)/(2
.0*gF2M);\n"); | |
| 820 * Version 2: | |
| 821 * builder->fsCodeAppend("\t\tedgeAlpha = (gFM - sqrt(gFM*gFM-4.0*func*gF2M))/(2
.0*gF2M);\n"); | |
| 822 * | |
| 823 * Also note that 2nd partials of k,l,m are zero | |
| 824 * | |
| 825 * When comparing the two second order approximations to the first order approxi
mations, | |
| 826 * the following results were found. Version 1 tends to underestimate the distan
ces, thus it | |
| 827 * basically increases all the error that we were already seeing in the first or
der | |
| 828 * approx. So this version is not the one to use. Version 2 has the opposite eff
ect | |
| 829 * and tends to overestimate the distances. This is much closer to what we are | |
| 830 * looking for. It is able to render ellipses (even thin ones) without the need
to chop. | |
| 831 * However, it can not handle thin hyperbolas well and thus would still rely on | |
| 832 * chopping to tighten the clipping. Another side effect of the overestimating i
s | |
| 833 * that the curves become much thinner and "ropey". If all that was ever rendere
d | |
| 834 * were "not too thin" curves and ellipses then 2nd order may have an advantage
since | |
| 835 * only one geometry would need to be rendered. However no benches were run comp
aring | |
| 836 * chopped first order and non chopped 2nd order. | |
| 837 */ | |
| 838 class HairConicEdgeEffect : public GrEffect { | |
| 839 public: | |
| 840 static GrEffectRef* Create() { | |
| 841 GR_CREATE_STATIC_EFFECT(gHairConicEdgeEffect, HairConicEdgeEffect, ()); | |
| 842 gHairConicEdgeEffect->ref(); | |
| 843 return gHairConicEdgeEffect; | |
| 844 } | |
| 845 | |
| 846 virtual ~HairConicEdgeEffect() {} | |
| 847 | |
| 848 static const char* Name() { return "HairConicEdge"; } | |
| 849 | |
| 850 virtual void getConstantColorComponents(GrColor* color, | |
| 851 uint32_t* validFlags) const SK_OVERR
IDE { | |
| 852 *validFlags = 0; | |
| 853 } | |
| 854 | |
| 855 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { | |
| 856 return GrTBackendEffectFactory<HairConicEdgeEffect>::getInstance(); | |
| 857 } | |
| 858 | |
| 859 class GLEffect : public GrGLEffect { | |
| 860 public: | |
| 861 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) | |
| 862 : INHERITED (factory) {} | |
| 863 | |
| 864 virtual void emitCode(GrGLShaderBuilder* builder, | |
| 865 const GrDrawEffect& drawEffect, | |
| 866 EffectKey key, | |
| 867 const char* outputColor, | |
| 868 const char* inputColor, | |
| 869 const TextureSamplerArray& samplers) SK_OVERRIDE { | |
| 870 const char *vsName, *fsName; | |
| 871 | |
| 872 SkAssertResult(builder->enableFeature( | |
| 873 GrGLShaderBuilder::kStandardDerivatives_GLSLFeature)); | |
| 874 builder->addVarying(kVec4f_GrSLType, "ConicCoeffs", | |
| 875 &vsName, &fsName); | |
| 876 const SkString* attr0Name = | |
| 877 builder->getEffectAttributeName(drawEffect.getVertexAttribIndice
s()[0]); | |
| 878 builder->vsCodeAppendf("\t%s = %s;\n", vsName, attr0Name->c_str()); | |
| 879 | |
| 880 builder->fsCodeAppend("\t\tfloat edgeAlpha;\n"); | |
| 881 | |
| 882 builder->fsCodeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName); | |
| 883 builder->fsCodeAppendf("\t\tvec3 dklmdy = dFdy(%s.xyz);\n", fsName); | |
| 884 builder->fsCodeAppendf("\t\tfloat dfdx =\n" | |
| 885 "\t\t\t2.0*%s.x*dklmdx.x - %s.y*dklmdx.z - %s
.z*dklmdx.y;\n", | |
| 886 fsName, fsName, fsName); | |
| 887 builder->fsCodeAppendf("\t\tfloat dfdy =\n" | |
| 888 "\t\t\t2.0*%s.x*dklmdy.x - %s.y*dklmdy.z - %s
.z*dklmdy.y;\n", | |
| 889 fsName, fsName, fsName); | |
| 890 builder->fsCodeAppend("\t\tvec2 gF = vec2(dfdx, dfdy);\n"); | |
| 891 builder->fsCodeAppend("\t\tfloat gFM = sqrt(dot(gF, gF));\n"); | |
| 892 builder->fsCodeAppendf("\t\tfloat func = abs(%s.x*%s.x - %s.y*%s.z);
\n", fsName, fsName, | |
| 893 fsName, fsName); | |
| 894 builder->fsCodeAppend("\t\tedgeAlpha = func / gFM;\n"); | |
| 895 builder->fsCodeAppend("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n"
); | |
| 896 // Add line below for smooth cubic ramp | |
| 897 // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2
.0*edgeAlpha);\n"); | |
| 898 | |
| 899 SkString modulate; | |
| 900 GrGLSLModulatef<4>(&modulate, inputColor, "edgeAlpha"); | |
| 901 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str()
); | |
| 902 } | |
| 903 | |
| 904 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrG
LCaps&) { | |
| 905 return 0x0; | |
| 906 } | |
| 907 | |
| 908 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_
OVERRIDE {} | |
| 909 | |
| 910 private: | |
| 911 typedef GrGLEffect INHERITED; | |
| 912 }; | |
| 913 | |
| 914 private: | |
| 915 HairConicEdgeEffect() { | |
| 916 this->addVertexAttrib(kVec4f_GrSLType); | |
| 917 } | |
| 918 | |
| 919 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { | |
| 920 return true; | |
| 921 } | |
| 922 | |
| 923 GR_DECLARE_EFFECT_TEST; | |
| 924 | |
| 925 typedef GrEffect INHERITED; | |
| 926 }; | |
| 927 | |
| 928 GR_DEFINE_EFFECT_TEST(HairConicEdgeEffect); | |
| 929 | |
| 930 GrEffectRef* HairConicEdgeEffect::TestCreate(SkMWCRandom* random, | |
| 931 GrContext*, | |
| 932 const GrDrawTargetCaps& caps, | |
| 933 GrTexture*[]) { | |
| 934 return caps.shaderDerivativeSupport() ? HairConicEdgeEffect::Create() : NULL
; | |
| 935 } | |
| 936 | |
| 937 /** | |
| 938 * The output of this effect is a hairline edge for quadratics. | |
| 939 * Quadratic specified by 0=u^2-v canonical coords. u and v are the first | |
| 940 * two components of the vertex attribute. Uses unsigned distance. | |
| 941 * Coverage is min(0, 1-distance). 3rd & 4th component unused. | |
| 942 * Requires shader derivative instruction support. | |
| 943 */ | |
| 944 class HairQuadEdgeEffect : public GrEffect { | |
| 945 public: | |
| 946 | |
| 947 static GrEffectRef* Create() { | |
| 948 GR_CREATE_STATIC_EFFECT(gHairQuadEdgeEffect, HairQuadEdgeEffect, ()); | |
| 949 gHairQuadEdgeEffect->ref(); | |
| 950 return gHairQuadEdgeEffect; | |
| 951 } | |
| 952 | |
| 953 virtual ~HairQuadEdgeEffect() {} | |
| 954 | |
| 955 static const char* Name() { return "HairQuadEdge"; } | |
| 956 | |
| 957 virtual void getConstantColorComponents(GrColor* color, | |
| 958 uint32_t* validFlags) const SK_OVERR
IDE { | |
| 959 *validFlags = 0; | |
| 960 } | |
| 961 | |
| 962 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { | |
| 963 return GrTBackendEffectFactory<HairQuadEdgeEffect>::getInstance(); | |
| 964 } | |
| 965 | |
| 966 class GLEffect : public GrGLEffect { | |
| 967 public: | |
| 968 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) | |
| 969 : INHERITED (factory) {} | |
| 970 | |
| 971 virtual void emitCode(GrGLShaderBuilder* builder, | |
| 972 const GrDrawEffect& drawEffect, | |
| 973 EffectKey key, | |
| 974 const char* outputColor, | |
| 975 const char* inputColor, | |
| 976 const TextureSamplerArray& samplers) SK_OVERRIDE { | |
| 977 const char *vsName, *fsName; | |
| 978 const SkString* attrName = | |
| 979 builder->getEffectAttributeName(drawEffect.getVertexAttribIndice
s()[0]); | |
| 980 builder->fsCodeAppendf("\t\tfloat edgeAlpha;\n"); | |
| 981 | |
| 982 SkAssertResult(builder->enableFeature( | |
| 983 GrGLShaderBuilder::kStandardDerivatives_GLSLFeature)); | |
| 984 builder->addVarying(kVec4f_GrSLType, "HairQuadEdge", &vsName, &fsNam
e); | |
| 985 | |
| 986 builder->fsCodeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName); | |
| 987 builder->fsCodeAppendf("\t\tvec2 duvdy = dFdy(%s.xy);\n", fsName); | |
| 988 builder->fsCodeAppendf("\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.
y,\n" | |
| 989 "\t\t 2.0*%s.x*duvdy.x - duvdy.
y);\n", | |
| 990 fsName, fsName); | |
| 991 builder->fsCodeAppendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsNa
me, fsName, | |
| 992 fsName); | |
| 993 builder->fsCodeAppend("\t\tedgeAlpha = sqrt(edgeAlpha*edgeAlpha / do
t(gF, gF));\n"); | |
| 994 builder->fsCodeAppend("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n"
); | |
| 995 | |
| 996 SkString modulate; | |
| 997 GrGLSLModulatef<4>(&modulate, inputColor, "edgeAlpha"); | |
| 998 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str()
); | |
| 999 | |
| 1000 builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str()); | |
| 1001 } | |
| 1002 | |
| 1003 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrG
LCaps&) { | |
| 1004 return 0x0; | |
| 1005 } | |
| 1006 | |
| 1007 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_
OVERRIDE {} | |
| 1008 | |
| 1009 private: | |
| 1010 typedef GrGLEffect INHERITED; | |
| 1011 }; | |
| 1012 | |
| 1013 private: | |
| 1014 HairQuadEdgeEffect() { | |
| 1015 this->addVertexAttrib(kVec4f_GrSLType); | |
| 1016 } | |
| 1017 | |
| 1018 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { | |
| 1019 return true; | |
| 1020 } | |
| 1021 | |
| 1022 GR_DECLARE_EFFECT_TEST; | |
| 1023 | |
| 1024 typedef GrEffect INHERITED; | |
| 1025 }; | |
| 1026 | |
| 1027 GR_DEFINE_EFFECT_TEST(HairQuadEdgeEffect); | |
| 1028 | |
| 1029 GrEffectRef* HairQuadEdgeEffect::TestCreate(SkMWCRandom* random, | |
| 1030 GrContext*, | |
| 1031 const GrDrawTargetCaps& caps, | |
| 1032 GrTexture*[]) { | |
| 1033 // Doesn't work without derivative instructions. | |
| 1034 return caps.shaderDerivativeSupport() ? HairQuadEdgeEffect::Create() : NULL; | |
| 1035 } | |
| 1036 | |
| 1037 /////////////////////////////////////////////////////////////////////////////// | 696 /////////////////////////////////////////////////////////////////////////////// |
| 1038 | 697 |
| 1039 namespace { | 698 namespace { |
| 1040 | 699 |
| 1041 // position + edge | 700 // position + edge |
| 1042 extern const GrVertexAttrib gHairlineBezierAttribs[] = { | 701 extern const GrVertexAttrib gHairlineBezierAttribs[] = { |
| 1043 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBind
ing}, | 702 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBind
ing}, |
| 1044 {kVec4f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBindin
g} | 703 {kVec4f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBindin
g} |
| 1045 }; | 704 }; |
| 1046 | 705 |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1290 // perspective. | 949 // perspective. |
| 1291 if (target->getDrawState().getViewMatrix().hasPerspective()) { | 950 if (target->getDrawState().getViewMatrix().hasPerspective()) { |
| 1292 asr.set(target, GrDrawTarget::kPreserve_ASRInit); | 951 asr.set(target, GrDrawTarget::kPreserve_ASRInit); |
| 1293 } else if (!asr.setIdentity(target, GrDrawTarget::kPreserve_ASRInit)) { | 952 } else if (!asr.setIdentity(target, GrDrawTarget::kPreserve_ASRInit)) { |
| 1294 return false; | 953 return false; |
| 1295 } | 954 } |
| 1296 GrDrawState* drawState = target->drawState(); | 955 GrDrawState* drawState = target->drawState(); |
| 1297 | 956 |
| 1298 static const int kEdgeAttrIndex = 1; | 957 static const int kEdgeAttrIndex = 1; |
| 1299 | 958 |
| 1300 GrEffectRef* hairQuadEffect = HairQuadEdgeEffect::Create(); | 959 GrEffectRef* hairQuadEffect = GrQuadEffect::Create(kHairAA_BezierEffectT
ype); |
| 1301 GrEffectRef* hairConicEffect = HairConicEdgeEffect::Create(); | 960 GrEffectRef* hairConicEffect = GrConicEffect::Create(kHairAA_BezierEffec
tType); |
| 1302 | 961 |
| 1303 // Check devBounds | 962 // Check devBounds |
| 1304 SkASSERT(check_bounds<BezierVertex>(drawState, devBounds, arg.vertices()
, | 963 SkASSERT(check_bounds<BezierVertex>(drawState, devBounds, arg.vertices()
, |
| 1305 kVertsPerQuad * quadCnt + kVertsPerQ
uad * conicCnt)); | 964 kVertsPerQuad * quadCnt + kVertsPerQ
uad * conicCnt)); |
| 1306 | 965 |
| 1307 { | 966 { |
| 1308 GrDrawState::AutoRestoreEffects are(drawState); | 967 GrDrawState::AutoRestoreEffects are(drawState); |
| 1309 target->setIndexSourceToBuffer(fQuadsIndexBuffer); | 968 target->setIndexSourceToBuffer(fQuadsIndexBuffer); |
| 1310 int quads = 0; | 969 int quads = 0; |
| 1311 drawState->addCoverageEffect(hairQuadEffect, kEdgeAttrIndex)->unref(
); | 970 drawState->addCoverageEffect(hairQuadEffect, kEdgeAttrIndex)->unref(
); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1335 &devBounds); | 994 &devBounds); |
| 1336 conics += n; | 995 conics += n; |
| 1337 } | 996 } |
| 1338 } | 997 } |
| 1339 } | 998 } |
| 1340 | 999 |
| 1341 target->resetIndexSource(); | 1000 target->resetIndexSource(); |
| 1342 | 1001 |
| 1343 return true; | 1002 return true; |
| 1344 } | 1003 } |
| OLD | NEW |