| 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 |