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