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