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 "GrProcessor.h" | 10 #include "GrProcessor.h" |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 * with origin at the circle center. Two vertex attributes are used: | 58 * with origin at the circle center. Two vertex attributes are used: |
59 * vec2f : position in device space of the bounding geometry vertices | 59 * vec2f : position in device space of the bounding geometry vertices |
60 * vec4f : (p.xy, outerRad, innerRad) | 60 * vec4f : (p.xy, outerRad, innerRad) |
61 * p is the position in the normalized space. | 61 * p is the position in the normalized space. |
62 * outerRad is the outerRadius in device space. | 62 * outerRad is the outerRadius in device space. |
63 * innerRad is the innerRadius in normalized space (ignored if not s
troking). | 63 * innerRad is the innerRadius in normalized space (ignored if not s
troking). |
64 */ | 64 */ |
65 | 65 |
66 class CircleEdgeEffect : public GrGeometryProcessor { | 66 class CircleEdgeEffect : public GrGeometryProcessor { |
67 public: | 67 public: |
68 static GrGeometryProcessor* Create(GrColor color, bool stroke) { | 68 static GrGeometryProcessor* Create(GrColor color, bool stroke, const SkMatri
x& localMatrix) { |
69 return SkNEW_ARGS(CircleEdgeEffect, (color, stroke)); | 69 return SkNEW_ARGS(CircleEdgeEffect, (color, stroke, localMatrix)); |
70 } | 70 } |
71 | 71 |
72 const GrAttribute* inPosition() const { return fInPosition; } | 72 const GrAttribute* inPosition() const { return fInPosition; } |
73 const GrAttribute* inCircleEdge() const { return fInCircleEdge; } | 73 const GrAttribute* inCircleEdge() const { return fInCircleEdge; } |
74 virtual ~CircleEdgeEffect() {} | 74 virtual ~CircleEdgeEffect() {} |
75 | 75 |
76 virtual const char* name() const SK_OVERRIDE { return "CircleEdge"; } | 76 virtual const char* name() const SK_OVERRIDE { return "CircleEdge"; } |
77 | 77 |
78 inline bool isStroked() const { return fStroke; } | 78 inline bool isStroked() const { return fStroke; } |
79 | 79 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 const GrBatchTracker& t) const SK_OVERRIDE { | 167 const GrBatchTracker& t) const SK_OVERRIDE { |
168 const BatchTracker& mine = m.cast<BatchTracker>(); | 168 const BatchTracker& mine = m.cast<BatchTracker>(); |
169 const BatchTracker& theirs = t.cast<BatchTracker>(); | 169 const BatchTracker& theirs = t.cast<BatchTracker>(); |
170 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords, | 170 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords, |
171 that, theirs.fUsesLocalCoords) && | 171 that, theirs.fUsesLocalCoords) && |
172 CanCombineOutput(mine.fInputColorType, mine.fColor, | 172 CanCombineOutput(mine.fInputColorType, mine.fColor, |
173 theirs.fInputColorType, theirs.fColor); | 173 theirs.fInputColorType, theirs.fColor); |
174 } | 174 } |
175 | 175 |
176 private: | 176 private: |
177 CircleEdgeEffect(GrColor color, bool stroke) : INHERITED(color) { | 177 CircleEdgeEffect(GrColor color, bool stroke, const SkMatrix& localMatrix) |
| 178 : INHERITED(color, false, localMatrix) { |
178 this->initClassID<CircleEdgeEffect>(); | 179 this->initClassID<CircleEdgeEffect>(); |
179 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_Gr
VertexAttribType)); | 180 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_Gr
VertexAttribType)); |
180 fInCircleEdge = &this->addVertexAttrib(GrAttribute("inCircleEdge", | 181 fInCircleEdge = &this->addVertexAttrib(GrAttribute("inCircleEdge", |
181 kVec4f_GrVertexAttrib
Type)); | 182 kVec4f_GrVertexAttrib
Type)); |
182 fStroke = stroke; | 183 fStroke = stroke; |
183 } | 184 } |
184 | 185 |
185 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE { | 186 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE { |
186 const CircleEdgeEffect& cee = other.cast<CircleEdgeEffect>(); | 187 const CircleEdgeEffect& cee = other.cast<CircleEdgeEffect>(); |
187 return cee.fStroke == fStroke; | 188 return cee.fStroke == fStroke; |
(...skipping 17 matching lines...) Expand all Loading... |
205 | 206 |
206 typedef GrGeometryProcessor INHERITED; | 207 typedef GrGeometryProcessor INHERITED; |
207 }; | 208 }; |
208 | 209 |
209 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(CircleEdgeEffect); | 210 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(CircleEdgeEffect); |
210 | 211 |
211 GrGeometryProcessor* CircleEdgeEffect::TestCreate(SkRandom* random, | 212 GrGeometryProcessor* CircleEdgeEffect::TestCreate(SkRandom* random, |
212 GrContext* context, | 213 GrContext* context, |
213 const GrDrawTargetCaps&, | 214 const GrDrawTargetCaps&, |
214 GrTexture* textures[]) { | 215 GrTexture* textures[]) { |
215 return CircleEdgeEffect::Create(GrRandomColor(random), random->nextBool()); | 216 return CircleEdgeEffect::Create(GrRandomColor(random), random->nextBool(), |
| 217 GrProcessorUnitTest::TestMatrix(random)); |
216 } | 218 } |
217 | 219 |
218 /////////////////////////////////////////////////////////////////////////////// | 220 /////////////////////////////////////////////////////////////////////////////// |
219 | 221 |
220 /** | 222 /** |
221 * The output of this effect is a modulation of the input color and coverage for
an axis-aligned | 223 * The output of this effect is a modulation of the input color and coverage for
an axis-aligned |
222 * ellipse, specified as a 2D offset from center, and the reciprocals of the out
er and inner radii, | 224 * ellipse, specified as a 2D offset from center, and the reciprocals of the out
er and inner radii, |
223 * in both x and y directions. | 225 * in both x and y directions. |
224 * | 226 * |
225 * We are using an implicit function of x^2/a^2 + y^2/b^2 - 1 = 0. | 227 * We are using an implicit function of x^2/a^2 + y^2/b^2 - 1 = 0. |
226 */ | 228 */ |
227 | 229 |
228 class EllipseEdgeEffect : public GrGeometryProcessor { | 230 class EllipseEdgeEffect : public GrGeometryProcessor { |
229 public: | 231 public: |
230 static GrGeometryProcessor* Create(GrColor color, bool stroke) { | 232 static GrGeometryProcessor* Create(GrColor color, bool stroke, const SkMatri
x& localMatrix) { |
231 return SkNEW_ARGS(EllipseEdgeEffect, (color, stroke)); | 233 return SkNEW_ARGS(EllipseEdgeEffect, (color, stroke, localMatrix)); |
232 } | 234 } |
233 | 235 |
234 virtual ~EllipseEdgeEffect() {} | 236 virtual ~EllipseEdgeEffect() {} |
235 | 237 |
236 virtual const char* name() const SK_OVERRIDE { return "EllipseEdge"; } | 238 virtual const char* name() const SK_OVERRIDE { return "EllipseEdge"; } |
237 | 239 |
238 const GrAttribute* inPosition() const { return fInPosition; } | 240 const GrAttribute* inPosition() const { return fInPosition; } |
239 const GrAttribute* inEllipseOffset() const { return fInEllipseOffset; } | 241 const GrAttribute* inEllipseOffset() const { return fInEllipseOffset; } |
240 const GrAttribute* inEllipseRadii() const { return fInEllipseRadii; } | 242 const GrAttribute* inEllipseRadii() const { return fInEllipseRadii; } |
241 | 243 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 const GrBatchTracker& t) const SK_OVERRIDE { | 355 const GrBatchTracker& t) const SK_OVERRIDE { |
354 const BatchTracker& mine = m.cast<BatchTracker>(); | 356 const BatchTracker& mine = m.cast<BatchTracker>(); |
355 const BatchTracker& theirs = t.cast<BatchTracker>(); | 357 const BatchTracker& theirs = t.cast<BatchTracker>(); |
356 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords, | 358 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords, |
357 that, theirs.fUsesLocalCoords) && | 359 that, theirs.fUsesLocalCoords) && |
358 CanCombineOutput(mine.fInputColorType, mine.fColor, | 360 CanCombineOutput(mine.fInputColorType, mine.fColor, |
359 theirs.fInputColorType, theirs.fColor); | 361 theirs.fInputColorType, theirs.fColor); |
360 } | 362 } |
361 | 363 |
362 private: | 364 private: |
363 EllipseEdgeEffect(GrColor color, bool stroke) : INHERITED(color) { | 365 EllipseEdgeEffect(GrColor color, bool stroke, const SkMatrix& localMatrix) |
| 366 : INHERITED(color, false, localMatrix) { |
364 this->initClassID<EllipseEdgeEffect>(); | 367 this->initClassID<EllipseEdgeEffect>(); |
365 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_Gr
VertexAttribType)); | 368 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_Gr
VertexAttribType)); |
366 fInEllipseOffset = &this->addVertexAttrib(GrAttribute("inEllipseOffset", | 369 fInEllipseOffset = &this->addVertexAttrib(GrAttribute("inEllipseOffset", |
367 kVec2f_GrVertexAtt
ribType)); | 370 kVec2f_GrVertexAtt
ribType)); |
368 fInEllipseRadii = &this->addVertexAttrib(GrAttribute("inEllipseRadii", | 371 fInEllipseRadii = &this->addVertexAttrib(GrAttribute("inEllipseRadii", |
369 kVec4f_GrVertexAttr
ibType)); | 372 kVec4f_GrVertexAttr
ibType)); |
370 fStroke = stroke; | 373 fStroke = stroke; |
371 } | 374 } |
372 | 375 |
373 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE { | 376 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE { |
(...skipping 20 matching lines...) Expand all Loading... |
394 | 397 |
395 typedef GrGeometryProcessor INHERITED; | 398 typedef GrGeometryProcessor INHERITED; |
396 }; | 399 }; |
397 | 400 |
398 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(EllipseEdgeEffect); | 401 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(EllipseEdgeEffect); |
399 | 402 |
400 GrGeometryProcessor* EllipseEdgeEffect::TestCreate(SkRandom* random, | 403 GrGeometryProcessor* EllipseEdgeEffect::TestCreate(SkRandom* random, |
401 GrContext* context, | 404 GrContext* context, |
402 const GrDrawTargetCaps&, | 405 const GrDrawTargetCaps&, |
403 GrTexture* textures[]) { | 406 GrTexture* textures[]) { |
404 return EllipseEdgeEffect::Create(GrRandomColor(random), random->nextBool()); | 407 return EllipseEdgeEffect::Create(GrRandomColor(random), random->nextBool(), |
| 408 GrProcessorUnitTest::TestMatrix(random)); |
405 } | 409 } |
406 | 410 |
407 /////////////////////////////////////////////////////////////////////////////// | 411 /////////////////////////////////////////////////////////////////////////////// |
408 | 412 |
409 /** | 413 /** |
410 * The output of this effect is a modulation of the input color and coverage for
an ellipse, | 414 * The output of this effect is a modulation of the input color and coverage for
an ellipse, |
411 * specified as a 2D offset from center for both the outer and inner paths (if s
troked). The | 415 * specified as a 2D offset from center for both the outer and inner paths (if s
troked). The |
412 * implict equation used is for a unit circle (x^2 + y^2 - 1 = 0) and the edge c
orrected by | 416 * implict equation used is for a unit circle (x^2 + y^2 - 1 = 0) and the edge c
orrected by |
413 * using differentials. | 417 * using differentials. |
414 * | 418 * |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
660 bool useCoverageAA, | 664 bool useCoverageAA, |
661 const SkRect& circle, | 665 const SkRect& circle, |
662 const SkStrokeRec& stroke) | 666 const SkStrokeRec& stroke) |
663 { | 667 { |
664 const SkMatrix& vm = drawState->getViewMatrix(); | 668 const SkMatrix& vm = drawState->getViewMatrix(); |
665 SkPoint center = SkPoint::Make(circle.centerX(), circle.centerY()); | 669 SkPoint center = SkPoint::Make(circle.centerX(), circle.centerY()); |
666 vm.mapPoints(¢er, 1); | 670 vm.mapPoints(¢er, 1); |
667 SkScalar radius = vm.mapRadius(SkScalarHalf(circle.width())); | 671 SkScalar radius = vm.mapRadius(SkScalarHalf(circle.width())); |
668 SkScalar strokeWidth = vm.mapRadius(stroke.getWidth()); | 672 SkScalar strokeWidth = vm.mapRadius(stroke.getWidth()); |
669 | 673 |
670 GrDrawState::AutoViewMatrixRestore avmr; | 674 SkMatrix invert; |
671 if (!avmr.setIdentity(drawState)) { | 675 if (!vm.invert(&invert)) { |
672 return; | 676 return; |
673 } | 677 } |
674 | 678 |
| 679 GrDrawState::AutoViewMatrixRestore avmr(drawState); |
| 680 |
675 SkStrokeRec::Style style = stroke.getStyle(); | 681 SkStrokeRec::Style style = stroke.getStyle(); |
676 bool isStrokeOnly = SkStrokeRec::kStroke_Style == style || | 682 bool isStrokeOnly = SkStrokeRec::kStroke_Style == style || |
677 SkStrokeRec::kHairline_Style == style; | 683 SkStrokeRec::kHairline_Style == style; |
678 bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == style; | 684 bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == style; |
679 | 685 |
680 SkScalar innerRadius = 0.0f; | 686 SkScalar innerRadius = 0.0f; |
681 SkScalar outerRadius = radius; | 687 SkScalar outerRadius = radius; |
682 SkScalar halfWidth = 0; | 688 SkScalar halfWidth = 0; |
683 if (hasStroke) { | 689 if (hasStroke) { |
684 if (SkScalarNearlyZero(strokeWidth)) { | 690 if (SkScalarNearlyZero(strokeWidth)) { |
685 halfWidth = SK_ScalarHalf; | 691 halfWidth = SK_ScalarHalf; |
686 } else { | 692 } else { |
687 halfWidth = SkScalarHalf(strokeWidth); | 693 halfWidth = SkScalarHalf(strokeWidth); |
688 } | 694 } |
689 | 695 |
690 outerRadius += halfWidth; | 696 outerRadius += halfWidth; |
691 if (isStrokeOnly) { | 697 if (isStrokeOnly) { |
692 innerRadius = radius - halfWidth; | 698 innerRadius = radius - halfWidth; |
693 } | 699 } |
694 } | 700 } |
695 | 701 |
696 SkAutoTUnref<GrGeometryProcessor> gp( | 702 SkAutoTUnref<GrGeometryProcessor> gp( |
697 CircleEdgeEffect::Create(color, isStrokeOnly && innerRadius > 0)); | 703 CircleEdgeEffect::Create(color, isStrokeOnly && innerRadius > 0, inv
ert)); |
698 | 704 |
699 GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0); | 705 GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0); |
700 SkASSERT(gp->getVertexStride() == sizeof(CircleVertex)); | 706 SkASSERT(gp->getVertexStride() == sizeof(CircleVertex)); |
701 if (!geo.succeeded()) { | 707 if (!geo.succeeded()) { |
702 SkDebugf("Failed to get space for vertices!\n"); | 708 SkDebugf("Failed to get space for vertices!\n"); |
703 return; | 709 return; |
704 } | 710 } |
705 | 711 |
706 CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices()); | 712 CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices()); |
707 | 713 |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
809 // this is legit only if scale & translation (which should be the case a
t the moment) | 815 // this is legit only if scale & translation (which should be the case a
t the moment) |
810 if (isStrokeOnly) { | 816 if (isStrokeOnly) { |
811 innerXRadius = xRadius - scaledStroke.fX; | 817 innerXRadius = xRadius - scaledStroke.fX; |
812 innerYRadius = yRadius - scaledStroke.fY; | 818 innerYRadius = yRadius - scaledStroke.fY; |
813 } | 819 } |
814 | 820 |
815 xRadius += scaledStroke.fX; | 821 xRadius += scaledStroke.fX; |
816 yRadius += scaledStroke.fY; | 822 yRadius += scaledStroke.fY; |
817 } | 823 } |
818 | 824 |
819 GrDrawState::AutoViewMatrixRestore avmr; | 825 SkMatrix invert; |
820 if (!avmr.setIdentity(drawState)) { | 826 if (!vm.invert(&invert)) { |
821 return false; | 827 return false; |
822 } | 828 } |
823 | 829 |
| 830 GrDrawState::AutoViewMatrixRestore avmr(drawState); |
| 831 |
824 SkAutoTUnref<GrGeometryProcessor> gp( | 832 SkAutoTUnref<GrGeometryProcessor> gp( |
825 EllipseEdgeEffect::Create(color, isStrokeOnly && innerXRadius > 0 &&
innerYRadius > 0)); | 833 EllipseEdgeEffect::Create(color, isStrokeOnly && innerXRadius > 0 &&
innerYRadius > 0, |
| 834 invert)); |
826 | 835 |
827 GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0); | 836 GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0); |
828 SkASSERT(gp->getVertexStride() == sizeof(EllipseVertex)); | 837 SkASSERT(gp->getVertexStride() == sizeof(EllipseVertex)); |
829 if (!geo.succeeded()) { | 838 if (!geo.succeeded()) { |
830 SkDebugf("Failed to get space for vertices!\n"); | 839 SkDebugf("Failed to get space for vertices!\n"); |
831 return false; | 840 return false; |
832 } | 841 } |
833 | 842 |
834 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); | 843 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); |
835 | 844 |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1077 } | 1086 } |
1078 GrPrimitiveEdgeType edgeType = applyAA ? kFillAA_GrProcessorEdgeType : | 1087 GrPrimitiveEdgeType edgeType = applyAA ? kFillAA_GrProcessorEdgeType : |
1079 kFillBW_GrProcessorEdgeType; | 1088 kFillBW_GrProcessorEdgeType; |
1080 GrFragmentProcessor* effect = GrRRectEffect::Create(edgeType, *outer); | 1089 GrFragmentProcessor* effect = GrRRectEffect::Create(edgeType, *outer); |
1081 if (NULL == effect) { | 1090 if (NULL == effect) { |
1082 return false; | 1091 return false; |
1083 } | 1092 } |
1084 if (!are.isSet()) { | 1093 if (!are.isSet()) { |
1085 are.set(drawState); | 1094 are.set(drawState); |
1086 } | 1095 } |
1087 GrDrawState::AutoViewMatrixRestore avmr; | 1096 |
1088 if (!avmr.setIdentity(drawState)) { | 1097 SkMatrix invert; |
| 1098 if (!drawState->getViewMatrix().invert(&invert)) { |
1089 return false; | 1099 return false; |
1090 } | 1100 } |
| 1101 |
| 1102 GrDrawState::AutoViewMatrixRestore avmr(drawState); |
1091 drawState->addCoverageProcessor(effect)->unref(); | 1103 drawState->addCoverageProcessor(effect)->unref(); |
1092 SkRect bounds = outer->getBounds(); | 1104 SkRect bounds = outer->getBounds(); |
1093 if (applyAA) { | 1105 if (applyAA) { |
1094 bounds.outset(SK_ScalarHalf, SK_ScalarHalf); | 1106 bounds.outset(SK_ScalarHalf, SK_ScalarHalf); |
1095 } | 1107 } |
1096 target->drawSimpleRect(drawState, color, bounds); | 1108 target->drawRect(drawState, color, bounds, NULL, &invert); |
1097 return true; | 1109 return true; |
1098 } | 1110 } |
1099 | 1111 |
1100 bool GrOvalRenderer::drawRRect(GrDrawTarget* target, | 1112 bool GrOvalRenderer::drawRRect(GrDrawTarget* target, |
1101 GrDrawState* drawState, | 1113 GrDrawState* drawState, |
1102 GrColor color, | 1114 GrColor color, |
1103 bool useAA, | 1115 bool useAA, |
1104 const SkRRect& rrect, | 1116 const SkRRect& rrect, |
1105 const SkStrokeRec& stroke) { | 1117 const SkStrokeRec& stroke) { |
1106 if (rrect.isOval()) { | 1118 if (rrect.isOval()) { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1162 // The way the effect interpolates the offset-to-ellipse/circle-center attri
bute only works on | 1174 // The way the effect interpolates the offset-to-ellipse/circle-center attri
bute only works on |
1163 // the interior of the rrect if the radii are >= 0.5. Otherwise, the inner r
ect of the nine- | 1175 // the interior of the rrect if the radii are >= 0.5. Otherwise, the inner r
ect of the nine- |
1164 // patch will have fractional coverage. This only matters when the interior
is actually filled. | 1176 // patch will have fractional coverage. This only matters when the interior
is actually filled. |
1165 // We could consider falling back to rect rendering here, since a tiny radiu
s is | 1177 // We could consider falling back to rect rendering here, since a tiny radiu
s is |
1166 // indistinguishable from a square corner. | 1178 // indistinguishable from a square corner. |
1167 if (!isStrokeOnly && (SK_ScalarHalf > xRadius || SK_ScalarHalf > yRadius)) { | 1179 if (!isStrokeOnly && (SK_ScalarHalf > xRadius || SK_ScalarHalf > yRadius)) { |
1168 return false; | 1180 return false; |
1169 } | 1181 } |
1170 | 1182 |
1171 // reset to device coordinates | 1183 // reset to device coordinates |
1172 GrDrawState::AutoViewMatrixRestore avmr; | 1184 SkMatrix invert; |
1173 if (!avmr.setIdentity(drawState)) { | 1185 if (!vm.invert(&invert)) { |
| 1186 SkDebugf("Failed to invert\n"); |
1174 return false; | 1187 return false; |
1175 } | 1188 } |
1176 | 1189 |
| 1190 GrDrawState::AutoViewMatrixRestore avmr(drawState); |
| 1191 |
1177 GrIndexBuffer* indexBuffer = this->rRectIndexBuffer(isStrokeOnly); | 1192 GrIndexBuffer* indexBuffer = this->rRectIndexBuffer(isStrokeOnly); |
1178 if (NULL == indexBuffer) { | 1193 if (NULL == indexBuffer) { |
1179 SkDebugf("Failed to create index buffer!\n"); | 1194 SkDebugf("Failed to create index buffer!\n"); |
1180 return false; | 1195 return false; |
1181 } | 1196 } |
1182 | 1197 |
1183 // if the corners are circles, use the circle renderer | 1198 // if the corners are circles, use the circle renderer |
1184 if ((!hasStroke || scaledStroke.fX == scaledStroke.fY) && xRadius == yRadius
) { | 1199 if ((!hasStroke || scaledStroke.fX == scaledStroke.fY) && xRadius == yRadius
) { |
1185 SkScalar innerRadius = 0.0f; | 1200 SkScalar innerRadius = 0.0f; |
1186 SkScalar outerRadius = xRadius; | 1201 SkScalar outerRadius = xRadius; |
1187 SkScalar halfWidth = 0; | 1202 SkScalar halfWidth = 0; |
1188 if (hasStroke) { | 1203 if (hasStroke) { |
1189 if (SkScalarNearlyZero(scaledStroke.fX)) { | 1204 if (SkScalarNearlyZero(scaledStroke.fX)) { |
1190 halfWidth = SK_ScalarHalf; | 1205 halfWidth = SK_ScalarHalf; |
1191 } else { | 1206 } else { |
1192 halfWidth = SkScalarHalf(scaledStroke.fX); | 1207 halfWidth = SkScalarHalf(scaledStroke.fX); |
1193 } | 1208 } |
1194 | 1209 |
1195 if (isStrokeOnly) { | 1210 if (isStrokeOnly) { |
1196 innerRadius = xRadius - halfWidth; | 1211 innerRadius = xRadius - halfWidth; |
1197 } | 1212 } |
1198 outerRadius += halfWidth; | 1213 outerRadius += halfWidth; |
1199 bounds.outset(halfWidth, halfWidth); | 1214 bounds.outset(halfWidth, halfWidth); |
1200 } | 1215 } |
1201 | 1216 |
1202 isStrokeOnly = (isStrokeOnly && innerRadius >= 0); | 1217 isStrokeOnly = (isStrokeOnly && innerRadius >= 0); |
1203 | 1218 |
1204 SkAutoTUnref<GrGeometryProcessor> effect(CircleEdgeEffect::Create(color,
isStrokeOnly)); | 1219 SkAutoTUnref<GrGeometryProcessor> effect(CircleEdgeEffect::Create(color,
isStrokeOnly, |
| 1220 invert
)); |
1205 | 1221 |
1206 GrDrawTarget::AutoReleaseGeometry geo(target, 16, effect->getVertexStrid
e(), 0); | 1222 GrDrawTarget::AutoReleaseGeometry geo(target, 16, effect->getVertexStrid
e(), 0); |
1207 SkASSERT(effect->getVertexStride() == sizeof(CircleVertex)); | 1223 SkASSERT(effect->getVertexStride() == sizeof(CircleVertex)); |
1208 if (!geo.succeeded()) { | 1224 if (!geo.succeeded()) { |
1209 SkDebugf("Failed to get space for vertices!\n"); | 1225 SkDebugf("Failed to get space for vertices!\n"); |
1210 return false; | 1226 return false; |
1211 } | 1227 } |
1212 CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices()); | 1228 CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices()); |
1213 | 1229 |
1214 // The radii are outset for two reasons. First, it allows the shader to
simply perform | 1230 // The radii are outset for two reasons. First, it allows the shader to
simply perform |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1293 innerYRadius = yRadius - scaledStroke.fY; | 1309 innerYRadius = yRadius - scaledStroke.fY; |
1294 } | 1310 } |
1295 | 1311 |
1296 xRadius += scaledStroke.fX; | 1312 xRadius += scaledStroke.fX; |
1297 yRadius += scaledStroke.fY; | 1313 yRadius += scaledStroke.fY; |
1298 bounds.outset(scaledStroke.fX, scaledStroke.fY); | 1314 bounds.outset(scaledStroke.fX, scaledStroke.fY); |
1299 } | 1315 } |
1300 | 1316 |
1301 isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0); | 1317 isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0); |
1302 | 1318 |
1303 SkAutoTUnref<GrGeometryProcessor> effect(EllipseEdgeEffect::Create(color
, isStrokeOnly)); | 1319 SkAutoTUnref<GrGeometryProcessor> effect(EllipseEdgeEffect::Create(color
, isStrokeOnly, |
| 1320 inver
t)); |
1304 | 1321 |
1305 GrDrawTarget::AutoReleaseGeometry geo(target, 16, effect->getVertexStrid
e(), 0); | 1322 GrDrawTarget::AutoReleaseGeometry geo(target, 16, effect->getVertexStrid
e(), 0); |
1306 SkASSERT(effect->getVertexStride() == sizeof(EllipseVertex)); | 1323 SkASSERT(effect->getVertexStride() == sizeof(EllipseVertex)); |
1307 if (!geo.succeeded()) { | 1324 if (!geo.succeeded()) { |
1308 SkDebugf("Failed to get space for vertices!\n"); | 1325 SkDebugf("Failed to get space for vertices!\n"); |
1309 return false; | 1326 return false; |
1310 } | 1327 } |
1311 | 1328 |
1312 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); | 1329 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); |
1313 | 1330 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1367 int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 : | 1384 int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 : |
1368 SK_ARRAY_COUNT(gRRectIndices); | 1385 SK_ARRAY_COUNT(gRRectIndices); |
1369 target->setIndexSourceToBuffer(indexBuffer); | 1386 target->setIndexSourceToBuffer(indexBuffer); |
1370 target->drawIndexedInstances(drawState, effect, kTriangles_GrPrimitiveTy
pe, 1, 16, indexCnt, | 1387 target->drawIndexedInstances(drawState, effect, kTriangles_GrPrimitiveTy
pe, 1, 16, indexCnt, |
1371 &bounds); | 1388 &bounds); |
1372 } | 1389 } |
1373 | 1390 |
1374 target->resetIndexSource(); | 1391 target->resetIndexSource(); |
1375 return true; | 1392 return true; |
1376 } | 1393 } |
OLD | NEW |