| 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 "GrEffect.h" | 10 #include "GrEffect.h" |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); | 342 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); |
| 343 if (!geo.succeeded()) { | 343 if (!geo.succeeded()) { |
| 344 GrPrintf("Failed to get space for vertices!\n"); | 344 GrPrintf("Failed to get space for vertices!\n"); |
| 345 return; | 345 return; |
| 346 } | 346 } |
| 347 | 347 |
| 348 CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices()); | 348 CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices()); |
| 349 | 349 |
| 350 SkStrokeRec::Style style = stroke.getStyle(); | 350 SkStrokeRec::Style style = stroke.getStyle(); |
| 351 bool isStroked = (SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairl
ine_Style == style); | 351 bool isStroked = (SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairl
ine_Style == style); |
| 352 enum { | |
| 353 // the edge effects share this stage with glyph rendering | |
| 354 // (kGlyphMaskStage in GrTextContext) && SW path rendering | |
| 355 // (kPathMaskStage in GrSWMaskHelper) | |
| 356 kEdgeEffectStage = GrPaint::kTotalStages, | |
| 357 }; | |
| 358 | 352 |
| 359 GrEffectRef* effect = CircleEdgeEffect::Create(isStroked); | 353 GrEffectRef* effect = CircleEdgeEffect::Create(isStroked); |
| 360 static const int kCircleEdgeAttrIndex = 1; | 354 static const int kCircleEdgeAttrIndex = 1; |
| 361 drawState->setEffect(kEdgeEffectStage, effect, kCircleEdgeAttrIndex)->unref(
); | 355 drawState->addCoverageEffect(effect, kCircleEdgeAttrIndex)->unref(); |
| 362 | 356 |
| 363 SkScalar innerRadius = 0.0f; | 357 SkScalar innerRadius = 0.0f; |
| 364 SkScalar outerRadius = radius; | 358 SkScalar outerRadius = radius; |
| 365 SkScalar halfWidth = 0; | 359 SkScalar halfWidth = 0; |
| 366 if (style != SkStrokeRec::kFill_Style) { | 360 if (style != SkStrokeRec::kFill_Style) { |
| 367 if (SkScalarNearlyZero(strokeWidth)) { | 361 if (SkScalarNearlyZero(strokeWidth)) { |
| 368 halfWidth = SK_ScalarHalf; | 362 halfWidth = SK_ScalarHalf; |
| 369 } else { | 363 } else { |
| 370 halfWidth = SkScalarHalf(strokeWidth); | 364 halfWidth = SkScalarHalf(strokeWidth); |
| 371 } | 365 } |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 GrAssert(sizeof(EllipseVertex) == drawState->getVertexSize()); | 496 GrAssert(sizeof(EllipseVertex) == drawState->getVertexSize()); |
| 503 | 497 |
| 504 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); | 498 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); |
| 505 if (!geo.succeeded()) { | 499 if (!geo.succeeded()) { |
| 506 GrPrintf("Failed to get space for vertices!\n"); | 500 GrPrintf("Failed to get space for vertices!\n"); |
| 507 return false; | 501 return false; |
| 508 } | 502 } |
| 509 | 503 |
| 510 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); | 504 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); |
| 511 | 505 |
| 512 enum { | |
| 513 // the edge effects share this stage with glyph rendering | |
| 514 // (kGlyphMaskStage in GrTextContext) && SW path rendering | |
| 515 // (kPathMaskStage in GrSWMaskHelper) | |
| 516 kEdgeEffectStage = GrPaint::kTotalStages, | |
| 517 }; | |
| 518 GrEffectRef* effect = EllipseEdgeEffect::Create(isStroked); | 506 GrEffectRef* effect = EllipseEdgeEffect::Create(isStroked); |
| 519 | 507 |
| 520 static const int kEllipseCenterAttrIndex = 1; | 508 static const int kEllipseCenterAttrIndex = 1; |
| 521 static const int kEllipseEdgeAttrIndex = 2; | 509 static const int kEllipseEdgeAttrIndex = 2; |
| 522 drawState->setEffect(kEdgeEffectStage, effect, | 510 drawState->addCoverageEffect(effect, kEllipseCenterAttrIndex, kEllipseEdgeAt
trIndex)->unref(); |
| 523 kEllipseCenterAttrIndex, kEllipseEdgeAttrIndex)->unref(
); | |
| 524 | 511 |
| 525 // Compute the reciprocals of the radii here to save time in the shader | 512 // Compute the reciprocals of the radii here to save time in the shader |
| 526 SkScalar xRadRecip = SkScalarInvert(xRadius); | 513 SkScalar xRadRecip = SkScalarInvert(xRadius); |
| 527 SkScalar yRadRecip = SkScalarInvert(yRadius); | 514 SkScalar yRadRecip = SkScalarInvert(yRadius); |
| 528 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius); | 515 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius); |
| 529 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius); | 516 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius); |
| 530 | 517 |
| 531 // We've extended the outer x radius out half a pixel to antialias. | 518 // We've extended the outer x radius out half a pixel to antialias. |
| 532 // This will also expand the rect so all the pixels will be captured. | 519 // This will also expand the rect so all the pixels will be captured. |
| 533 // TODO: Consider if we should use sqrt(2)/2 instead | 520 // TODO: Consider if we should use sqrt(2)/2 instead |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 650 | 637 |
| 651 // reset to device coordinates | 638 // reset to device coordinates |
| 652 GrDrawState* drawState = target->drawState(); | 639 GrDrawState* drawState = target->drawState(); |
| 653 GrDrawState::AutoViewMatrixRestore avmr; | 640 GrDrawState::AutoViewMatrixRestore avmr; |
| 654 if (!avmr.setIdentity(drawState)) { | 641 if (!avmr.setIdentity(drawState)) { |
| 655 return false; | 642 return false; |
| 656 } | 643 } |
| 657 | 644 |
| 658 bool isStroked = (SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairl
ine_Style == style); | 645 bool isStroked = (SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairl
ine_Style == style); |
| 659 | 646 |
| 660 enum { | |
| 661 // the edge effects share this stage with glyph rendering | |
| 662 // (kGlyphMaskStage in GrTextContext) && SW path rendering | |
| 663 // (kPathMaskStage in GrSWMaskHelper) | |
| 664 kEdgeEffectStage = GrPaint::kTotalStages, | |
| 665 }; | |
| 666 | |
| 667 GrIndexBuffer* indexBuffer = this->rRectIndexBuffer(context->getGpu()); | 647 GrIndexBuffer* indexBuffer = this->rRectIndexBuffer(context->getGpu()); |
| 668 if (NULL == indexBuffer) { | 648 if (NULL == indexBuffer) { |
| 669 GrPrintf("Failed to create index buffer!\n"); | 649 GrPrintf("Failed to create index buffer!\n"); |
| 670 return false; | 650 return false; |
| 671 } | 651 } |
| 672 | 652 |
| 673 // if the corners are circles, use the circle renderer | 653 // if the corners are circles, use the circle renderer |
| 674 if ((!isStroked || scaledStroke.fX == scaledStroke.fY) && xRadius == yRadius
) { | 654 if ((!isStroked || scaledStroke.fX == scaledStroke.fY) && xRadius == yRadius
) { |
| 675 drawState->setVertexAttribs<gCircleVertexAttribs>(SK_ARRAY_COUNT(gCircle
VertexAttribs)); | 655 drawState->setVertexAttribs<gCircleVertexAttribs>(SK_ARRAY_COUNT(gCircle
VertexAttribs)); |
| 676 GrAssert(sizeof(CircleVertex) == drawState->getVertexSize()); | 656 GrAssert(sizeof(CircleVertex) == drawState->getVertexSize()); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 695 if (isStroked) { | 675 if (isStroked) { |
| 696 innerRadius = xRadius - halfWidth; | 676 innerRadius = xRadius - halfWidth; |
| 697 isStroked = (innerRadius > 0); | 677 isStroked = (innerRadius > 0); |
| 698 } | 678 } |
| 699 outerRadius += halfWidth; | 679 outerRadius += halfWidth; |
| 700 bounds.outset(halfWidth, halfWidth); | 680 bounds.outset(halfWidth, halfWidth); |
| 701 } | 681 } |
| 702 | 682 |
| 703 GrEffectRef* effect = CircleEdgeEffect::Create(isStroked); | 683 GrEffectRef* effect = CircleEdgeEffect::Create(isStroked); |
| 704 static const int kCircleEdgeAttrIndex = 1; | 684 static const int kCircleEdgeAttrIndex = 1; |
| 705 drawState->setEffect(kEdgeEffectStage, effect, kCircleEdgeAttrIndex)->un
ref(); | 685 drawState->addCoverageEffect(effect, kCircleEdgeAttrIndex)->unref(); |
| 706 | 686 |
| 707 // The radii are outset for two reasons. First, it allows the shader to
simply perform | 687 // The radii are outset for two reasons. First, it allows the shader to
simply perform |
| 708 // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is
used to compute the | 688 // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is
used to compute the |
| 709 // verts of the bounding box that is rendered and the outset ensures the
box will cover all | 689 // verts of the bounding box that is rendered and the outset ensures the
box will cover all |
| 710 // pixels partially covered by the circle. | 690 // pixels partially covered by the circle. |
| 711 outerRadius += SK_ScalarHalf; | 691 outerRadius += SK_ScalarHalf; |
| 712 innerRadius -= SK_ScalarHalf; | 692 innerRadius -= SK_ScalarHalf; |
| 713 | 693 |
| 714 // Expand the rect so all the pixels will be captured. | 694 // Expand the rect so all the pixels will be captured. |
| 715 bounds.outset(SK_ScalarHalf, SK_ScalarHalf); | 695 bounds.outset(SK_ScalarHalf, SK_ScalarHalf); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 798 GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0); | 778 GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0); |
| 799 if (!geo.succeeded()) { | 779 if (!geo.succeeded()) { |
| 800 GrPrintf("Failed to get space for vertices!\n"); | 780 GrPrintf("Failed to get space for vertices!\n"); |
| 801 return false; | 781 return false; |
| 802 } | 782 } |
| 803 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); | 783 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); |
| 804 | 784 |
| 805 GrEffectRef* effect = EllipseEdgeEffect::Create(isStroked); | 785 GrEffectRef* effect = EllipseEdgeEffect::Create(isStroked); |
| 806 static const int kEllipseOffsetAttrIndex = 1; | 786 static const int kEllipseOffsetAttrIndex = 1; |
| 807 static const int kEllipseRadiiAttrIndex = 2; | 787 static const int kEllipseRadiiAttrIndex = 2; |
| 808 drawState->setEffect(kEdgeEffectStage, effect, | 788 drawState->addCoverageEffect(effect, |
| 809 kEllipseOffsetAttrIndex, kEllipseRadiiAttrIndex)->u
nref(); | 789 kEllipseOffsetAttrIndex, kEllipseRadiiAttrI
ndex)->unref(); |
| 810 | 790 |
| 811 // Compute the reciprocals of the radii here to save time in the shader | 791 // Compute the reciprocals of the radii here to save time in the shader |
| 812 SkScalar xRadRecip = SkScalarInvert(xRadius); | 792 SkScalar xRadRecip = SkScalarInvert(xRadius); |
| 813 SkScalar yRadRecip = SkScalarInvert(yRadius); | 793 SkScalar yRadRecip = SkScalarInvert(yRadius); |
| 814 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius); | 794 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius); |
| 815 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius); | 795 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius); |
| 816 | 796 |
| 817 // Extend the radii out half a pixel to antialias. | 797 // Extend the radii out half a pixel to antialias. |
| 818 SkScalar xOuterRadius = xRadius + SK_ScalarHalf; | 798 SkScalar xOuterRadius = xRadius + SK_ScalarHalf; |
| 819 SkScalar yOuterRadius = yRadius + SK_ScalarHalf; | 799 SkScalar yOuterRadius = yRadius + SK_ScalarHalf; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 861 } | 841 } |
| 862 | 842 |
| 863 // drop out the middle quad if we're stroked | 843 // drop out the middle quad if we're stroked |
| 864 int indexCnt = isStroked ? GR_ARRAY_COUNT(gRRectIndices)-6 : GR_ARRAY_CO
UNT(gRRectIndices); | 844 int indexCnt = isStroked ? GR_ARRAY_COUNT(gRRectIndices)-6 : GR_ARRAY_CO
UNT(gRRectIndices); |
| 865 target->setIndexSourceToBuffer(indexBuffer); | 845 target->setIndexSourceToBuffer(indexBuffer); |
| 866 target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 16, indexCnt, &bou
nds); | 846 target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 16, indexCnt, &bou
nds); |
| 867 } | 847 } |
| 868 | 848 |
| 869 return true; | 849 return true; |
| 870 } | 850 } |
| OLD | NEW |