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 "gl/builders/GrGLProgramBuilder.h" | 10 #include "gl/builders/GrGLProgramBuilder.h" |
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 return DIEllipseEdgeEffect::Create((Mode)(random->nextRangeU(0,2))); | 474 return DIEllipseEdgeEffect::Create((Mode)(random->nextRangeU(0,2))); |
475 } | 475 } |
476 | 476 |
477 /////////////////////////////////////////////////////////////////////////////// | 477 /////////////////////////////////////////////////////////////////////////////// |
478 | 478 |
479 void GrOvalRenderer::reset() { | 479 void GrOvalRenderer::reset() { |
480 SkSafeSetNull(fRRectIndexBuffer); | 480 SkSafeSetNull(fRRectIndexBuffer); |
481 SkSafeSetNull(fStrokeRRectIndexBuffer); | 481 SkSafeSetNull(fStrokeRRectIndexBuffer); |
482 } | 482 } |
483 | 483 |
484 bool GrOvalRenderer::drawOval(GrDrawTarget* target, const GrContext* context, bo
ol useAA, | 484 bool GrOvalRenderer::drawOval(GrDrawTarget* target, |
485 const SkRect& oval, const SkStrokeRec& stroke) | 485 GrDrawState* drawState, |
| 486 const GrContext* context, |
| 487 bool useAA, |
| 488 const SkRect& oval, |
| 489 const SkStrokeRec& stroke) |
486 { | 490 { |
487 bool useCoverageAA = useAA && | 491 bool useCoverageAA = useAA && |
488 !target->getDrawState().getRenderTarget()->isMultisampled() && | 492 !drawState->getRenderTarget()->isMultisampled() && |
489 !target->shouldDisableCoverageAAForBlend(); | 493 drawState->couldApplyCoverage(*target->caps()); |
490 | 494 |
491 if (!useCoverageAA) { | 495 if (!useCoverageAA) { |
492 return false; | 496 return false; |
493 } | 497 } |
494 | 498 |
495 const SkMatrix& vm = context->getMatrix(); | 499 const SkMatrix& vm = context->getMatrix(); |
496 | 500 |
497 // we can draw circles | 501 // we can draw circles |
498 if (SkScalarNearlyEqual(oval.width(), oval.height()) | 502 if (SkScalarNearlyEqual(oval.width(), oval.height()) |
499 && circle_stays_circle(vm)) { | 503 && circle_stays_circle(vm)) { |
500 this->drawCircle(target, context, useCoverageAA, oval, stroke); | 504 this->drawCircle(target, drawState, context, useCoverageAA, oval, stroke
); |
501 // if we have shader derivative support, render as device-independent | 505 // if we have shader derivative support, render as device-independent |
502 } else if (target->caps()->shaderDerivativeSupport()) { | 506 } else if (target->caps()->shaderDerivativeSupport()) { |
503 return this->drawDIEllipse(target, context, useCoverageAA, oval, stroke)
; | 507 return this->drawDIEllipse(target, drawState, context, useCoverageAA, ov
al, stroke); |
504 // otherwise axis-aligned ellipses only | 508 // otherwise axis-aligned ellipses only |
505 } else if (vm.rectStaysRect()) { | 509 } else if (vm.rectStaysRect()) { |
506 return this->drawEllipse(target, context, useCoverageAA, oval, stroke); | 510 return this->drawEllipse(target, drawState, context, useCoverageAA, oval
, stroke); |
507 } else { | 511 } else { |
508 return false; | 512 return false; |
509 } | 513 } |
510 | 514 |
511 return true; | 515 return true; |
512 } | 516 } |
513 | 517 |
514 /////////////////////////////////////////////////////////////////////////////// | 518 /////////////////////////////////////////////////////////////////////////////// |
515 | 519 |
516 // position + edge | 520 // position + edge |
517 extern const GrVertexAttrib gCircleVertexAttribs[] = { | 521 extern const GrVertexAttrib gCircleVertexAttribs[] = { |
518 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding
}, | 522 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding
}, |
519 {kVec4f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAttr
ibBinding} | 523 {kVec4f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAttr
ibBinding} |
520 }; | 524 }; |
521 | 525 |
522 void GrOvalRenderer::drawCircle(GrDrawTarget* target, | 526 void GrOvalRenderer::drawCircle(GrDrawTarget* target, |
| 527 GrDrawState* drawState, |
523 const GrContext* context, | 528 const GrContext* context, |
524 bool useCoverageAA, | 529 bool useCoverageAA, |
525 const SkRect& circle, | 530 const SkRect& circle, |
526 const SkStrokeRec& stroke) | 531 const SkStrokeRec& stroke) |
527 { | 532 { |
528 GrDrawState* drawState = target->drawState(); | |
529 | |
530 const SkMatrix& vm = drawState->getViewMatrix(); | 533 const SkMatrix& vm = drawState->getViewMatrix(); |
531 SkPoint center = SkPoint::Make(circle.centerX(), circle.centerY()); | 534 SkPoint center = SkPoint::Make(circle.centerX(), circle.centerY()); |
532 vm.mapPoints(¢er, 1); | 535 vm.mapPoints(¢er, 1); |
533 SkScalar radius = vm.mapRadius(SkScalarHalf(circle.width())); | 536 SkScalar radius = vm.mapRadius(SkScalarHalf(circle.width())); |
534 SkScalar strokeWidth = vm.mapRadius(stroke.getWidth()); | 537 SkScalar strokeWidth = vm.mapRadius(stroke.getWidth()); |
535 | 538 |
536 GrDrawState::AutoViewMatrixRestore avmr; | 539 GrDrawState::AutoViewMatrixRestore avmr; |
537 if (!avmr.setIdentity(drawState)) { | 540 if (!avmr.setIdentity(drawState)) { |
538 return; | 541 return; |
539 } | 542 } |
540 | 543 |
541 drawState->setVertexAttribs<gCircleVertexAttribs>(SK_ARRAY_COUNT(gCircleVert
exAttribs), | 544 drawState->setVertexAttribs<gCircleVertexAttribs>(SK_ARRAY_COUNT(gCircleVert
exAttribs), |
542 sizeof(CircleVertex)); | 545 sizeof(CircleVertex)); |
543 | 546 |
544 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); | 547 GrDrawTarget::AutoReleaseGeometry geo(target, 4, drawState->getVertexStride(
), 0); |
545 if (!geo.succeeded()) { | 548 if (!geo.succeeded()) { |
546 SkDebugf("Failed to get space for vertices!\n"); | 549 SkDebugf("Failed to get space for vertices!\n"); |
547 return; | 550 return; |
548 } | 551 } |
549 | 552 |
550 CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices()); | 553 CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices()); |
551 | 554 |
552 SkStrokeRec::Style style = stroke.getStyle(); | 555 SkStrokeRec::Style style = stroke.getStyle(); |
553 bool isStrokeOnly = SkStrokeRec::kStroke_Style == style || | 556 bool isStrokeOnly = SkStrokeRec::kStroke_Style == style || |
554 SkStrokeRec::kHairline_Style == style; | 557 SkStrokeRec::kHairline_Style == style; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
601 verts[2].fOffset = SkPoint::Make(outerRadius, outerRadius); | 604 verts[2].fOffset = SkPoint::Make(outerRadius, outerRadius); |
602 verts[2].fOuterRadius = outerRadius; | 605 verts[2].fOuterRadius = outerRadius; |
603 verts[2].fInnerRadius = innerRadius; | 606 verts[2].fInnerRadius = innerRadius; |
604 | 607 |
605 verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fTop); | 608 verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fTop); |
606 verts[3].fOffset = SkPoint::Make(outerRadius, -outerRadius); | 609 verts[3].fOffset = SkPoint::Make(outerRadius, -outerRadius); |
607 verts[3].fOuterRadius = outerRadius; | 610 verts[3].fOuterRadius = outerRadius; |
608 verts[3].fInnerRadius = innerRadius; | 611 verts[3].fInnerRadius = innerRadius; |
609 | 612 |
610 target->setIndexSourceToBuffer(context->getGpu()->getQuadIndexBuffer()); | 613 target->setIndexSourceToBuffer(context->getGpu()->getQuadIndexBuffer()); |
611 target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6, &bounds); | 614 target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 4, 6,
&bounds); |
612 target->resetIndexSource(); | 615 target->resetIndexSource(); |
613 } | 616 } |
614 | 617 |
615 /////////////////////////////////////////////////////////////////////////////// | 618 /////////////////////////////////////////////////////////////////////////////// |
616 | 619 |
617 // position + offset + 1/radii | 620 // position + offset + 1/radii |
618 extern const GrVertexAttrib gEllipseVertexAttribs[] = { | 621 extern const GrVertexAttrib gEllipseVertexAttribs[] = { |
619 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBindi
ng}, | 622 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBindi
ng}, |
620 {kVec2f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAt
tribBinding}, | 623 {kVec2f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAt
tribBinding}, |
621 {kVec4f_GrVertexAttribType, 2*sizeof(SkPoint), kGeometryProcessor_GrVertexAt
tribBinding} | 624 {kVec4f_GrVertexAttribType, 2*sizeof(SkPoint), kGeometryProcessor_GrVertexAt
tribBinding} |
622 }; | 625 }; |
623 | 626 |
624 // position + offsets | 627 // position + offsets |
625 extern const GrVertexAttrib gDIEllipseVertexAttribs[] = { | 628 extern const GrVertexAttrib gDIEllipseVertexAttribs[] = { |
626 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBindi
ng}, | 629 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBindi
ng}, |
627 {kVec2f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAt
tribBinding}, | 630 {kVec2f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAt
tribBinding}, |
628 {kVec2f_GrVertexAttribType, 2*sizeof(SkPoint), kGeometryProcessor_GrVertexAt
tribBinding}, | 631 {kVec2f_GrVertexAttribType, 2*sizeof(SkPoint), kGeometryProcessor_GrVertexAt
tribBinding}, |
629 }; | 632 }; |
630 | 633 |
631 bool GrOvalRenderer::drawEllipse(GrDrawTarget* target, | 634 bool GrOvalRenderer::drawEllipse(GrDrawTarget* target, |
| 635 GrDrawState* drawState, |
632 const GrContext* context, | 636 const GrContext* context, |
633 bool useCoverageAA, | 637 bool useCoverageAA, |
634 const SkRect& ellipse, | 638 const SkRect& ellipse, |
635 const SkStrokeRec& stroke) | 639 const SkStrokeRec& stroke) |
636 { | 640 { |
637 GrDrawState* drawState = target->drawState(); | |
638 #ifdef SK_DEBUG | 641 #ifdef SK_DEBUG |
639 { | 642 { |
640 // we should have checked for this previously | 643 // we should have checked for this previously |
641 bool isAxisAlignedEllipse = drawState->getViewMatrix().rectStaysRect(); | 644 bool isAxisAlignedEllipse = drawState->getViewMatrix().rectStaysRect(); |
642 SkASSERT(useCoverageAA && isAxisAlignedEllipse); | 645 SkASSERT(useCoverageAA && isAxisAlignedEllipse); |
643 } | 646 } |
644 #endif | 647 #endif |
645 | 648 |
646 // do any matrix crunching before we reset the draw state for device coords | 649 // do any matrix crunching before we reset the draw state for device coords |
647 const SkMatrix& vm = drawState->getViewMatrix(); | 650 const SkMatrix& vm = drawState->getViewMatrix(); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
697 } | 700 } |
698 | 701 |
699 GrDrawState::AutoViewMatrixRestore avmr; | 702 GrDrawState::AutoViewMatrixRestore avmr; |
700 if (!avmr.setIdentity(drawState)) { | 703 if (!avmr.setIdentity(drawState)) { |
701 return false; | 704 return false; |
702 } | 705 } |
703 | 706 |
704 drawState->setVertexAttribs<gEllipseVertexAttribs>(SK_ARRAY_COUNT(gEllipseVe
rtexAttribs), | 707 drawState->setVertexAttribs<gEllipseVertexAttribs>(SK_ARRAY_COUNT(gEllipseVe
rtexAttribs), |
705 sizeof(EllipseVertex)); | 708 sizeof(EllipseVertex)); |
706 | 709 |
707 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); | 710 GrDrawTarget::AutoReleaseGeometry geo(target, 4, drawState->getVertexStride(
), 0); |
708 if (!geo.succeeded()) { | 711 if (!geo.succeeded()) { |
709 SkDebugf("Failed to get space for vertices!\n"); | 712 SkDebugf("Failed to get space for vertices!\n"); |
710 return false; | 713 return false; |
711 } | 714 } |
712 | 715 |
713 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); | 716 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); |
714 | 717 |
715 GrGeometryProcessor* gp = EllipseEdgeEffect::Create(isStrokeOnly && | 718 GrGeometryProcessor* gp = EllipseEdgeEffect::Create(isStrokeOnly && |
716 innerXRadius > 0 && inne
rYRadius > 0); | 719 innerXRadius > 0 && inne
rYRadius > 0); |
717 | 720 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
750 verts[2].fOffset = SkPoint::Make(xRadius, yRadius); | 753 verts[2].fOffset = SkPoint::Make(xRadius, yRadius); |
751 verts[2].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); | 754 verts[2].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); |
752 verts[2].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip); | 755 verts[2].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip); |
753 | 756 |
754 verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fTop); | 757 verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fTop); |
755 verts[3].fOffset = SkPoint::Make(xRadius, -yRadius); | 758 verts[3].fOffset = SkPoint::Make(xRadius, -yRadius); |
756 verts[3].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); | 759 verts[3].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); |
757 verts[3].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip); | 760 verts[3].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip); |
758 | 761 |
759 target->setIndexSourceToBuffer(context->getGpu()->getQuadIndexBuffer()); | 762 target->setIndexSourceToBuffer(context->getGpu()->getQuadIndexBuffer()); |
760 target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6, &bounds); | 763 target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 4, 6,
&bounds); |
761 target->resetIndexSource(); | 764 target->resetIndexSource(); |
762 | 765 |
763 return true; | 766 return true; |
764 } | 767 } |
765 | 768 |
766 bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target, | 769 bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target, |
| 770 GrDrawState* drawState, |
767 const GrContext* context, | 771 const GrContext* context, |
768 bool useCoverageAA, | 772 bool useCoverageAA, |
769 const SkRect& ellipse, | 773 const SkRect& ellipse, |
770 const SkStrokeRec& stroke) | 774 const SkStrokeRec& stroke) |
771 { | 775 { |
772 GrDrawState* drawState = target->drawState(); | |
773 const SkMatrix& vm = drawState->getViewMatrix(); | 776 const SkMatrix& vm = drawState->getViewMatrix(); |
774 | 777 |
775 SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY()); | 778 SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY()); |
776 SkScalar xRadius = SkScalarHalf(ellipse.width()); | 779 SkScalar xRadius = SkScalarHalf(ellipse.width()); |
777 SkScalar yRadius = SkScalarHalf(ellipse.height()); | 780 SkScalar yRadius = SkScalarHalf(ellipse.height()); |
778 | 781 |
779 SkStrokeRec::Style style = stroke.getStyle(); | 782 SkStrokeRec::Style style = stroke.getStyle(); |
780 DIEllipseEdgeEffect::Mode mode = (SkStrokeRec::kStroke_Style == style) ? | 783 DIEllipseEdgeEffect::Mode mode = (SkStrokeRec::kStroke_Style == style) ? |
781 DIEllipseEdgeEffect::kStroke : | 784 DIEllipseEdgeEffect::kStroke : |
782 (SkStrokeRec::kHairline_Style == style) ? | 785 (SkStrokeRec::kHairline_Style == style) ? |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
817 if (DIEllipseEdgeEffect::kStroke == mode) { | 820 if (DIEllipseEdgeEffect::kStroke == mode) { |
818 mode = (innerXRadius > 0 && innerYRadius > 0) ? DIEllipseEdgeEffect::kSt
roke : | 821 mode = (innerXRadius > 0 && innerYRadius > 0) ? DIEllipseEdgeEffect::kSt
roke : |
819 DIEllipseEdgeEffect::kFi
ll; | 822 DIEllipseEdgeEffect::kFi
ll; |
820 } | 823 } |
821 SkScalar innerRatioX = SkScalarDiv(xRadius, innerXRadius); | 824 SkScalar innerRatioX = SkScalarDiv(xRadius, innerXRadius); |
822 SkScalar innerRatioY = SkScalarDiv(yRadius, innerYRadius); | 825 SkScalar innerRatioY = SkScalarDiv(yRadius, innerYRadius); |
823 | 826 |
824 drawState->setVertexAttribs<gDIEllipseVertexAttribs>(SK_ARRAY_COUNT(gDIEllip
seVertexAttribs), | 827 drawState->setVertexAttribs<gDIEllipseVertexAttribs>(SK_ARRAY_COUNT(gDIEllip
seVertexAttribs), |
825 sizeof(DIEllipseVertex)
); | 828 sizeof(DIEllipseVertex)
); |
826 | 829 |
827 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); | 830 GrDrawTarget::AutoReleaseGeometry geo(target, 4, drawState->getVertexStride(
), 0); |
828 if (!geo.succeeded()) { | 831 if (!geo.succeeded()) { |
829 SkDebugf("Failed to get space for vertices!\n"); | 832 SkDebugf("Failed to get space for vertices!\n"); |
830 return false; | 833 return false; |
831 } | 834 } |
832 | 835 |
833 DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(geo.vertices()); | 836 DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(geo.vertices()); |
834 | 837 |
835 GrGeometryProcessor* gp = DIEllipseEdgeEffect::Create(mode); | 838 GrGeometryProcessor* gp = DIEllipseEdgeEffect::Create(mode); |
836 | 839 |
837 drawState->setGeometryProcessor(gp)->unref(); | 840 drawState->setGeometryProcessor(gp)->unref(); |
(...skipping 26 matching lines...) Expand all Loading... |
864 | 867 |
865 verts[2].fPos = SkPoint::Make(bounds.fRight, bounds.fBottom); | 868 verts[2].fPos = SkPoint::Make(bounds.fRight, bounds.fBottom); |
866 verts[2].fOuterOffset = SkPoint::Make(1.0f + offsetDx, 1.0f + offsetDy); | 869 verts[2].fOuterOffset = SkPoint::Make(1.0f + offsetDx, 1.0f + offsetDy); |
867 verts[2].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, innerRatioY +
offsetDy); | 870 verts[2].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, innerRatioY +
offsetDy); |
868 | 871 |
869 verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fTop); | 872 verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fTop); |
870 verts[3].fOuterOffset = SkPoint::Make(1.0f + offsetDx, -1.0f - offsetDy); | 873 verts[3].fOuterOffset = SkPoint::Make(1.0f + offsetDx, -1.0f - offsetDy); |
871 verts[3].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, -innerRatioY -
offsetDy); | 874 verts[3].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, -innerRatioY -
offsetDy); |
872 | 875 |
873 target->setIndexSourceToBuffer(context->getGpu()->getQuadIndexBuffer()); | 876 target->setIndexSourceToBuffer(context->getGpu()->getQuadIndexBuffer()); |
874 target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6, &bounds); | 877 target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 4, 6,
&bounds); |
875 target->resetIndexSource(); | 878 target->resetIndexSource(); |
876 | 879 |
877 return true; | 880 return true; |
878 } | 881 } |
879 | 882 |
880 /////////////////////////////////////////////////////////////////////////////// | 883 /////////////////////////////////////////////////////////////////////////////// |
881 | 884 |
882 static const uint16_t gRRectIndices[] = { | 885 static const uint16_t gRRectIndices[] = { |
883 // corners | 886 // corners |
884 0, 1, 5, 0, 5, 4, | 887 0, 1, 5, 0, 5, 4, |
(...skipping 30 matching lines...) Expand all Loading... |
915 if (NULL == fRRectIndexBuffer) { | 918 if (NULL == fRRectIndexBuffer) { |
916 fRRectIndexBuffer = gpu->createInstancedIndexBuffer(gRRectIndices, | 919 fRRectIndexBuffer = gpu->createInstancedIndexBuffer(gRRectIndices, |
917 kIndicesPerRRect
, | 920 kIndicesPerRRect
, |
918 kNumRRectsInInde
xBuffer, | 921 kNumRRectsInInde
xBuffer, |
919 kVertsPerRRect); | 922 kVertsPerRRect); |
920 } | 923 } |
921 return fRRectIndexBuffer; | 924 return fRRectIndexBuffer; |
922 } | 925 } |
923 } | 926 } |
924 | 927 |
925 bool GrOvalRenderer::drawDRRect(GrDrawTarget* target, GrContext* context, bool u
seAA, | 928 bool GrOvalRenderer::drawDRRect(GrDrawTarget* target, |
926 const SkRRect& origOuter, const SkRRect& origInn
er) { | 929 GrDrawState* drawState, |
| 930 GrContext* context, |
| 931 bool useAA, |
| 932 const SkRRect& origOuter, |
| 933 const SkRRect& origInner) { |
927 bool applyAA = useAA && | 934 bool applyAA = useAA && |
928 !target->getDrawState().getRenderTarget()->isMultisampled() &
& | 935 !drawState->getRenderTarget()->isMultisampled() && |
929 !target->shouldDisableCoverageAAForBlend(); | 936 drawState->couldApplyCoverage(*target->caps()); |
930 GrDrawState::AutoRestoreEffects are; | 937 GrDrawState::AutoRestoreEffects are; |
931 if (!origInner.isEmpty()) { | 938 if (!origInner.isEmpty()) { |
932 SkTCopyOnFirstWrite<SkRRect> inner(origInner); | 939 SkTCopyOnFirstWrite<SkRRect> inner(origInner); |
933 if (!context->getMatrix().isIdentity()) { | 940 if (!context->getMatrix().isIdentity()) { |
934 if (!origInner.transform(context->getMatrix(), inner.writable())) { | 941 if (!origInner.transform(context->getMatrix(), inner.writable())) { |
935 return false; | 942 return false; |
936 } | 943 } |
937 } | 944 } |
938 GrPrimitiveEdgeType edgeType = applyAA ? | 945 GrPrimitiveEdgeType edgeType = applyAA ? |
939 kInverseFillAA_GrProcessorEdgeType : | 946 kInverseFillAA_GrProcessorEdgeType : |
940 kInverseFillBW_GrProcessorEdgeType; | 947 kInverseFillBW_GrProcessorEdgeType; |
941 GrFragmentProcessor* fp = GrRRectEffect::Create(edgeType, *inner); | 948 GrFragmentProcessor* fp = GrRRectEffect::Create(edgeType, *inner); |
942 if (NULL == fp) { | 949 if (NULL == fp) { |
943 return false; | 950 return false; |
944 } | 951 } |
945 are.set(target->drawState()); | 952 are.set(drawState); |
946 target->drawState()->addCoverageProcessor(fp)->unref(); | 953 drawState->addCoverageProcessor(fp)->unref(); |
947 } | 954 } |
948 | 955 |
949 SkStrokeRec fillRec(SkStrokeRec::kFill_InitStyle); | 956 SkStrokeRec fillRec(SkStrokeRec::kFill_InitStyle); |
950 if (this->drawRRect(target, context, useAA, origOuter, fillRec)) { | 957 if (this->drawRRect(target, drawState, context, useAA, origOuter, fillRec))
{ |
951 return true; | 958 return true; |
952 } | 959 } |
953 | 960 |
954 SkASSERT(!origOuter.isEmpty()); | 961 SkASSERT(!origOuter.isEmpty()); |
955 SkTCopyOnFirstWrite<SkRRect> outer(origOuter); | 962 SkTCopyOnFirstWrite<SkRRect> outer(origOuter); |
956 if (!context->getMatrix().isIdentity()) { | 963 if (!context->getMatrix().isIdentity()) { |
957 if (!origOuter.transform(context->getMatrix(), outer.writable())) { | 964 if (!origOuter.transform(context->getMatrix(), outer.writable())) { |
958 return false; | 965 return false; |
959 } | 966 } |
960 } | 967 } |
961 GrPrimitiveEdgeType edgeType = applyAA ? kFillAA_GrProcessorEdgeType : | 968 GrPrimitiveEdgeType edgeType = applyAA ? kFillAA_GrProcessorEdgeType : |
962 kFillBW_GrProcessorEdgeType; | 969 kFillBW_GrProcessorEdgeType; |
963 GrFragmentProcessor* effect = GrRRectEffect::Create(edgeType, *outer); | 970 GrFragmentProcessor* effect = GrRRectEffect::Create(edgeType, *outer); |
964 if (NULL == effect) { | 971 if (NULL == effect) { |
965 return false; | 972 return false; |
966 } | 973 } |
967 if (!are.isSet()) { | 974 if (!are.isSet()) { |
968 are.set(target->drawState()); | 975 are.set(drawState); |
969 } | 976 } |
970 GrDrawState::AutoViewMatrixRestore avmr; | 977 GrDrawState::AutoViewMatrixRestore avmr; |
971 if (!avmr.setIdentity(target->drawState())) { | 978 if (!avmr.setIdentity(drawState)) { |
972 return false; | 979 return false; |
973 } | 980 } |
974 target->drawState()->addCoverageProcessor(effect)->unref(); | 981 drawState->addCoverageProcessor(effect)->unref(); |
975 SkRect bounds = outer->getBounds(); | 982 SkRect bounds = outer->getBounds(); |
976 if (applyAA) { | 983 if (applyAA) { |
977 bounds.outset(SK_ScalarHalf, SK_ScalarHalf); | 984 bounds.outset(SK_ScalarHalf, SK_ScalarHalf); |
978 } | 985 } |
979 target->drawRect(bounds, NULL, NULL); | 986 target->drawRect(drawState, bounds, NULL, NULL); |
980 return true; | 987 return true; |
981 } | 988 } |
982 | 989 |
983 bool GrOvalRenderer::drawRRect(GrDrawTarget* target, GrContext* context, bool us
eAA, | 990 bool GrOvalRenderer::drawRRect(GrDrawTarget* target, |
984 const SkRRect& rrect, const SkStrokeRec& stroke)
{ | 991 GrDrawState* drawState, |
| 992 GrContext* context, |
| 993 bool useAA, |
| 994 const SkRRect& rrect, |
| 995 const SkStrokeRec& stroke) { |
985 if (rrect.isOval()) { | 996 if (rrect.isOval()) { |
986 return this->drawOval(target, context, useAA, rrect.getBounds(), stroke)
; | 997 return this->drawOval(target, drawState, context, useAA, rrect.getBounds
(), stroke); |
987 } | 998 } |
988 | 999 |
989 bool useCoverageAA = useAA && | 1000 bool useCoverageAA = useAA && |
990 !target->getDrawState().getRenderTarget()->isMultisampled() && | 1001 !drawState->getRenderTarget()->isMultisampled() && |
991 !target->shouldDisableCoverageAAForBlend(); | 1002 drawState->couldApplyCoverage(*target->caps()); |
992 | 1003 |
993 // only anti-aliased rrects for now | 1004 // only anti-aliased rrects for now |
994 if (!useCoverageAA) { | 1005 if (!useCoverageAA) { |
995 return false; | 1006 return false; |
996 } | 1007 } |
997 | 1008 |
998 const SkMatrix& vm = context->getMatrix(); | 1009 const SkMatrix& vm = context->getMatrix(); |
999 | 1010 |
1000 if (!vm.rectStaysRect() || !rrect.isSimple()) { | 1011 if (!vm.rectStaysRect() || !rrect.isSimple()) { |
1001 return false; | 1012 return false; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1041 // The way the effect interpolates the offset-to-ellipse/circle-center attri
bute only works on | 1052 // The way the effect interpolates the offset-to-ellipse/circle-center attri
bute only works on |
1042 // the interior of the rrect if the radii are >= 0.5. Otherwise, the inner r
ect of the nine- | 1053 // the interior of the rrect if the radii are >= 0.5. Otherwise, the inner r
ect of the nine- |
1043 // patch will have fractional coverage. This only matters when the interior
is actually filled. | 1054 // patch will have fractional coverage. This only matters when the interior
is actually filled. |
1044 // We could consider falling back to rect rendering here, since a tiny radiu
s is | 1055 // We could consider falling back to rect rendering here, since a tiny radiu
s is |
1045 // indistinguishable from a square corner. | 1056 // indistinguishable from a square corner. |
1046 if (!isStrokeOnly && (SK_ScalarHalf > xRadius || SK_ScalarHalf > yRadius)) { | 1057 if (!isStrokeOnly && (SK_ScalarHalf > xRadius || SK_ScalarHalf > yRadius)) { |
1047 return false; | 1058 return false; |
1048 } | 1059 } |
1049 | 1060 |
1050 // reset to device coordinates | 1061 // reset to device coordinates |
1051 GrDrawState* drawState = target->drawState(); | |
1052 GrDrawState::AutoViewMatrixRestore avmr; | 1062 GrDrawState::AutoViewMatrixRestore avmr; |
1053 if (!avmr.setIdentity(drawState)) { | 1063 if (!avmr.setIdentity(drawState)) { |
1054 return false; | 1064 return false; |
1055 } | 1065 } |
1056 | 1066 |
1057 GrIndexBuffer* indexBuffer = this->rRectIndexBuffer(isStrokeOnly, context->g
etGpu()); | 1067 GrIndexBuffer* indexBuffer = this->rRectIndexBuffer(isStrokeOnly, context->g
etGpu()); |
1058 if (NULL == indexBuffer) { | 1068 if (NULL == indexBuffer) { |
1059 SkDebugf("Failed to create index buffer!\n"); | 1069 SkDebugf("Failed to create index buffer!\n"); |
1060 return false; | 1070 return false; |
1061 } | 1071 } |
1062 | 1072 |
1063 // if the corners are circles, use the circle renderer | 1073 // if the corners are circles, use the circle renderer |
1064 if ((!hasStroke || scaledStroke.fX == scaledStroke.fY) && xRadius == yRadius
) { | 1074 if ((!hasStroke || scaledStroke.fX == scaledStroke.fY) && xRadius == yRadius
) { |
1065 drawState->setVertexAttribs<gCircleVertexAttribs>(SK_ARRAY_COUNT(gCircle
VertexAttribs), | 1075 drawState->setVertexAttribs<gCircleVertexAttribs>(SK_ARRAY_COUNT(gCircle
VertexAttribs), |
1066 sizeof(CircleVertex)); | 1076 sizeof(CircleVertex)); |
1067 | 1077 |
1068 GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0); | 1078 GrDrawTarget::AutoReleaseGeometry geo(target, 16, drawState->getVertexSt
ride(), 0); |
1069 if (!geo.succeeded()) { | 1079 if (!geo.succeeded()) { |
1070 SkDebugf("Failed to get space for vertices!\n"); | 1080 SkDebugf("Failed to get space for vertices!\n"); |
1071 return false; | 1081 return false; |
1072 } | 1082 } |
1073 CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices()); | 1083 CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices()); |
1074 | 1084 |
1075 SkScalar innerRadius = 0.0f; | 1085 SkScalar innerRadius = 0.0f; |
1076 SkScalar outerRadius = xRadius; | 1086 SkScalar outerRadius = xRadius; |
1077 SkScalar halfWidth = 0; | 1087 SkScalar halfWidth = 0; |
1078 if (hasStroke) { | 1088 if (hasStroke) { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1139 verts->fOffset = SkPoint::Make(outerRadius, yOuterRadii[i]); | 1149 verts->fOffset = SkPoint::Make(outerRadius, yOuterRadii[i]); |
1140 verts->fOuterRadius = outerRadius; | 1150 verts->fOuterRadius = outerRadius; |
1141 verts->fInnerRadius = innerRadius; | 1151 verts->fInnerRadius = innerRadius; |
1142 verts++; | 1152 verts++; |
1143 } | 1153 } |
1144 | 1154 |
1145 // drop out the middle quad if we're stroked | 1155 // drop out the middle quad if we're stroked |
1146 int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 : | 1156 int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 : |
1147 SK_ARRAY_COUNT(gRRectIndices); | 1157 SK_ARRAY_COUNT(gRRectIndices); |
1148 target->setIndexSourceToBuffer(indexBuffer); | 1158 target->setIndexSourceToBuffer(indexBuffer); |
1149 target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 16, indexCnt
, &bounds); | 1159 target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 1
6, indexCnt, |
| 1160 &bounds); |
1150 | 1161 |
1151 // otherwise we use the ellipse renderer | 1162 // otherwise we use the ellipse renderer |
1152 } else { | 1163 } else { |
1153 drawState->setVertexAttribs<gEllipseVertexAttribs>(SK_ARRAY_COUNT(gEllip
seVertexAttribs), | 1164 drawState->setVertexAttribs<gEllipseVertexAttribs>(SK_ARRAY_COUNT(gEllip
seVertexAttribs), |
1154 sizeof(EllipseVertex)
); | 1165 sizeof(EllipseVertex)
); |
1155 | 1166 |
1156 SkScalar innerXRadius = 0.0f; | 1167 SkScalar innerXRadius = 0.0f; |
1157 SkScalar innerYRadius = 0.0f; | 1168 SkScalar innerYRadius = 0.0f; |
1158 if (hasStroke) { | 1169 if (hasStroke) { |
1159 if (SkScalarNearlyZero(scaledStroke.length())) { | 1170 if (SkScalarNearlyZero(scaledStroke.length())) { |
(...skipping 20 matching lines...) Expand all Loading... |
1180 innerYRadius = yRadius - scaledStroke.fY; | 1191 innerYRadius = yRadius - scaledStroke.fY; |
1181 } | 1192 } |
1182 | 1193 |
1183 xRadius += scaledStroke.fX; | 1194 xRadius += scaledStroke.fX; |
1184 yRadius += scaledStroke.fY; | 1195 yRadius += scaledStroke.fY; |
1185 bounds.outset(scaledStroke.fX, scaledStroke.fY); | 1196 bounds.outset(scaledStroke.fX, scaledStroke.fY); |
1186 } | 1197 } |
1187 | 1198 |
1188 isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0); | 1199 isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0); |
1189 | 1200 |
1190 GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0); | 1201 GrDrawTarget::AutoReleaseGeometry geo(target, 16, drawState->getVertexSt
ride(), 0); |
1191 if (!geo.succeeded()) { | 1202 if (!geo.succeeded()) { |
1192 SkDebugf("Failed to get space for vertices!\n"); | 1203 SkDebugf("Failed to get space for vertices!\n"); |
1193 return false; | 1204 return false; |
1194 } | 1205 } |
1195 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); | 1206 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); |
1196 | 1207 |
1197 GrGeometryProcessor* effect = EllipseEdgeEffect::Create(isStrokeOnly); | 1208 GrGeometryProcessor* effect = EllipseEdgeEffect::Create(isStrokeOnly); |
1198 drawState->setGeometryProcessor(effect)->unref(); | 1209 drawState->setGeometryProcessor(effect)->unref(); |
1199 | 1210 |
1200 // Compute the reciprocals of the radii here to save time in the shader | 1211 // Compute the reciprocals of the radii here to save time in the shader |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1246 verts->fOffset = SkPoint::Make(xOuterRadius, yOuterOffsets[i]); | 1257 verts->fOffset = SkPoint::Make(xOuterRadius, yOuterOffsets[i]); |
1247 verts->fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); | 1258 verts->fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); |
1248 verts->fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip); | 1259 verts->fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip); |
1249 verts++; | 1260 verts++; |
1250 } | 1261 } |
1251 | 1262 |
1252 // drop out the middle quad if we're stroked | 1263 // drop out the middle quad if we're stroked |
1253 int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 : | 1264 int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 : |
1254 SK_ARRAY_COUNT(gRRectIndices); | 1265 SK_ARRAY_COUNT(gRRectIndices); |
1255 target->setIndexSourceToBuffer(indexBuffer); | 1266 target->setIndexSourceToBuffer(indexBuffer); |
1256 target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 16, indexCnt
, &bounds); | 1267 target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 1
6, indexCnt, |
| 1268 &bounds); |
1257 } | 1269 } |
1258 | 1270 |
1259 target->resetIndexSource(); | 1271 target->resetIndexSource(); |
1260 return true; | 1272 return true; |
1261 } | 1273 } |
OLD | NEW |