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 |