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_GrBezierEdgeT
ype, |
1301 GrEffectRef* hairConicEffect = HairConicEdgeEffect::Create(); | 960 *target->caps()); |
1302 | 961 GrEffectRef* hairConicEffect = GrConicEffect::Create(kHairAA_GrBezierEdg
eType, |
| 962 *target->caps()); |
| 963 SkASSERT(hairQuadEffect && hairConicEffect); |
| 964 |
1303 // Check devBounds | 965 // Check devBounds |
1304 SkASSERT(check_bounds<BezierVertex>(drawState, devBounds, arg.vertices()
, | 966 SkASSERT(check_bounds<BezierVertex>(drawState, devBounds, arg.vertices()
, |
1305 kVertsPerQuad * quadCnt + kVertsPerQ
uad * conicCnt)); | 967 kVertsPerQuad * quadCnt + kVertsPerQ
uad * conicCnt)); |
1306 | 968 |
1307 { | 969 { |
1308 GrDrawState::AutoRestoreEffects are(drawState); | 970 GrDrawState::AutoRestoreEffects are(drawState); |
1309 target->setIndexSourceToBuffer(fQuadsIndexBuffer); | 971 target->setIndexSourceToBuffer(fQuadsIndexBuffer); |
1310 int quads = 0; | 972 int quads = 0; |
1311 drawState->addCoverageEffect(hairQuadEffect, kEdgeAttrIndex)->unref(
); | 973 drawState->addCoverageEffect(hairQuadEffect, kEdgeAttrIndex)->unref(
); |
1312 while (quads < quadCnt) { | 974 while (quads < quadCnt) { |
(...skipping 22 matching lines...) Expand all Loading... |
1335 &devBounds); | 997 &devBounds); |
1336 conics += n; | 998 conics += n; |
1337 } | 999 } |
1338 } | 1000 } |
1339 } | 1001 } |
1340 | 1002 |
1341 target->resetIndexSource(); | 1003 target->resetIndexSource(); |
1342 | 1004 |
1343 return true; | 1005 return true; |
1344 } | 1006 } |
OLD | NEW |