Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(232)

Side by Side Diff: src/gpu/GrOvalRenderer.cpp

Issue 815553003: Move ViewMatrix off of drawstate (Closed) Base URL: https://skia.googlesource.com/skia.git@remove-fragment-stage
Patch Set: more claenup Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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, const SkMatri x& localMatrix) { 68 static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix , bool stroke,
69 return SkNEW_ARGS(CircleEdgeEffect, (color, stroke, localMatrix)); 69 const SkMatrix& localMatrix) {
70 return SkNEW_ARGS(CircleEdgeEffect, (color, viewMatrix, stroke, localMat rix));
70 } 71 }
71 72
72 const GrAttribute* inPosition() const { return fInPosition; } 73 const GrAttribute* inPosition() const { return fInPosition; }
73 const GrAttribute* inCircleEdge() const { return fInCircleEdge; } 74 const GrAttribute* inCircleEdge() const { return fInCircleEdge; }
74 virtual ~CircleEdgeEffect() {} 75 virtual ~CircleEdgeEffect() {}
75 76
76 virtual const char* name() const SK_OVERRIDE { return "CircleEdge"; } 77 virtual const char* name() const SK_OVERRIDE { return "CircleEdge"; }
77 78
78 inline bool isStroked() const { return fStroke; } 79 inline bool isStroked() const { return fStroke; }
79 80
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 const GrBatchTracker& t) const SK_OVERRIDE { 168 const GrBatchTracker& t) const SK_OVERRIDE {
168 const BatchTracker& mine = m.cast<BatchTracker>(); 169 const BatchTracker& mine = m.cast<BatchTracker>();
169 const BatchTracker& theirs = t.cast<BatchTracker>(); 170 const BatchTracker& theirs = t.cast<BatchTracker>();
170 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords, 171 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
171 that, theirs.fUsesLocalCoords) && 172 that, theirs.fUsesLocalCoords) &&
172 CanCombineOutput(mine.fInputColorType, mine.fColor, 173 CanCombineOutput(mine.fInputColorType, mine.fColor,
173 theirs.fInputColorType, theirs.fColor); 174 theirs.fInputColorType, theirs.fColor);
174 } 175 }
175 176
176 private: 177 private:
177 CircleEdgeEffect(GrColor color, bool stroke, const SkMatrix& localMatrix) 178 CircleEdgeEffect(GrColor color, const SkMatrix& viewMatrix, bool stroke,
178 : INHERITED(color, false, localMatrix) { 179 const SkMatrix& localMatrix)
180 : INHERITED(color, viewMatrix, localMatrix) {
179 this->initClassID<CircleEdgeEffect>(); 181 this->initClassID<CircleEdgeEffect>();
180 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_Gr VertexAttribType)); 182 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_Gr VertexAttribType));
181 fInCircleEdge = &this->addVertexAttrib(GrAttribute("inCircleEdge", 183 fInCircleEdge = &this->addVertexAttrib(GrAttribute("inCircleEdge",
182 kVec4f_GrVertexAttrib Type)); 184 kVec4f_GrVertexAttrib Type));
183 fStroke = stroke; 185 fStroke = stroke;
184 } 186 }
185 187
186 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE { 188 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE {
187 const CircleEdgeEffect& cee = other.cast<CircleEdgeEffect>(); 189 const CircleEdgeEffect& cee = other.cast<CircleEdgeEffect>();
188 return cee.fStroke == fStroke; 190 return cee.fStroke == fStroke;
(...skipping 17 matching lines...) Expand all
206 208
207 typedef GrGeometryProcessor INHERITED; 209 typedef GrGeometryProcessor INHERITED;
208 }; 210 };
209 211
210 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(CircleEdgeEffect); 212 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(CircleEdgeEffect);
211 213
212 GrGeometryProcessor* CircleEdgeEffect::TestCreate(SkRandom* random, 214 GrGeometryProcessor* CircleEdgeEffect::TestCreate(SkRandom* random,
213 GrContext* context, 215 GrContext* context,
214 const GrDrawTargetCaps&, 216 const GrDrawTargetCaps&,
215 GrTexture* textures[]) { 217 GrTexture* textures[]) {
216 return CircleEdgeEffect::Create(GrRandomColor(random), random->nextBool(), 218 return CircleEdgeEffect::Create(GrRandomColor(random),
219 GrProcessorUnitTest::TestMatrix(random),
220 random->nextBool(),
217 GrProcessorUnitTest::TestMatrix(random)); 221 GrProcessorUnitTest::TestMatrix(random));
218 } 222 }
219 223
220 /////////////////////////////////////////////////////////////////////////////// 224 ///////////////////////////////////////////////////////////////////////////////
221 225
222 /** 226 /**
223 * The output of this effect is a modulation of the input color and coverage for an axis-aligned 227 * The output of this effect is a modulation of the input color and coverage for an axis-aligned
224 * ellipse, specified as a 2D offset from center, and the reciprocals of the out er and inner radii, 228 * ellipse, specified as a 2D offset from center, and the reciprocals of the out er and inner radii,
225 * in both x and y directions. 229 * in both x and y directions.
226 * 230 *
227 * We are using an implicit function of x^2/a^2 + y^2/b^2 - 1 = 0. 231 * We are using an implicit function of x^2/a^2 + y^2/b^2 - 1 = 0.
228 */ 232 */
229 233
230 class EllipseEdgeEffect : public GrGeometryProcessor { 234 class EllipseEdgeEffect : public GrGeometryProcessor {
231 public: 235 public:
232 static GrGeometryProcessor* Create(GrColor color, bool stroke, const SkMatri x& localMatrix) { 236 static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix , bool stroke,
233 return SkNEW_ARGS(EllipseEdgeEffect, (color, stroke, localMatrix)); 237 const SkMatrix& localMatrix) {
238 return SkNEW_ARGS(EllipseEdgeEffect, (color, viewMatrix, stroke, localMa trix));
234 } 239 }
235 240
236 virtual ~EllipseEdgeEffect() {} 241 virtual ~EllipseEdgeEffect() {}
237 242
238 virtual const char* name() const SK_OVERRIDE { return "EllipseEdge"; } 243 virtual const char* name() const SK_OVERRIDE { return "EllipseEdge"; }
239 244
240 const GrAttribute* inPosition() const { return fInPosition; } 245 const GrAttribute* inPosition() const { return fInPosition; }
241 const GrAttribute* inEllipseOffset() const { return fInEllipseOffset; } 246 const GrAttribute* inEllipseOffset() const { return fInEllipseOffset; }
242 const GrAttribute* inEllipseRadii() const { return fInEllipseRadii; } 247 const GrAttribute* inEllipseRadii() const { return fInEllipseRadii; }
243 248
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 const GrBatchTracker& t) const SK_OVERRIDE { 360 const GrBatchTracker& t) const SK_OVERRIDE {
356 const BatchTracker& mine = m.cast<BatchTracker>(); 361 const BatchTracker& mine = m.cast<BatchTracker>();
357 const BatchTracker& theirs = t.cast<BatchTracker>(); 362 const BatchTracker& theirs = t.cast<BatchTracker>();
358 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords, 363 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
359 that, theirs.fUsesLocalCoords) && 364 that, theirs.fUsesLocalCoords) &&
360 CanCombineOutput(mine.fInputColorType, mine.fColor, 365 CanCombineOutput(mine.fInputColorType, mine.fColor,
361 theirs.fInputColorType, theirs.fColor); 366 theirs.fInputColorType, theirs.fColor);
362 } 367 }
363 368
364 private: 369 private:
365 EllipseEdgeEffect(GrColor color, bool stroke, const SkMatrix& localMatrix) 370 EllipseEdgeEffect(GrColor color, const SkMatrix& viewMatrix, bool stroke,
366 : INHERITED(color, false, localMatrix) { 371 const SkMatrix& localMatrix)
372 : INHERITED(color, viewMatrix, localMatrix) {
367 this->initClassID<EllipseEdgeEffect>(); 373 this->initClassID<EllipseEdgeEffect>();
368 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_Gr VertexAttribType)); 374 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_Gr VertexAttribType));
369 fInEllipseOffset = &this->addVertexAttrib(GrAttribute("inEllipseOffset", 375 fInEllipseOffset = &this->addVertexAttrib(GrAttribute("inEllipseOffset",
370 kVec2f_GrVertexAtt ribType)); 376 kVec2f_GrVertexAtt ribType));
371 fInEllipseRadii = &this->addVertexAttrib(GrAttribute("inEllipseRadii", 377 fInEllipseRadii = &this->addVertexAttrib(GrAttribute("inEllipseRadii",
372 kVec4f_GrVertexAttr ibType)); 378 kVec4f_GrVertexAttr ibType));
373 fStroke = stroke; 379 fStroke = stroke;
374 } 380 }
375 381
376 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE { 382 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE {
(...skipping 20 matching lines...) Expand all
397 403
398 typedef GrGeometryProcessor INHERITED; 404 typedef GrGeometryProcessor INHERITED;
399 }; 405 };
400 406
401 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(EllipseEdgeEffect); 407 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(EllipseEdgeEffect);
402 408
403 GrGeometryProcessor* EllipseEdgeEffect::TestCreate(SkRandom* random, 409 GrGeometryProcessor* EllipseEdgeEffect::TestCreate(SkRandom* random,
404 GrContext* context, 410 GrContext* context,
405 const GrDrawTargetCaps&, 411 const GrDrawTargetCaps&,
406 GrTexture* textures[]) { 412 GrTexture* textures[]) {
407 return EllipseEdgeEffect::Create(GrRandomColor(random), random->nextBool(), 413 return EllipseEdgeEffect::Create(GrRandomColor(random),
414 GrProcessorUnitTest::TestMatrix(random),
415 random->nextBool(),
408 GrProcessorUnitTest::TestMatrix(random)); 416 GrProcessorUnitTest::TestMatrix(random));
409 } 417 }
410 418
411 /////////////////////////////////////////////////////////////////////////////// 419 ///////////////////////////////////////////////////////////////////////////////
412 420
413 /** 421 /**
414 * The output of this effect is a modulation of the input color and coverage for an ellipse, 422 * The output of this effect is a modulation of the input color and coverage for an ellipse,
415 * specified as a 2D offset from center for both the outer and inner paths (if s troked). The 423 * specified as a 2D offset from center for both the outer and inner paths (if s troked). The
416 * implict equation used is for a unit circle (x^2 + y^2 - 1 = 0) and the edge c orrected by 424 * implict equation used is for a unit circle (x^2 + y^2 - 1 = 0) and the edge c orrected by
417 * using differentials. 425 * using differentials.
418 * 426 *
419 * The result is device-independent and can be used with any affine matrix. 427 * The result is device-independent and can be used with any affine matrix.
420 */ 428 */
421 429
422 class DIEllipseEdgeEffect : public GrGeometryProcessor { 430 class DIEllipseEdgeEffect : public GrGeometryProcessor {
423 public: 431 public:
424 enum Mode { kStroke = 0, kHairline, kFill }; 432 enum Mode { kStroke = 0, kHairline, kFill };
425 433
426 static GrGeometryProcessor* Create(GrColor color, Mode mode) { 434 static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix , Mode mode) {
427 return SkNEW_ARGS(DIEllipseEdgeEffect, (color, mode)); 435 return SkNEW_ARGS(DIEllipseEdgeEffect, (color, viewMatrix, mode));
428 } 436 }
429 437
430 virtual ~DIEllipseEdgeEffect() {} 438 virtual ~DIEllipseEdgeEffect() {}
431 439
432 virtual const char* name() const SK_OVERRIDE { return "DIEllipseEdge"; } 440 virtual const char* name() const SK_OVERRIDE { return "DIEllipseEdge"; }
433 441
434 const GrAttribute* inPosition() const { return fInPosition; } 442 const GrAttribute* inPosition() const { return fInPosition; }
435 const GrAttribute* inEllipseOffsets0() const { return fInEllipseOffsets0; } 443 const GrAttribute* inEllipseOffsets0() const { return fInEllipseOffsets0; }
436 const GrAttribute* inEllipseOffsets1() const { return fInEllipseOffsets1; } 444 const GrAttribute* inEllipseOffsets1() const { return fInEllipseOffsets1; }
437 445
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 const GrBatchTracker& t) const SK_OVERRIDE { 572 const GrBatchTracker& t) const SK_OVERRIDE {
565 const BatchTracker& mine = m.cast<BatchTracker>(); 573 const BatchTracker& mine = m.cast<BatchTracker>();
566 const BatchTracker& theirs = t.cast<BatchTracker>(); 574 const BatchTracker& theirs = t.cast<BatchTracker>();
567 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords, 575 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
568 that, theirs.fUsesLocalCoords) && 576 that, theirs.fUsesLocalCoords) &&
569 CanCombineOutput(mine.fInputColorType, mine.fColor, 577 CanCombineOutput(mine.fInputColorType, mine.fColor,
570 theirs.fInputColorType, theirs.fColor); 578 theirs.fInputColorType, theirs.fColor);
571 } 579 }
572 580
573 private: 581 private:
574 DIEllipseEdgeEffect(GrColor color, Mode mode) : INHERITED(color) { 582 DIEllipseEdgeEffect(GrColor color, const SkMatrix& viewMatrix, Mode mode)
583 : INHERITED(color, viewMatrix) {
575 this->initClassID<DIEllipseEdgeEffect>(); 584 this->initClassID<DIEllipseEdgeEffect>();
576 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_Gr VertexAttribType)); 585 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_Gr VertexAttribType));
577 fInEllipseOffsets0 = &this->addVertexAttrib(GrAttribute("inEllipseOffset s0", 586 fInEllipseOffsets0 = &this->addVertexAttrib(GrAttribute("inEllipseOffset s0",
578 kVec2f_GrVertexA ttribType)); 587 kVec2f_GrVertexA ttribType));
579 fInEllipseOffsets1 = &this->addVertexAttrib(GrAttribute("inEllipseOffset s1", 588 fInEllipseOffsets1 = &this->addVertexAttrib(GrAttribute("inEllipseOffset s1",
580 kVec2f_GrVertexA ttribType)); 589 kVec2f_GrVertexA ttribType));
581 fMode = mode; 590 fMode = mode;
582 } 591 }
583 592
584 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE { 593 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE {
(...skipping 20 matching lines...) Expand all
605 614
606 typedef GrGeometryProcessor INHERITED; 615 typedef GrGeometryProcessor INHERITED;
607 }; 616 };
608 617
609 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DIEllipseEdgeEffect); 618 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DIEllipseEdgeEffect);
610 619
611 GrGeometryProcessor* DIEllipseEdgeEffect::TestCreate(SkRandom* random, 620 GrGeometryProcessor* DIEllipseEdgeEffect::TestCreate(SkRandom* random,
612 GrContext* context, 621 GrContext* context,
613 const GrDrawTargetCaps&, 622 const GrDrawTargetCaps&,
614 GrTexture* textures[]) { 623 GrTexture* textures[]) {
615 return DIEllipseEdgeEffect::Create(GrRandomColor(random), (Mode)(random->nex tRangeU(0,2))); 624 return DIEllipseEdgeEffect::Create(GrRandomColor(random),
625 GrProcessorUnitTest::TestMatrix(random),
626 (Mode)(random->nextRangeU(0,2)));
616 } 627 }
617 628
618 /////////////////////////////////////////////////////////////////////////////// 629 ///////////////////////////////////////////////////////////////////////////////
619 630
620 void GrOvalRenderer::reset() { 631 void GrOvalRenderer::reset() {
621 SkSafeSetNull(fRRectIndexBuffer); 632 SkSafeSetNull(fRRectIndexBuffer);
622 SkSafeSetNull(fStrokeRRectIndexBuffer); 633 SkSafeSetNull(fStrokeRRectIndexBuffer);
623 } 634 }
624 635
625 bool GrOvalRenderer::drawOval(GrDrawTarget* target, 636 bool GrOvalRenderer::drawOval(GrDrawTarget* target,
626 GrDrawState* drawState, 637 GrDrawState* drawState,
627 GrColor color, 638 GrColor color,
639 const SkMatrix& viewMatrix,
628 bool useAA, 640 bool useAA,
629 const SkRect& oval, 641 const SkRect& oval,
630 const SkStrokeRec& stroke) 642 const SkStrokeRec& stroke)
631 { 643 {
632 bool useCoverageAA = useAA && 644 bool useCoverageAA = useAA &&
633 !drawState->getRenderTarget()->isMultisampled() && 645 !drawState->getRenderTarget()->isMultisampled() &&
634 drawState->canUseFracCoveragePrimProc(color, *target->caps()); 646 drawState->canUseFracCoveragePrimProc(color, *target->caps());
635 647
636 if (!useCoverageAA) { 648 if (!useCoverageAA) {
637 return false; 649 return false;
638 } 650 }
639 651
640 const SkMatrix& vm = drawState->getViewMatrix();
641
642 // we can draw circles 652 // we can draw circles
643 if (SkScalarNearlyEqual(oval.width(), oval.height()) 653 if (SkScalarNearlyEqual(oval.width(), oval.height()) && circle_stays_circle( viewMatrix)) {
644 && circle_stays_circle(vm)) { 654 this->drawCircle(target, drawState, color, viewMatrix, useCoverageAA, ov al, stroke);
645 this->drawCircle(target, drawState, color, useCoverageAA, oval, stroke);
646 // if we have shader derivative support, render as device-independent 655 // if we have shader derivative support, render as device-independent
647 } else if (target->caps()->shaderDerivativeSupport()) { 656 } else if (target->caps()->shaderDerivativeSupport()) {
648 return this->drawDIEllipse(target, drawState, color, useCoverageAA, oval , stroke); 657 return this->drawDIEllipse(target, drawState, color, viewMatrix, useCove rageAA, oval,
658 stroke);
649 // otherwise axis-aligned ellipses only 659 // otherwise axis-aligned ellipses only
650 } else if (vm.rectStaysRect()) { 660 } else if (viewMatrix.rectStaysRect()) {
651 return this->drawEllipse(target, drawState, color, useCoverageAA, oval, stroke); 661 return this->drawEllipse(target, drawState, color, viewMatrix, useCovera geAA, oval, stroke);
652 } else { 662 } else {
653 return false; 663 return false;
654 } 664 }
655 665
656 return true; 666 return true;
657 } 667 }
658 668
659 /////////////////////////////////////////////////////////////////////////////// 669 ///////////////////////////////////////////////////////////////////////////////
660 670
661 void GrOvalRenderer::drawCircle(GrDrawTarget* target, 671 void GrOvalRenderer::drawCircle(GrDrawTarget* target,
662 GrDrawState* drawState, 672 GrDrawState* drawState,
663 GrColor color, 673 GrColor color,
674 const SkMatrix& viewMatrix,
664 bool useCoverageAA, 675 bool useCoverageAA,
665 const SkRect& circle, 676 const SkRect& circle,
666 const SkStrokeRec& stroke) 677 const SkStrokeRec& stroke) {
667 {
668 const SkMatrix& vm = drawState->getViewMatrix();
669 SkPoint center = SkPoint::Make(circle.centerX(), circle.centerY()); 678 SkPoint center = SkPoint::Make(circle.centerX(), circle.centerY());
670 vm.mapPoints(&center, 1); 679 viewMatrix.mapPoints(&center, 1);
671 SkScalar radius = vm.mapRadius(SkScalarHalf(circle.width())); 680 SkScalar radius = viewMatrix.mapRadius(SkScalarHalf(circle.width()));
672 SkScalar strokeWidth = vm.mapRadius(stroke.getWidth()); 681 SkScalar strokeWidth = viewMatrix.mapRadius(stroke.getWidth());
673 682
674 SkMatrix invert; 683 SkMatrix invert;
675 if (!vm.invert(&invert)) { 684 if (!viewMatrix.invert(&invert)) {
676 return; 685 return;
677 } 686 }
678 687
679 GrDrawState::AutoViewMatrixRestore avmr(drawState);
680
681 SkStrokeRec::Style style = stroke.getStyle(); 688 SkStrokeRec::Style style = stroke.getStyle();
682 bool isStrokeOnly = SkStrokeRec::kStroke_Style == style || 689 bool isStrokeOnly = SkStrokeRec::kStroke_Style == style ||
683 SkStrokeRec::kHairline_Style == style; 690 SkStrokeRec::kHairline_Style == style;
684 bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == style; 691 bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == style;
685 692
686 SkScalar innerRadius = 0.0f; 693 SkScalar innerRadius = 0.0f;
687 SkScalar outerRadius = radius; 694 SkScalar outerRadius = radius;
688 SkScalar halfWidth = 0; 695 SkScalar halfWidth = 0;
689 if (hasStroke) { 696 if (hasStroke) {
690 if (SkScalarNearlyZero(strokeWidth)) { 697 if (SkScalarNearlyZero(strokeWidth)) {
691 halfWidth = SK_ScalarHalf; 698 halfWidth = SK_ScalarHalf;
692 } else { 699 } else {
693 halfWidth = SkScalarHalf(strokeWidth); 700 halfWidth = SkScalarHalf(strokeWidth);
694 } 701 }
695 702
696 outerRadius += halfWidth; 703 outerRadius += halfWidth;
697 if (isStrokeOnly) { 704 if (isStrokeOnly) {
698 innerRadius = radius - halfWidth; 705 innerRadius = radius - halfWidth;
699 } 706 }
700 } 707 }
701 708
702 SkAutoTUnref<GrGeometryProcessor> gp( 709 SkAutoTUnref<GrGeometryProcessor> gp(
703 CircleEdgeEffect::Create(color, isStrokeOnly && innerRadius > 0, inv ert)); 710 CircleEdgeEffect::Create(color, SkMatrix::I(), isStrokeOnly && inner Radius > 0,invert));
704 711
705 GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0); 712 GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0);
706 SkASSERT(gp->getVertexStride() == sizeof(CircleVertex)); 713 SkASSERT(gp->getVertexStride() == sizeof(CircleVertex));
707 if (!geo.succeeded()) { 714 if (!geo.succeeded()) {
708 SkDebugf("Failed to get space for vertices!\n"); 715 SkDebugf("Failed to get space for vertices!\n");
709 return; 716 return;
710 } 717 }
711 718
712 CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices()); 719 CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices());
713 720
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 target->setIndexSourceToBuffer(fGpu->getQuadIndexBuffer()); 757 target->setIndexSourceToBuffer(fGpu->getQuadIndexBuffer());
751 target->drawIndexedInstances(drawState, gp, kTriangles_GrPrimitiveType, 1, 4 , 6, &bounds); 758 target->drawIndexedInstances(drawState, gp, kTriangles_GrPrimitiveType, 1, 4 , 6, &bounds);
752 target->resetIndexSource(); 759 target->resetIndexSource();
753 } 760 }
754 761
755 /////////////////////////////////////////////////////////////////////////////// 762 ///////////////////////////////////////////////////////////////////////////////
756 763
757 bool GrOvalRenderer::drawEllipse(GrDrawTarget* target, 764 bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
758 GrDrawState* drawState, 765 GrDrawState* drawState,
759 GrColor color, 766 GrColor color,
767 const SkMatrix& viewMatrix,
760 bool useCoverageAA, 768 bool useCoverageAA,
761 const SkRect& ellipse, 769 const SkRect& ellipse,
762 const SkStrokeRec& stroke) 770 const SkStrokeRec& stroke) {
763 {
764 #ifdef SK_DEBUG 771 #ifdef SK_DEBUG
765 { 772 {
766 // we should have checked for this previously 773 // we should have checked for this previously
767 bool isAxisAlignedEllipse = drawState->getViewMatrix().rectStaysRect(); 774 bool isAxisAlignedEllipse = viewMatrix.rectStaysRect();
768 SkASSERT(useCoverageAA && isAxisAlignedEllipse); 775 SkASSERT(useCoverageAA && isAxisAlignedEllipse);
769 } 776 }
770 #endif 777 #endif
771 778
772 // do any matrix crunching before we reset the draw state for device coords 779 // do any matrix crunching before we reset the draw state for device coords
773 const SkMatrix& vm = drawState->getViewMatrix();
774 SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY()); 780 SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY());
775 vm.mapPoints(&center, 1); 781 viewMatrix.mapPoints(&center, 1);
776 SkScalar ellipseXRadius = SkScalarHalf(ellipse.width()); 782 SkScalar ellipseXRadius = SkScalarHalf(ellipse.width());
777 SkScalar ellipseYRadius = SkScalarHalf(ellipse.height()); 783 SkScalar ellipseYRadius = SkScalarHalf(ellipse.height());
778 SkScalar xRadius = SkScalarAbs(vm[SkMatrix::kMScaleX]*ellipseXRadius + 784 SkScalar xRadius = SkScalarAbs(viewMatrix[SkMatrix::kMScaleX]*ellipseXRadius +
779 vm[SkMatrix::kMSkewY]*ellipseYRadius); 785 viewMatrix[SkMatrix::kMSkewY]*ellipseYRadius) ;
780 SkScalar yRadius = SkScalarAbs(vm[SkMatrix::kMSkewX]*ellipseXRadius + 786 SkScalar yRadius = SkScalarAbs(viewMatrix[SkMatrix::kMSkewX]*ellipseXRadius +
781 vm[SkMatrix::kMScaleY]*ellipseYRadius); 787 viewMatrix[SkMatrix::kMScaleY]*ellipseYRadius );
782 788
783 // do (potentially) anisotropic mapping of stroke 789 // do (potentially) anisotropic mapping of stroke
784 SkVector scaledStroke; 790 SkVector scaledStroke;
785 SkScalar strokeWidth = stroke.getWidth(); 791 SkScalar strokeWidth = stroke.getWidth();
786 scaledStroke.fX = SkScalarAbs(strokeWidth*(vm[SkMatrix::kMScaleX] + vm[SkMat rix::kMSkewY])); 792 scaledStroke.fX = SkScalarAbs(strokeWidth*(viewMatrix[SkMatrix::kMScaleX] +
787 scaledStroke.fY = SkScalarAbs(strokeWidth*(vm[SkMatrix::kMSkewX] + vm[SkMatr ix::kMScaleY])); 793 viewMatrix[SkMatrix::kMSkewY]));
794 scaledStroke.fY = SkScalarAbs(strokeWidth*(viewMatrix[SkMatrix::kMSkewX] +
795 viewMatrix[SkMatrix::kMScaleY]));
788 796
789 SkStrokeRec::Style style = stroke.getStyle(); 797 SkStrokeRec::Style style = stroke.getStyle();
790 bool isStrokeOnly = SkStrokeRec::kStroke_Style == style || 798 bool isStrokeOnly = SkStrokeRec::kStroke_Style == style ||
791 SkStrokeRec::kHairline_Style == style; 799 SkStrokeRec::kHairline_Style == style;
792 bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == style; 800 bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == style;
793 801
794 SkScalar innerXRadius = 0; 802 SkScalar innerXRadius = 0;
795 SkScalar innerYRadius = 0; 803 SkScalar innerYRadius = 0;
796 if (hasStroke) { 804 if (hasStroke) {
797 if (SkScalarNearlyZero(scaledStroke.length())) { 805 if (SkScalarNearlyZero(scaledStroke.length())) {
(...skipping 18 matching lines...) Expand all
816 if (isStrokeOnly) { 824 if (isStrokeOnly) {
817 innerXRadius = xRadius - scaledStroke.fX; 825 innerXRadius = xRadius - scaledStroke.fX;
818 innerYRadius = yRadius - scaledStroke.fY; 826 innerYRadius = yRadius - scaledStroke.fY;
819 } 827 }
820 828
821 xRadius += scaledStroke.fX; 829 xRadius += scaledStroke.fX;
822 yRadius += scaledStroke.fY; 830 yRadius += scaledStroke.fY;
823 } 831 }
824 832
825 SkMatrix invert; 833 SkMatrix invert;
826 if (!vm.invert(&invert)) { 834 if (!viewMatrix.invert(&invert)) {
827 return false; 835 return false;
828 } 836 }
829 837
830 GrDrawState::AutoViewMatrixRestore avmr(drawState);
831
832 SkAutoTUnref<GrGeometryProcessor> gp( 838 SkAutoTUnref<GrGeometryProcessor> gp(
833 EllipseEdgeEffect::Create(color, isStrokeOnly && innerXRadius > 0 && innerYRadius > 0, 839 EllipseEdgeEffect::Create(color,
840 SkMatrix::I(),
841 isStrokeOnly && innerXRadius > 0 && innerY Radius > 0,
834 invert)); 842 invert));
835 843
836 GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0); 844 GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0);
837 SkASSERT(gp->getVertexStride() == sizeof(EllipseVertex)); 845 SkASSERT(gp->getVertexStride() == sizeof(EllipseVertex));
838 if (!geo.succeeded()) { 846 if (!geo.succeeded()) {
839 SkDebugf("Failed to get space for vertices!\n"); 847 SkDebugf("Failed to get space for vertices!\n");
840 return false; 848 return false;
841 } 849 }
842 850
843 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); 851 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices());
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
884 target->setIndexSourceToBuffer(fGpu->getQuadIndexBuffer()); 892 target->setIndexSourceToBuffer(fGpu->getQuadIndexBuffer());
885 target->drawIndexedInstances(drawState, gp, kTriangles_GrPrimitiveType, 1, 4 , 6, &bounds); 893 target->drawIndexedInstances(drawState, gp, kTriangles_GrPrimitiveType, 1, 4 , 6, &bounds);
886 target->resetIndexSource(); 894 target->resetIndexSource();
887 895
888 return true; 896 return true;
889 } 897 }
890 898
891 bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target, 899 bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target,
892 GrDrawState* drawState, 900 GrDrawState* drawState,
893 GrColor color, 901 GrColor color,
902 const SkMatrix& viewMatrix,
894 bool useCoverageAA, 903 bool useCoverageAA,
895 const SkRect& ellipse, 904 const SkRect& ellipse,
896 const SkStrokeRec& stroke) 905 const SkStrokeRec& stroke) {
897 {
898 const SkMatrix& vm = drawState->getViewMatrix();
899
900 SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY()); 906 SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY());
901 SkScalar xRadius = SkScalarHalf(ellipse.width()); 907 SkScalar xRadius = SkScalarHalf(ellipse.width());
902 SkScalar yRadius = SkScalarHalf(ellipse.height()); 908 SkScalar yRadius = SkScalarHalf(ellipse.height());
903 909
904 SkStrokeRec::Style style = stroke.getStyle(); 910 SkStrokeRec::Style style = stroke.getStyle();
905 DIEllipseEdgeEffect::Mode mode = (SkStrokeRec::kStroke_Style == style) ? 911 DIEllipseEdgeEffect::Mode mode = (SkStrokeRec::kStroke_Style == style) ?
906 DIEllipseEdgeEffect::kStroke : 912 DIEllipseEdgeEffect::kStroke :
907 (SkStrokeRec::kHairline_Style == style) ? 913 (SkStrokeRec::kHairline_Style == style) ?
908 DIEllipseEdgeEffect::kHairline : DIEllipseEd geEffect::kFill; 914 DIEllipseEdgeEffect::kHairline : DIEllipseEd geEffect::kFill;
909 915
(...skipping 29 matching lines...) Expand all
939 xRadius += strokeWidth; 945 xRadius += strokeWidth;
940 yRadius += strokeWidth; 946 yRadius += strokeWidth;
941 } 947 }
942 if (DIEllipseEdgeEffect::kStroke == mode) { 948 if (DIEllipseEdgeEffect::kStroke == mode) {
943 mode = (innerXRadius > 0 && innerYRadius > 0) ? DIEllipseEdgeEffect::kSt roke : 949 mode = (innerXRadius > 0 && innerYRadius > 0) ? DIEllipseEdgeEffect::kSt roke :
944 DIEllipseEdgeEffect::kFi ll; 950 DIEllipseEdgeEffect::kFi ll;
945 } 951 }
946 SkScalar innerRatioX = SkScalarDiv(xRadius, innerXRadius); 952 SkScalar innerRatioX = SkScalarDiv(xRadius, innerXRadius);
947 SkScalar innerRatioY = SkScalarDiv(yRadius, innerYRadius); 953 SkScalar innerRatioY = SkScalarDiv(yRadius, innerYRadius);
948 954
949 SkAutoTUnref<GrGeometryProcessor> gp(DIEllipseEdgeEffect::Create(color, mode )); 955 SkAutoTUnref<GrGeometryProcessor> gp(DIEllipseEdgeEffect::Create(color, view Matrix, mode));
950 956
951 GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0); 957 GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0);
952 SkASSERT(gp->getVertexStride() == sizeof(DIEllipseVertex)); 958 SkASSERT(gp->getVertexStride() == sizeof(DIEllipseVertex));
953 if (!geo.succeeded()) { 959 if (!geo.succeeded()) {
954 SkDebugf("Failed to get space for vertices!\n"); 960 SkDebugf("Failed to get space for vertices!\n");
955 return false; 961 return false;
956 } 962 }
957 963
958 DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(geo.vertices()); 964 DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(geo.vertices());
959 965
960 // This expands the outer rect so that after CTM we end up with a half-pixel border 966 // This expands the outer rect so that after CTM we end up with a half-pixel border
961 SkScalar a = vm[SkMatrix::kMScaleX]; 967 SkScalar a = viewMatrix[SkMatrix::kMScaleX];
962 SkScalar b = vm[SkMatrix::kMSkewX]; 968 SkScalar b = viewMatrix[SkMatrix::kMSkewX];
963 SkScalar c = vm[SkMatrix::kMSkewY]; 969 SkScalar c = viewMatrix[SkMatrix::kMSkewY];
964 SkScalar d = vm[SkMatrix::kMScaleY]; 970 SkScalar d = viewMatrix[SkMatrix::kMScaleY];
965 SkScalar geoDx = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(a*a + c*c)); 971 SkScalar geoDx = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(a*a + c*c));
966 SkScalar geoDy = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(b*b + d*d)); 972 SkScalar geoDy = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(b*b + d*d));
967 // This adjusts the "radius" to include the half-pixel border 973 // This adjusts the "radius" to include the half-pixel border
968 SkScalar offsetDx = SkScalarDiv(geoDx, xRadius); 974 SkScalar offsetDx = SkScalarDiv(geoDx, xRadius);
969 SkScalar offsetDy = SkScalarDiv(geoDy, yRadius); 975 SkScalar offsetDy = SkScalarDiv(geoDy, yRadius);
970 976
971 SkRect bounds = SkRect::MakeLTRB( 977 SkRect bounds = SkRect::MakeLTRB(
972 center.fX - xRadius - geoDx, 978 center.fX - xRadius - geoDx,
973 center.fY - yRadius - geoDy, 979 center.fY - yRadius - geoDy,
974 center.fX + xRadius + geoDx, 980 center.fX + xRadius + geoDx,
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1039 kNumRRectsInInd exBuffer, 1045 kNumRRectsInInd exBuffer,
1040 kVertsPerRRect) ; 1046 kVertsPerRRect) ;
1041 } 1047 }
1042 return fRRectIndexBuffer; 1048 return fRRectIndexBuffer;
1043 } 1049 }
1044 } 1050 }
1045 1051
1046 bool GrOvalRenderer::drawDRRect(GrDrawTarget* target, 1052 bool GrOvalRenderer::drawDRRect(GrDrawTarget* target,
1047 GrDrawState* drawState, 1053 GrDrawState* drawState,
1048 GrColor color, 1054 GrColor color,
1055 const SkMatrix& viewMatrix,
1049 bool useAA, 1056 bool useAA,
1050 const SkRRect& origOuter, 1057 const SkRRect& origOuter,
1051 const SkRRect& origInner) { 1058 const SkRRect& origInner) {
1052 bool applyAA = useAA && 1059 bool applyAA = useAA &&
1053 !drawState->getRenderTarget()->isMultisampled() && 1060 !drawState->getRenderTarget()->isMultisampled() &&
1054 drawState->canUseFracCoveragePrimProc(color, *target->caps()) ; 1061 drawState->canUseFracCoveragePrimProc(color, *target->caps()) ;
1055 GrDrawState::AutoRestoreEffects are; 1062 GrDrawState::AutoRestoreEffects are;
1056 if (!origInner.isEmpty()) { 1063 if (!origInner.isEmpty()) {
1057 SkTCopyOnFirstWrite<SkRRect> inner(origInner); 1064 SkTCopyOnFirstWrite<SkRRect> inner(origInner);
1058 if (!drawState->getViewMatrix().isIdentity()) { 1065 if (!viewMatrix.isIdentity()) {
1059 if (!origInner.transform(drawState->getViewMatrix(), inner.writable( ))) { 1066 if (!origInner.transform(viewMatrix, inner.writable())) {
1060 return false; 1067 return false;
1061 } 1068 }
1062 } 1069 }
1063 GrPrimitiveEdgeType edgeType = applyAA ? 1070 GrPrimitiveEdgeType edgeType = applyAA ?
1064 kInverseFillAA_GrProcessorEdgeType : 1071 kInverseFillAA_GrProcessorEdgeType :
1065 kInverseFillBW_GrProcessorEdgeType; 1072 kInverseFillBW_GrProcessorEdgeType;
1066 // TODO this needs to be a geometry processor 1073 // TODO this needs to be a geometry processor
1067 GrFragmentProcessor* fp = GrRRectEffect::Create(edgeType, *inner); 1074 GrFragmentProcessor* fp = GrRRectEffect::Create(edgeType, *inner);
1068 if (NULL == fp) { 1075 if (NULL == fp) {
1069 return false; 1076 return false;
1070 } 1077 }
1071 are.set(drawState); 1078 are.set(drawState);
1072 drawState->addCoverageProcessor(fp)->unref(); 1079 drawState->addCoverageProcessor(fp)->unref();
1073 } 1080 }
1074 1081
1075 SkStrokeRec fillRec(SkStrokeRec::kFill_InitStyle); 1082 SkStrokeRec fillRec(SkStrokeRec::kFill_InitStyle);
1076 if (this->drawRRect(target, drawState, color, useAA, origOuter, fillRec)) { 1083 if (this->drawRRect(target, drawState, color, viewMatrix, useAA, origOuter, fillRec)) {
1077 return true; 1084 return true;
1078 } 1085 }
1079 1086
1080 SkASSERT(!origOuter.isEmpty()); 1087 SkASSERT(!origOuter.isEmpty());
1081 SkTCopyOnFirstWrite<SkRRect> outer(origOuter); 1088 SkTCopyOnFirstWrite<SkRRect> outer(origOuter);
1082 if (!drawState->getViewMatrix().isIdentity()) { 1089 if (!viewMatrix.isIdentity()) {
1083 if (!origOuter.transform(drawState->getViewMatrix(), outer.writable())) { 1090 if (!origOuter.transform(viewMatrix, outer.writable())) {
1084 return false; 1091 return false;
1085 } 1092 }
1086 } 1093 }
1087 GrPrimitiveEdgeType edgeType = applyAA ? kFillAA_GrProcessorEdgeType : 1094 GrPrimitiveEdgeType edgeType = applyAA ? kFillAA_GrProcessorEdgeType :
1088 kFillBW_GrProcessorEdgeType; 1095 kFillBW_GrProcessorEdgeType;
1089 GrFragmentProcessor* effect = GrRRectEffect::Create(edgeType, *outer); 1096 GrFragmentProcessor* effect = GrRRectEffect::Create(edgeType, *outer);
1090 if (NULL == effect) { 1097 if (NULL == effect) {
1091 return false; 1098 return false;
1092 } 1099 }
1093 if (!are.isSet()) { 1100 if (!are.isSet()) {
1094 are.set(drawState); 1101 are.set(drawState);
1095 } 1102 }
1096 1103
1097 SkMatrix invert; 1104 SkMatrix invert;
1098 if (!drawState->getViewMatrix().invert(&invert)) { 1105 if (!viewMatrix.invert(&invert)) {
1099 return false; 1106 return false;
1100 } 1107 }
1101 1108
1102 GrDrawState::AutoViewMatrixRestore avmr(drawState);
1103 drawState->addCoverageProcessor(effect)->unref(); 1109 drawState->addCoverageProcessor(effect)->unref();
1104 SkRect bounds = outer->getBounds(); 1110 SkRect bounds = outer->getBounds();
1105 if (applyAA) { 1111 if (applyAA) {
1106 bounds.outset(SK_ScalarHalf, SK_ScalarHalf); 1112 bounds.outset(SK_ScalarHalf, SK_ScalarHalf);
1107 } 1113 }
1108 target->drawRect(drawState, color, bounds, NULL, &invert); 1114 target->drawRect(drawState, color, SkMatrix::I(), bounds, NULL, &invert);
1109 return true; 1115 return true;
1110 } 1116 }
1111 1117
1112 bool GrOvalRenderer::drawRRect(GrDrawTarget* target, 1118 bool GrOvalRenderer::drawRRect(GrDrawTarget* target,
1113 GrDrawState* drawState, 1119 GrDrawState* drawState,
1114 GrColor color, 1120 GrColor color,
1121 const SkMatrix& viewMatrix,
1115 bool useAA, 1122 bool useAA,
1116 const SkRRect& rrect, 1123 const SkRRect& rrect,
1117 const SkStrokeRec& stroke) { 1124 const SkStrokeRec& stroke) {
1118 if (rrect.isOval()) { 1125 if (rrect.isOval()) {
1119 return this->drawOval(target, drawState, color, useAA, rrect.getBounds() , stroke); 1126 return this->drawOval(target, drawState, color, viewMatrix, useAA, rrect .getBounds(),
1127 stroke);
1120 } 1128 }
1121 1129
1122 bool useCoverageAA = useAA && 1130 bool useCoverageAA = useAA &&
1123 !drawState->getRenderTarget()->isMultisampled() && 1131 !drawState->getRenderTarget()->isMultisampled() &&
1124 drawState->canUseFracCoveragePrimProc(color, *target->caps()); 1132 drawState->canUseFracCoveragePrimProc(color, *target->caps());
1125 1133
1126 // only anti-aliased rrects for now 1134 // only anti-aliased rrects for now
1127 if (!useCoverageAA) { 1135 if (!useCoverageAA) {
1128 return false; 1136 return false;
1129 } 1137 }
1130 1138
1131 const SkMatrix& vm = drawState->getViewMatrix(); 1139 if (!viewMatrix.rectStaysRect() || !rrect.isSimple()) {
1132
1133 if (!vm.rectStaysRect() || !rrect.isSimple()) {
1134 return false; 1140 return false;
1135 } 1141 }
1136 1142
1137 // do any matrix crunching before we reset the draw state for device coords 1143 // do any matrix crunching before we reset the draw state for device coords
1138 const SkRect& rrectBounds = rrect.getBounds(); 1144 const SkRect& rrectBounds = rrect.getBounds();
1139 SkRect bounds; 1145 SkRect bounds;
1140 vm.mapRect(&bounds, rrectBounds); 1146 viewMatrix.mapRect(&bounds, rrectBounds);
1141 1147
1142 SkVector radii = rrect.getSimpleRadii(); 1148 SkVector radii = rrect.getSimpleRadii();
1143 SkScalar xRadius = SkScalarAbs(vm[SkMatrix::kMScaleX]*radii.fX + 1149 SkScalar xRadius = SkScalarAbs(viewMatrix[SkMatrix::kMScaleX]*radii.fX +
1144 vm[SkMatrix::kMSkewY]*radii.fY); 1150 viewMatrix[SkMatrix::kMSkewY]*radii.fY);
1145 SkScalar yRadius = SkScalarAbs(vm[SkMatrix::kMSkewX]*radii.fX + 1151 SkScalar yRadius = SkScalarAbs(viewMatrix[SkMatrix::kMSkewX]*radii.fX +
1146 vm[SkMatrix::kMScaleY]*radii.fY); 1152 viewMatrix[SkMatrix::kMScaleY]*radii.fY);
1147 1153
1148 SkStrokeRec::Style style = stroke.getStyle(); 1154 SkStrokeRec::Style style = stroke.getStyle();
1149 1155
1150 // do (potentially) anisotropic mapping of stroke 1156 // do (potentially) anisotropic mapping of stroke
1151 SkVector scaledStroke; 1157 SkVector scaledStroke;
1152 SkScalar strokeWidth = stroke.getWidth(); 1158 SkScalar strokeWidth = stroke.getWidth();
1153 1159
1154 bool isStrokeOnly = SkStrokeRec::kStroke_Style == style || 1160 bool isStrokeOnly = SkStrokeRec::kStroke_Style == style ||
1155 SkStrokeRec::kHairline_Style == style; 1161 SkStrokeRec::kHairline_Style == style;
1156 bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == style; 1162 bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == style;
1157 1163
1158 if (hasStroke) { 1164 if (hasStroke) {
1159 if (SkStrokeRec::kHairline_Style == style) { 1165 if (SkStrokeRec::kHairline_Style == style) {
1160 scaledStroke.set(1, 1); 1166 scaledStroke.set(1, 1);
1161 } else { 1167 } else {
1162 scaledStroke.fX = SkScalarAbs(strokeWidth*(vm[SkMatrix::kMScaleX] + 1168 scaledStroke.fX = SkScalarAbs(strokeWidth*(viewMatrix[SkMatrix::kMSc aleX] +
1163 vm[SkMatrix::kMSkewY])); 1169 viewMatrix[SkMatrix::kMSk ewY]));
1164 scaledStroke.fY = SkScalarAbs(strokeWidth*(vm[SkMatrix::kMSkewX] + 1170 scaledStroke.fY = SkScalarAbs(strokeWidth*(viewMatrix[SkMatrix::kMSk ewX] +
1165 vm[SkMatrix::kMScaleY])); 1171 viewMatrix[SkMatrix::kMSc aleY]));
1166 } 1172 }
1167 1173
1168 // if half of strokewidth is greater than radius, we don't handle that r ight now 1174 // if half of strokewidth is greater than radius, we don't handle that r ight now
1169 if (SK_ScalarHalf*scaledStroke.fX > xRadius || SK_ScalarHalf*scaledStrok e.fY > yRadius) { 1175 if (SK_ScalarHalf*scaledStroke.fX > xRadius || SK_ScalarHalf*scaledStrok e.fY > yRadius) {
1170 return false; 1176 return false;
1171 } 1177 }
1172 } 1178 }
1173 1179
1174 // The way the effect interpolates the offset-to-ellipse/circle-center attri bute only works on 1180 // The way the effect interpolates the offset-to-ellipse/circle-center attri bute only works on
1175 // the interior of the rrect if the radii are >= 0.5. Otherwise, the inner r ect of the nine- 1181 // the interior of the rrect if the radii are >= 0.5. Otherwise, the inner r ect of the nine-
1176 // patch will have fractional coverage. This only matters when the interior is actually filled. 1182 // patch will have fractional coverage. This only matters when the interior is actually filled.
1177 // We could consider falling back to rect rendering here, since a tiny radiu s is 1183 // We could consider falling back to rect rendering here, since a tiny radiu s is
1178 // indistinguishable from a square corner. 1184 // indistinguishable from a square corner.
1179 if (!isStrokeOnly && (SK_ScalarHalf > xRadius || SK_ScalarHalf > yRadius)) { 1185 if (!isStrokeOnly && (SK_ScalarHalf > xRadius || SK_ScalarHalf > yRadius)) {
1180 return false; 1186 return false;
1181 } 1187 }
1182 1188
1183 // reset to device coordinates 1189 // reset to device coordinates
1184 SkMatrix invert; 1190 SkMatrix invert;
1185 if (!vm.invert(&invert)) { 1191 if (!viewMatrix.invert(&invert)) {
1186 SkDebugf("Failed to invert\n"); 1192 SkDebugf("Failed to invert\n");
1187 return false; 1193 return false;
1188 } 1194 }
1189 1195
1190 GrDrawState::AutoViewMatrixRestore avmr(drawState);
1191
1192 GrIndexBuffer* indexBuffer = this->rRectIndexBuffer(isStrokeOnly); 1196 GrIndexBuffer* indexBuffer = this->rRectIndexBuffer(isStrokeOnly);
1193 if (NULL == indexBuffer) { 1197 if (NULL == indexBuffer) {
1194 SkDebugf("Failed to create index buffer!\n"); 1198 SkDebugf("Failed to create index buffer!\n");
1195 return false; 1199 return false;
1196 } 1200 }
1197 1201
1198 // if the corners are circles, use the circle renderer 1202 // if the corners are circles, use the circle renderer
1199 if ((!hasStroke || scaledStroke.fX == scaledStroke.fY) && xRadius == yRadius ) { 1203 if ((!hasStroke || scaledStroke.fX == scaledStroke.fY) && xRadius == yRadius ) {
1200 SkScalar innerRadius = 0.0f; 1204 SkScalar innerRadius = 0.0f;
1201 SkScalar outerRadius = xRadius; 1205 SkScalar outerRadius = xRadius;
1202 SkScalar halfWidth = 0; 1206 SkScalar halfWidth = 0;
1203 if (hasStroke) { 1207 if (hasStroke) {
1204 if (SkScalarNearlyZero(scaledStroke.fX)) { 1208 if (SkScalarNearlyZero(scaledStroke.fX)) {
1205 halfWidth = SK_ScalarHalf; 1209 halfWidth = SK_ScalarHalf;
1206 } else { 1210 } else {
1207 halfWidth = SkScalarHalf(scaledStroke.fX); 1211 halfWidth = SkScalarHalf(scaledStroke.fX);
1208 } 1212 }
1209 1213
1210 if (isStrokeOnly) { 1214 if (isStrokeOnly) {
1211 innerRadius = xRadius - halfWidth; 1215 innerRadius = xRadius - halfWidth;
1212 } 1216 }
1213 outerRadius += halfWidth; 1217 outerRadius += halfWidth;
1214 bounds.outset(halfWidth, halfWidth); 1218 bounds.outset(halfWidth, halfWidth);
1215 } 1219 }
1216 1220
1217 isStrokeOnly = (isStrokeOnly && innerRadius >= 0); 1221 isStrokeOnly = (isStrokeOnly && innerRadius >= 0);
1218 1222
1219 SkAutoTUnref<GrGeometryProcessor> effect(CircleEdgeEffect::Create(color, isStrokeOnly, 1223 SkAutoTUnref<GrGeometryProcessor> effect(CircleEdgeEffect::Create(color,
1224 SkMatr ix::I(),
1225 isStro keOnly,
1220 invert )); 1226 invert ));
1221 1227
1222 GrDrawTarget::AutoReleaseGeometry geo(target, 16, effect->getVertexStrid e(), 0); 1228 GrDrawTarget::AutoReleaseGeometry geo(target, 16, effect->getVertexStrid e(), 0);
1223 SkASSERT(effect->getVertexStride() == sizeof(CircleVertex)); 1229 SkASSERT(effect->getVertexStride() == sizeof(CircleVertex));
1224 if (!geo.succeeded()) { 1230 if (!geo.succeeded()) {
1225 SkDebugf("Failed to get space for vertices!\n"); 1231 SkDebugf("Failed to get space for vertices!\n");
1226 return false; 1232 return false;
1227 } 1233 }
1228 CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices()); 1234 CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices());
1229 1235
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1309 innerYRadius = yRadius - scaledStroke.fY; 1315 innerYRadius = yRadius - scaledStroke.fY;
1310 } 1316 }
1311 1317
1312 xRadius += scaledStroke.fX; 1318 xRadius += scaledStroke.fX;
1313 yRadius += scaledStroke.fY; 1319 yRadius += scaledStroke.fY;
1314 bounds.outset(scaledStroke.fX, scaledStroke.fY); 1320 bounds.outset(scaledStroke.fX, scaledStroke.fY);
1315 } 1321 }
1316 1322
1317 isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0); 1323 isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0);
1318 1324
1319 SkAutoTUnref<GrGeometryProcessor> effect(EllipseEdgeEffect::Create(color , isStrokeOnly, 1325 SkAutoTUnref<GrGeometryProcessor> effect(EllipseEdgeEffect::Create(color ,
1326 SkMat rix::I(),
1327 isStr okeOnly,
1320 inver t)); 1328 inver t));
1321 1329
1322 GrDrawTarget::AutoReleaseGeometry geo(target, 16, effect->getVertexStrid e(), 0); 1330 GrDrawTarget::AutoReleaseGeometry geo(target, 16, effect->getVertexStrid e(), 0);
1323 SkASSERT(effect->getVertexStride() == sizeof(EllipseVertex)); 1331 SkASSERT(effect->getVertexStride() == sizeof(EllipseVertex));
1324 if (!geo.succeeded()) { 1332 if (!geo.succeeded()) {
1325 SkDebugf("Failed to get space for vertices!\n"); 1333 SkDebugf("Failed to get space for vertices!\n");
1326 return false; 1334 return false;
1327 } 1335 }
1328 1336
1329 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); 1337 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices());
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1384 int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 : 1392 int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 :
1385 SK_ARRAY_COUNT(gRRectIndices); 1393 SK_ARRAY_COUNT(gRRectIndices);
1386 target->setIndexSourceToBuffer(indexBuffer); 1394 target->setIndexSourceToBuffer(indexBuffer);
1387 target->drawIndexedInstances(drawState, effect, kTriangles_GrPrimitiveTy pe, 1, 16, indexCnt, 1395 target->drawIndexedInstances(drawState, effect, kTriangles_GrPrimitiveTy pe, 1, 16, indexCnt,
1388 &bounds); 1396 &bounds);
1389 } 1397 }
1390 1398
1391 target->resetIndexSource(); 1399 target->resetIndexSource();
1392 return true; 1400 return true;
1393 } 1401 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698