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