OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 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 "GrOvalRenderer.h" | 8 #include "GrOvalRenderer.h" |
9 | 9 |
10 #include "GrEffect.h" | 10 #include "GrEffect.h" |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 | 54 |
55 /////////////////////////////////////////////////////////////////////////////// | 55 /////////////////////////////////////////////////////////////////////////////// |
56 | 56 |
57 /** | 57 /** |
58 * The output of this effect is a modulation of the input color and coverage for
a circle, | 58 * The output of this effect is a modulation of the input color and coverage for
a circle, |
59 * specified as offset_x, offset_y (both from center point), outer radius and in
ner radius. | 59 * specified as offset_x, offset_y (both from center point), outer radius and in
ner radius. |
60 */ | 60 */ |
61 | 61 |
62 class CircleEdgeEffect : public GrVertexEffect { | 62 class CircleEdgeEffect : public GrVertexEffect { |
63 public: | 63 public: |
64 static GrEffectRef* Create(bool stroke) { | 64 static GrEffect* Create(bool stroke) { |
65 GR_CREATE_STATIC_EFFECT(gCircleStrokeEdge, CircleEdgeEffect, (true)); | 65 GR_CREATE_STATIC_EFFECT(gCircleStrokeEdge, CircleEdgeEffect, (true)); |
66 GR_CREATE_STATIC_EFFECT(gCircleFillEdge, CircleEdgeEffect, (false)); | 66 GR_CREATE_STATIC_EFFECT(gCircleFillEdge, CircleEdgeEffect, (false)); |
67 | 67 |
68 if (stroke) { | 68 if (stroke) { |
69 gCircleStrokeEdge->ref(); | 69 gCircleStrokeEdge->ref(); |
70 return gCircleStrokeEdge; | 70 return gCircleStrokeEdge; |
71 } else { | 71 } else { |
72 gCircleFillEdge->ref(); | 72 gCircleFillEdge->ref(); |
73 return gCircleFillEdge; | 73 return gCircleFillEdge; |
74 } | 74 } |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 | 146 |
147 bool fStroke; | 147 bool fStroke; |
148 | 148 |
149 GR_DECLARE_EFFECT_TEST; | 149 GR_DECLARE_EFFECT_TEST; |
150 | 150 |
151 typedef GrVertexEffect INHERITED; | 151 typedef GrVertexEffect INHERITED; |
152 }; | 152 }; |
153 | 153 |
154 GR_DEFINE_EFFECT_TEST(CircleEdgeEffect); | 154 GR_DEFINE_EFFECT_TEST(CircleEdgeEffect); |
155 | 155 |
156 GrEffectRef* CircleEdgeEffect::TestCreate(SkRandom* random, | 156 GrEffect* CircleEdgeEffect::TestCreate(SkRandom* random, |
157 GrContext* context, | 157 GrContext* context, |
158 const GrDrawTargetCaps&, | 158 const GrDrawTargetCaps&, |
159 GrTexture* textures[]) { | 159 GrTexture* textures[]) { |
160 return CircleEdgeEffect::Create(random->nextBool()); | 160 return CircleEdgeEffect::Create(random->nextBool()); |
161 } | 161 } |
162 | 162 |
163 /////////////////////////////////////////////////////////////////////////////// | 163 /////////////////////////////////////////////////////////////////////////////// |
164 | 164 |
165 /** | 165 /** |
166 * The output of this effect is a modulation of the input color and coverage for
an axis-aligned | 166 * The output of this effect is a modulation of the input color and coverage for
an axis-aligned |
167 * ellipse, specified as a 2D offset from center, and the reciprocals of the out
er and inner radii, | 167 * ellipse, specified as a 2D offset from center, and the reciprocals of the out
er and inner radii, |
168 * in both x and y directions. | 168 * in both x and y directions. |
169 * | 169 * |
170 * We are using an implicit function of x^2/a^2 + y^2/b^2 - 1 = 0. | 170 * We are using an implicit function of x^2/a^2 + y^2/b^2 - 1 = 0. |
171 */ | 171 */ |
172 | 172 |
173 class EllipseEdgeEffect : public GrVertexEffect { | 173 class EllipseEdgeEffect : public GrVertexEffect { |
174 public: | 174 public: |
175 static GrEffectRef* Create(bool stroke) { | 175 static GrEffect* Create(bool stroke) { |
176 GR_CREATE_STATIC_EFFECT(gEllipseStrokeEdge, EllipseEdgeEffect, (true)); | 176 GR_CREATE_STATIC_EFFECT(gEllipseStrokeEdge, EllipseEdgeEffect, (true)); |
177 GR_CREATE_STATIC_EFFECT(gEllipseFillEdge, EllipseEdgeEffect, (false)); | 177 GR_CREATE_STATIC_EFFECT(gEllipseFillEdge, EllipseEdgeEffect, (false)); |
178 | 178 |
179 if (stroke) { | 179 if (stroke) { |
180 gEllipseStrokeEdge->ref(); | 180 gEllipseStrokeEdge->ref(); |
181 return gEllipseStrokeEdge; | 181 return gEllipseStrokeEdge; |
182 } else { | 182 } else { |
183 gEllipseFillEdge->ref(); | 183 gEllipseFillEdge->ref(); |
184 return gEllipseFillEdge; | 184 return gEllipseFillEdge; |
185 } | 185 } |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 | 277 |
278 bool fStroke; | 278 bool fStroke; |
279 | 279 |
280 GR_DECLARE_EFFECT_TEST; | 280 GR_DECLARE_EFFECT_TEST; |
281 | 281 |
282 typedef GrVertexEffect INHERITED; | 282 typedef GrVertexEffect INHERITED; |
283 }; | 283 }; |
284 | 284 |
285 GR_DEFINE_EFFECT_TEST(EllipseEdgeEffect); | 285 GR_DEFINE_EFFECT_TEST(EllipseEdgeEffect); |
286 | 286 |
287 GrEffectRef* EllipseEdgeEffect::TestCreate(SkRandom* random, | 287 GrEffect* EllipseEdgeEffect::TestCreate(SkRandom* random, |
288 GrContext* context, | 288 GrContext* context, |
289 const GrDrawTargetCaps&, | 289 const GrDrawTargetCaps&, |
290 GrTexture* textures[]) { | 290 GrTexture* textures[]) { |
291 return EllipseEdgeEffect::Create(random->nextBool()); | 291 return EllipseEdgeEffect::Create(random->nextBool()); |
292 } | 292 } |
293 | 293 |
294 /////////////////////////////////////////////////////////////////////////////// | 294 /////////////////////////////////////////////////////////////////////////////// |
295 | 295 |
296 /** | 296 /** |
297 * The output of this effect is a modulation of the input color and coverage for
an ellipse, | 297 * The output of this effect is a modulation of the input color and coverage for
an ellipse, |
298 * specified as a 2D offset from center for both the outer and inner paths (if s
troked). The | 298 * specified as a 2D offset from center for both the outer and inner paths (if s
troked). The |
299 * implict equation used is for a unit circle (x^2 + y^2 - 1 = 0) and the edge c
orrected by | 299 * implict equation used is for a unit circle (x^2 + y^2 - 1 = 0) and the edge c
orrected by |
300 * using differentials. | 300 * using differentials. |
301 * | 301 * |
302 * The result is device-independent and can be used with any affine matrix. | 302 * The result is device-independent and can be used with any affine matrix. |
303 */ | 303 */ |
304 | 304 |
305 class DIEllipseEdgeEffect : public GrVertexEffect { | 305 class DIEllipseEdgeEffect : public GrVertexEffect { |
306 public: | 306 public: |
307 enum Mode { kStroke = 0, kHairline, kFill }; | 307 enum Mode { kStroke = 0, kHairline, kFill }; |
308 | 308 |
309 static GrEffectRef* Create(Mode mode) { | 309 static GrEffect* Create(Mode mode) { |
310 GR_CREATE_STATIC_EFFECT(gEllipseStrokeEdge, DIEllipseEdgeEffect, (kStrok
e)); | 310 GR_CREATE_STATIC_EFFECT(gEllipseStrokeEdge, DIEllipseEdgeEffect, (kStrok
e)); |
311 GR_CREATE_STATIC_EFFECT(gEllipseHairlineEdge, DIEllipseEdgeEffect, (kHai
rline)); | 311 GR_CREATE_STATIC_EFFECT(gEllipseHairlineEdge, DIEllipseEdgeEffect, (kHai
rline)); |
312 GR_CREATE_STATIC_EFFECT(gEllipseFillEdge, DIEllipseEdgeEffect, (kFill)); | 312 GR_CREATE_STATIC_EFFECT(gEllipseFillEdge, DIEllipseEdgeEffect, (kFill)); |
313 | 313 |
314 if (kStroke == mode) { | 314 if (kStroke == mode) { |
315 gEllipseStrokeEdge->ref(); | 315 gEllipseStrokeEdge->ref(); |
316 return gEllipseStrokeEdge; | 316 return gEllipseStrokeEdge; |
317 } else if (kHairline == mode) { | 317 } else if (kHairline == mode) { |
318 gEllipseHairlineEdge->ref(); | 318 gEllipseHairlineEdge->ref(); |
319 return gEllipseHairlineEdge; | 319 return gEllipseHairlineEdge; |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 | 433 |
434 Mode fMode; | 434 Mode fMode; |
435 | 435 |
436 GR_DECLARE_EFFECT_TEST; | 436 GR_DECLARE_EFFECT_TEST; |
437 | 437 |
438 typedef GrVertexEffect INHERITED; | 438 typedef GrVertexEffect INHERITED; |
439 }; | 439 }; |
440 | 440 |
441 GR_DEFINE_EFFECT_TEST(DIEllipseEdgeEffect); | 441 GR_DEFINE_EFFECT_TEST(DIEllipseEdgeEffect); |
442 | 442 |
443 GrEffectRef* DIEllipseEdgeEffect::TestCreate(SkRandom* random, | 443 GrEffect* DIEllipseEdgeEffect::TestCreate(SkRandom* random, |
444 GrContext* context, | 444 GrContext* context, |
445 const GrDrawTargetCaps&, | 445 const GrDrawTargetCaps&, |
446 GrTexture* textures[]) { | 446 GrTexture* textures[]) { |
447 return DIEllipseEdgeEffect::Create((Mode)(random->nextRangeU(0,2))); | 447 return DIEllipseEdgeEffect::Create((Mode)(random->nextRangeU(0,2))); |
448 } | 448 } |
449 | 449 |
450 /////////////////////////////////////////////////////////////////////////////// | 450 /////////////////////////////////////////////////////////////////////////////// |
451 | 451 |
452 void GrOvalRenderer::reset() { | 452 void GrOvalRenderer::reset() { |
453 SkSafeSetNull(fRRectIndexBuffer); | 453 SkSafeSetNull(fRRectIndexBuffer); |
454 } | 454 } |
455 | 455 |
456 bool GrOvalRenderer::drawOval(GrDrawTarget* target, const GrContext* context, bo
ol useAA, | 456 bool GrOvalRenderer::drawOval(GrDrawTarget* target, const GrContext* context, bo
ol useAA, |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
534 } else { | 534 } else { |
535 halfWidth = SkScalarHalf(strokeWidth); | 535 halfWidth = SkScalarHalf(strokeWidth); |
536 } | 536 } |
537 | 537 |
538 outerRadius += halfWidth; | 538 outerRadius += halfWidth; |
539 if (isStrokeOnly) { | 539 if (isStrokeOnly) { |
540 innerRadius = radius - halfWidth; | 540 innerRadius = radius - halfWidth; |
541 } | 541 } |
542 } | 542 } |
543 | 543 |
544 GrEffectRef* effect = CircleEdgeEffect::Create(isStrokeOnly && innerRadius >
0); | 544 GrEffect* effect = CircleEdgeEffect::Create(isStrokeOnly && innerRadius > 0)
; |
545 static const int kCircleEdgeAttrIndex = 1; | 545 static const int kCircleEdgeAttrIndex = 1; |
546 drawState->addCoverageEffect(effect, kCircleEdgeAttrIndex)->unref(); | 546 drawState->addCoverageEffect(effect, kCircleEdgeAttrIndex)->unref(); |
547 | 547 |
548 // The radii are outset for two reasons. First, it allows the shader to simp
ly perform | 548 // The radii are outset for two reasons. First, it allows the shader to simp
ly perform |
549 // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is use
d to compute the | 549 // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is use
d to compute the |
550 // verts of the bounding box that is rendered and the outset ensures the box
will cover all | 550 // verts of the bounding box that is rendered and the outset ensures the box
will cover all |
551 // pixels partially covered by the circle. | 551 // pixels partially covered by the circle. |
552 outerRadius += SK_ScalarHalf; | 552 outerRadius += SK_ScalarHalf; |
553 innerRadius -= SK_ScalarHalf; | 553 innerRadius -= SK_ScalarHalf; |
554 | 554 |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
674 SkASSERT(sizeof(EllipseVertex) == drawState->getVertexSize()); | 674 SkASSERT(sizeof(EllipseVertex) == drawState->getVertexSize()); |
675 | 675 |
676 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); | 676 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); |
677 if (!geo.succeeded()) { | 677 if (!geo.succeeded()) { |
678 GrPrintf("Failed to get space for vertices!\n"); | 678 GrPrintf("Failed to get space for vertices!\n"); |
679 return false; | 679 return false; |
680 } | 680 } |
681 | 681 |
682 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); | 682 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); |
683 | 683 |
684 GrEffectRef* effect = EllipseEdgeEffect::Create(isStrokeOnly && | 684 GrEffect* effect = EllipseEdgeEffect::Create(isStrokeOnly && |
685 innerXRadius > 0 && innerYRa
dius > 0); | 685 innerXRadius > 0 && innerYRadiu
s > 0); |
686 | 686 |
687 static const int kEllipseCenterAttrIndex = 1; | 687 static const int kEllipseCenterAttrIndex = 1; |
688 static const int kEllipseEdgeAttrIndex = 2; | 688 static const int kEllipseEdgeAttrIndex = 2; |
689 drawState->addCoverageEffect(effect, kEllipseCenterAttrIndex, kEllipseEdgeAt
trIndex)->unref(); | 689 drawState->addCoverageEffect(effect, kEllipseCenterAttrIndex, kEllipseEdgeAt
trIndex)->unref(); |
690 | 690 |
691 // Compute the reciprocals of the radii here to save time in the shader | 691 // Compute the reciprocals of the radii here to save time in the shader |
692 SkScalar xRadRecip = SkScalarInvert(xRadius); | 692 SkScalar xRadRecip = SkScalarInvert(xRadius); |
693 SkScalar yRadRecip = SkScalarInvert(yRadius); | 693 SkScalar yRadRecip = SkScalarInvert(yRadius); |
694 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius); | 694 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius); |
695 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius); | 695 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
793 SkASSERT(sizeof(DIEllipseVertex) == drawState->getVertexSize()); | 793 SkASSERT(sizeof(DIEllipseVertex) == drawState->getVertexSize()); |
794 | 794 |
795 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); | 795 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); |
796 if (!geo.succeeded()) { | 796 if (!geo.succeeded()) { |
797 GrPrintf("Failed to get space for vertices!\n"); | 797 GrPrintf("Failed to get space for vertices!\n"); |
798 return false; | 798 return false; |
799 } | 799 } |
800 | 800 |
801 DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(geo.vertices()); | 801 DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(geo.vertices()); |
802 | 802 |
803 GrEffectRef* effect = DIEllipseEdgeEffect::Create(mode); | 803 GrEffect* effect = DIEllipseEdgeEffect::Create(mode); |
804 | 804 |
805 static const int kEllipseOuterOffsetAttrIndex = 1; | 805 static const int kEllipseOuterOffsetAttrIndex = 1; |
806 static const int kEllipseInnerOffsetAttrIndex = 2; | 806 static const int kEllipseInnerOffsetAttrIndex = 2; |
807 drawState->addCoverageEffect(effect, kEllipseOuterOffsetAttrIndex, | 807 drawState->addCoverageEffect(effect, kEllipseOuterOffsetAttrIndex, |
808 kEllipseInnerOffsetAttrIndex)->unref(); | 808 kEllipseInnerOffsetAttrIndex)->unref(); |
809 | 809 |
810 // This expands the outer rect so that after CTM we end up with a half-pixel
border | 810 // This expands the outer rect so that after CTM we end up with a half-pixel
border |
811 SkScalar a = vm[SkMatrix::kMScaleX]; | 811 SkScalar a = vm[SkMatrix::kMScaleX]; |
812 SkScalar b = vm[SkMatrix::kMSkewX]; | 812 SkScalar b = vm[SkMatrix::kMSkewX]; |
813 SkScalar c = vm[SkMatrix::kMSkewY]; | 813 SkScalar c = vm[SkMatrix::kMSkewY]; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
891 GrDrawState::AutoRestoreEffects are; | 891 GrDrawState::AutoRestoreEffects are; |
892 if (!origInner.isEmpty()) { | 892 if (!origInner.isEmpty()) { |
893 SkTCopyOnFirstWrite<SkRRect> inner(origInner); | 893 SkTCopyOnFirstWrite<SkRRect> inner(origInner); |
894 if (!context->getMatrix().isIdentity()) { | 894 if (!context->getMatrix().isIdentity()) { |
895 if (!origInner.transform(context->getMatrix(), inner.writable())) { | 895 if (!origInner.transform(context->getMatrix(), inner.writable())) { |
896 return false; | 896 return false; |
897 } | 897 } |
898 } | 898 } |
899 GrEffectEdgeType edgeType = applyAA ? kInverseFillAA_GrEffectEdgeType : | 899 GrEffectEdgeType edgeType = applyAA ? kInverseFillAA_GrEffectEdgeType : |
900 kInverseFillBW_GrEffectEdgeType; | 900 kInverseFillBW_GrEffectEdgeType; |
901 GrEffectRef* effect = GrRRectEffect::Create(edgeType, *inner); | 901 GrEffect* effect = GrRRectEffect::Create(edgeType, *inner); |
902 if (NULL == effect) { | 902 if (NULL == effect) { |
903 return false; | 903 return false; |
904 } | 904 } |
905 are.set(target->drawState()); | 905 are.set(target->drawState()); |
906 target->drawState()->addCoverageEffect(effect)->unref(); | 906 target->drawState()->addCoverageEffect(effect)->unref(); |
907 } | 907 } |
908 | 908 |
909 SkStrokeRec fillRec(SkStrokeRec::kFill_InitStyle); | 909 SkStrokeRec fillRec(SkStrokeRec::kFill_InitStyle); |
910 if (this->drawRRect(target, context, useAA, origOuter, fillRec)) { | 910 if (this->drawRRect(target, context, useAA, origOuter, fillRec)) { |
911 return true; | 911 return true; |
912 } | 912 } |
913 | 913 |
914 SkASSERT(!origOuter.isEmpty()); | 914 SkASSERT(!origOuter.isEmpty()); |
915 SkTCopyOnFirstWrite<SkRRect> outer(origOuter); | 915 SkTCopyOnFirstWrite<SkRRect> outer(origOuter); |
916 if (!context->getMatrix().isIdentity()) { | 916 if (!context->getMatrix().isIdentity()) { |
917 if (!origOuter.transform(context->getMatrix(), outer.writable())) { | 917 if (!origOuter.transform(context->getMatrix(), outer.writable())) { |
918 return false; | 918 return false; |
919 } | 919 } |
920 } | 920 } |
921 GrEffectEdgeType edgeType = applyAA ? kFillAA_GrEffectEdgeType : | 921 GrEffectEdgeType edgeType = applyAA ? kFillAA_GrEffectEdgeType : |
922 kFillBW_GrEffectEdgeType; | 922 kFillBW_GrEffectEdgeType; |
923 GrEffectRef* effect = GrRRectEffect::Create(edgeType, *outer); | 923 GrEffect* effect = GrRRectEffect::Create(edgeType, *outer); |
924 if (NULL == effect) { | 924 if (NULL == effect) { |
925 return false; | 925 return false; |
926 } | 926 } |
927 if (!are.isSet()) { | 927 if (!are.isSet()) { |
928 are.set(target->drawState()); | 928 are.set(target->drawState()); |
929 } | 929 } |
930 GrDrawState::AutoViewMatrixRestore avmr; | 930 GrDrawState::AutoViewMatrixRestore avmr; |
931 if (!avmr.setIdentity(target->drawState())) { | 931 if (!avmr.setIdentity(target->drawState())) { |
932 return false; | 932 return false; |
933 } | 933 } |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1044 | 1044 |
1045 if (isStrokeOnly) { | 1045 if (isStrokeOnly) { |
1046 innerRadius = xRadius - halfWidth; | 1046 innerRadius = xRadius - halfWidth; |
1047 } | 1047 } |
1048 outerRadius += halfWidth; | 1048 outerRadius += halfWidth; |
1049 bounds.outset(halfWidth, halfWidth); | 1049 bounds.outset(halfWidth, halfWidth); |
1050 } | 1050 } |
1051 | 1051 |
1052 isStrokeOnly = (isStrokeOnly && innerRadius >= 0); | 1052 isStrokeOnly = (isStrokeOnly && innerRadius >= 0); |
1053 | 1053 |
1054 GrEffectRef* effect = CircleEdgeEffect::Create(isStrokeOnly); | 1054 GrEffect* effect = CircleEdgeEffect::Create(isStrokeOnly); |
1055 static const int kCircleEdgeAttrIndex = 1; | 1055 static const int kCircleEdgeAttrIndex = 1; |
1056 drawState->addCoverageEffect(effect, kCircleEdgeAttrIndex)->unref(); | 1056 drawState->addCoverageEffect(effect, kCircleEdgeAttrIndex)->unref(); |
1057 | 1057 |
1058 // The radii are outset for two reasons. First, it allows the shader to
simply perform | 1058 // The radii are outset for two reasons. First, it allows the shader to
simply perform |
1059 // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is
used to compute the | 1059 // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is
used to compute the |
1060 // verts of the bounding box that is rendered and the outset ensures the
box will cover all | 1060 // verts of the bounding box that is rendered and the outset ensures the
box will cover all |
1061 // pixels partially covered by the circle. | 1061 // pixels partially covered by the circle. |
1062 outerRadius += SK_ScalarHalf; | 1062 outerRadius += SK_ScalarHalf; |
1063 innerRadius -= SK_ScalarHalf; | 1063 innerRadius -= SK_ScalarHalf; |
1064 | 1064 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1148 | 1148 |
1149 isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0); | 1149 isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0); |
1150 | 1150 |
1151 GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0); | 1151 GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0); |
1152 if (!geo.succeeded()) { | 1152 if (!geo.succeeded()) { |
1153 GrPrintf("Failed to get space for vertices!\n"); | 1153 GrPrintf("Failed to get space for vertices!\n"); |
1154 return false; | 1154 return false; |
1155 } | 1155 } |
1156 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); | 1156 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); |
1157 | 1157 |
1158 GrEffectRef* effect = EllipseEdgeEffect::Create(isStrokeOnly); | 1158 GrEffect* effect = EllipseEdgeEffect::Create(isStrokeOnly); |
1159 static const int kEllipseOffsetAttrIndex = 1; | 1159 static const int kEllipseOffsetAttrIndex = 1; |
1160 static const int kEllipseRadiiAttrIndex = 2; | 1160 static const int kEllipseRadiiAttrIndex = 2; |
1161 drawState->addCoverageEffect(effect, | 1161 drawState->addCoverageEffect(effect, |
1162 kEllipseOffsetAttrIndex, kEllipseRadiiAttrI
ndex)->unref(); | 1162 kEllipseOffsetAttrIndex, kEllipseRadiiAttrI
ndex)->unref(); |
1163 | 1163 |
1164 // Compute the reciprocals of the radii here to save time in the shader | 1164 // Compute the reciprocals of the radii here to save time in the shader |
1165 SkScalar xRadRecip = SkScalarInvert(xRadius); | 1165 SkScalar xRadRecip = SkScalarInvert(xRadius); |
1166 SkScalar yRadRecip = SkScalarInvert(yRadius); | 1166 SkScalar yRadRecip = SkScalarInvert(yRadius); |
1167 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius); | 1167 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius); |
1168 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius); | 1168 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1215 | 1215 |
1216 // drop out the middle quad if we're stroked | 1216 // drop out the middle quad if we're stroked |
1217 int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 : | 1217 int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 : |
1218 SK_ARRAY_COUNT(gRRectIndices); | 1218 SK_ARRAY_COUNT(gRRectIndices); |
1219 target->setIndexSourceToBuffer(indexBuffer); | 1219 target->setIndexSourceToBuffer(indexBuffer); |
1220 target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 16, indexCnt, &bou
nds); | 1220 target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 16, indexCnt, &bou
nds); |
1221 } | 1221 } |
1222 | 1222 |
1223 return true; | 1223 return true; |
1224 } | 1224 } |
OLD | NEW |