Chromium Code Reviews| 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 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 352 if (!geo.succeeded()) { | 352 if (!geo.succeeded()) { |
| 353 GrPrintf("Failed to get space for vertices!\n"); | 353 GrPrintf("Failed to get space for vertices!\n"); |
| 354 return; | 354 return; |
| 355 } | 355 } |
| 356 | 356 |
| 357 CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices()); | 357 CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices()); |
| 358 | 358 |
| 359 SkStrokeRec::Style style = stroke.getStyle(); | 359 SkStrokeRec::Style style = stroke.getStyle(); |
| 360 bool isStroked = (SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairl ine_Style == style); | 360 bool isStroked = (SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairl ine_Style == style); |
| 361 | 361 |
| 362 GrEffectRef* effect = CircleEdgeEffect::Create(isStroked); | |
| 363 static const int kCircleEdgeAttrIndex = 1; | |
| 364 drawState->addCoverageEffect(effect, kCircleEdgeAttrIndex)->unref(); | |
| 365 | |
| 366 SkScalar innerRadius = 0.0f; | 362 SkScalar innerRadius = 0.0f; |
| 367 SkScalar outerRadius = radius; | 363 SkScalar outerRadius = radius; |
| 368 SkScalar halfWidth = 0; | 364 SkScalar halfWidth = 0; |
| 369 if (style != SkStrokeRec::kFill_Style) { | 365 if (style != SkStrokeRec::kFill_Style) { |
| 370 if (SkScalarNearlyZero(strokeWidth)) { | 366 if (SkScalarNearlyZero(strokeWidth)) { |
| 371 halfWidth = SK_ScalarHalf; | 367 halfWidth = SK_ScalarHalf; |
| 372 } else { | 368 } else { |
| 373 halfWidth = SkScalarHalf(strokeWidth); | 369 halfWidth = SkScalarHalf(strokeWidth); |
| 374 } | 370 } |
| 375 | 371 |
| 376 outerRadius += halfWidth; | 372 outerRadius += halfWidth; |
| 377 if (isStroked) { | 373 if (isStroked) { |
| 378 innerRadius = radius - halfWidth; | 374 innerRadius = radius - halfWidth; |
|
robertphillips
2013/08/29 17:01:14
Did you try leaving the "innerRadius = radius - ha
jvanverth1
2013/08/29 18:16:53
Yes, that's why I moved it down.
| |
| 379 isStroked = (innerRadius > 0); | |
| 380 } | 375 } |
| 381 } | 376 } |
| 382 | 377 |
| 378 GrEffectRef* effect = CircleEdgeEffect::Create(isStroked && innerRadius > 0) ; | |
| 379 static const int kCircleEdgeAttrIndex = 1; | |
| 380 drawState->addCoverageEffect(effect, kCircleEdgeAttrIndex)->unref(); | |
| 381 | |
| 383 // The radii are outset for two reasons. First, it allows the shader to simp ly perform | 382 // The radii are outset for two reasons. First, it allows the shader to simp ly perform |
| 384 // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is use d to compute the | 383 // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is use d to compute the |
| 385 // verts of the bounding box that is rendered and the outset ensures the box will cover all | 384 // verts of the bounding box that is rendered and the outset ensures the box will cover all |
| 386 // pixels partially covered by the circle. | 385 // pixels partially covered by the circle. |
| 387 outerRadius += SK_ScalarHalf; | 386 outerRadius += SK_ScalarHalf; |
| 388 innerRadius -= SK_ScalarHalf; | 387 innerRadius -= SK_ScalarHalf; |
| 389 | 388 |
| 390 SkRect bounds = SkRect::MakeLTRB( | 389 SkRect bounds = SkRect::MakeLTRB( |
| 391 center.fX - outerRadius, | 390 center.fX - outerRadius, |
| 392 center.fY - outerRadius, | 391 center.fY - outerRadius, |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 482 // we don't handle it if curvature of the stroke is less than curvature of the ellipse | 481 // we don't handle it if curvature of the stroke is less than curvature of the ellipse |
| 483 if (scaledStroke.fX*(yRadius*yRadius) < (scaledStroke.fY*scaledStroke.fY )*xRadius || | 482 if (scaledStroke.fX*(yRadius*yRadius) < (scaledStroke.fY*scaledStroke.fY )*xRadius || |
| 484 scaledStroke.fY*(xRadius*xRadius) < (scaledStroke.fX*scaledStroke.fX )*yRadius) { | 483 scaledStroke.fY*(xRadius*xRadius) < (scaledStroke.fX*scaledStroke.fX )*yRadius) { |
| 485 return false; | 484 return false; |
| 486 } | 485 } |
| 487 | 486 |
| 488 // this is legit only if scale & translation (which should be the case a t the moment) | 487 // this is legit only if scale & translation (which should be the case a t the moment) |
| 489 if (isStroked) { | 488 if (isStroked) { |
| 490 innerXRadius = xRadius - scaledStroke.fX; | 489 innerXRadius = xRadius - scaledStroke.fX; |
| 491 innerYRadius = yRadius - scaledStroke.fY; | 490 innerYRadius = yRadius - scaledStroke.fY; |
| 492 isStroked = (innerXRadius > 0 && innerYRadius > 0); | |
| 493 } | 491 } |
| 494 | 492 |
| 495 xRadius += scaledStroke.fX; | 493 xRadius += scaledStroke.fX; |
| 496 yRadius += scaledStroke.fY; | 494 yRadius += scaledStroke.fY; |
| 497 } | 495 } |
| 498 | 496 |
| 499 GrDrawState::AutoViewMatrixRestore avmr; | 497 GrDrawState::AutoViewMatrixRestore avmr; |
| 500 if (!avmr.setIdentity(drawState)) { | 498 if (!avmr.setIdentity(drawState)) { |
| 501 return false; | 499 return false; |
| 502 } | 500 } |
| 503 | 501 |
| 504 drawState->setVertexAttribs<gEllipseVertexAttribs>(SK_ARRAY_COUNT(gEllipseVe rtexAttribs)); | 502 drawState->setVertexAttribs<gEllipseVertexAttribs>(SK_ARRAY_COUNT(gEllipseVe rtexAttribs)); |
| 505 SkASSERT(sizeof(EllipseVertex) == drawState->getVertexSize()); | 503 SkASSERT(sizeof(EllipseVertex) == drawState->getVertexSize()); |
| 506 | 504 |
| 507 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); | 505 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); |
| 508 if (!geo.succeeded()) { | 506 if (!geo.succeeded()) { |
| 509 GrPrintf("Failed to get space for vertices!\n"); | 507 GrPrintf("Failed to get space for vertices!\n"); |
| 510 return false; | 508 return false; |
| 511 } | 509 } |
| 512 | 510 |
| 513 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); | 511 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); |
| 514 | 512 |
| 515 GrEffectRef* effect = EllipseEdgeEffect::Create(isStroked); | 513 GrEffectRef* effect = EllipseEdgeEffect::Create(isStroked && |
| 514 innerXRadius > 0 && innerYRa dius > 0); | |
| 516 | 515 |
| 517 static const int kEllipseCenterAttrIndex = 1; | 516 static const int kEllipseCenterAttrIndex = 1; |
| 518 static const int kEllipseEdgeAttrIndex = 2; | 517 static const int kEllipseEdgeAttrIndex = 2; |
| 519 drawState->addCoverageEffect(effect, kEllipseCenterAttrIndex, kEllipseEdgeAt trIndex)->unref(); | 518 drawState->addCoverageEffect(effect, kEllipseCenterAttrIndex, kEllipseEdgeAt trIndex)->unref(); |
| 520 | 519 |
| 521 // Compute the reciprocals of the radii here to save time in the shader | 520 // Compute the reciprocals of the radii here to save time in the shader |
| 522 SkScalar xRadRecip = SkScalarInvert(xRadius); | 521 SkScalar xRadRecip = SkScalarInvert(xRadius); |
| 523 SkScalar yRadRecip = SkScalarInvert(yRadius); | 522 SkScalar yRadRecip = SkScalarInvert(yRadius); |
| 524 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius); | 523 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius); |
| 525 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius); | 524 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius); |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 676 SkScalar halfWidth = 0; | 675 SkScalar halfWidth = 0; |
| 677 if (style != SkStrokeRec::kFill_Style) { | 676 if (style != SkStrokeRec::kFill_Style) { |
| 678 if (SkScalarNearlyZero(scaledStroke.fX)) { | 677 if (SkScalarNearlyZero(scaledStroke.fX)) { |
| 679 halfWidth = SK_ScalarHalf; | 678 halfWidth = SK_ScalarHalf; |
| 680 } else { | 679 } else { |
| 681 halfWidth = SkScalarHalf(scaledStroke.fX); | 680 halfWidth = SkScalarHalf(scaledStroke.fX); |
| 682 } | 681 } |
| 683 | 682 |
| 684 if (isStroked) { | 683 if (isStroked) { |
| 685 innerRadius = xRadius - halfWidth; | 684 innerRadius = xRadius - halfWidth; |
| 686 isStroked = (innerRadius > 0); | |
| 687 } | 685 } |
| 688 outerRadius += halfWidth; | 686 outerRadius += halfWidth; |
| 689 bounds.outset(halfWidth, halfWidth); | 687 bounds.outset(halfWidth, halfWidth); |
| 690 } | 688 } |
| 691 | 689 |
| 692 GrEffectRef* effect = CircleEdgeEffect::Create(isStroked); | 690 GrEffectRef* effect = CircleEdgeEffect::Create(isStroked && innerRadius > 0); |
| 693 static const int kCircleEdgeAttrIndex = 1; | 691 static const int kCircleEdgeAttrIndex = 1; |
| 694 drawState->addCoverageEffect(effect, kCircleEdgeAttrIndex)->unref(); | 692 drawState->addCoverageEffect(effect, kCircleEdgeAttrIndex)->unref(); |
| 695 | 693 |
| 696 // The radii are outset for two reasons. First, it allows the shader to simply perform | 694 // The radii are outset for two reasons. First, it allows the shader to simply perform |
| 697 // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is used to compute the | 695 // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is used to compute the |
| 698 // verts of the bounding box that is rendered and the outset ensures the box will cover all | 696 // verts of the bounding box that is rendered and the outset ensures the box will cover all |
| 699 // pixels partially covered by the circle. | 697 // pixels partially covered by the circle. |
| 700 outerRadius += SK_ScalarHalf; | 698 outerRadius += SK_ScalarHalf; |
| 701 innerRadius -= SK_ScalarHalf; | 699 innerRadius -= SK_ScalarHalf; |
| 702 | 700 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 769 // we don't handle it if curvature of the stroke is less than curvat ure of the ellipse | 767 // we don't handle it if curvature of the stroke is less than curvat ure of the ellipse |
| 770 if (scaledStroke.fX*(yRadius*yRadius) < (scaledStroke.fY*scaledStrok e.fY)*xRadius || | 768 if (scaledStroke.fX*(yRadius*yRadius) < (scaledStroke.fY*scaledStrok e.fY)*xRadius || |
| 771 scaledStroke.fY*(xRadius*xRadius) < (scaledStroke.fX*scaledStrok e.fX)*yRadius) { | 769 scaledStroke.fY*(xRadius*xRadius) < (scaledStroke.fX*scaledStrok e.fX)*yRadius) { |
| 772 return false; | 770 return false; |
| 773 } | 771 } |
| 774 | 772 |
| 775 // this is legit only if scale & translation (which should be the ca se at the moment) | 773 // this is legit only if scale & translation (which should be the ca se at the moment) |
| 776 if (isStroked) { | 774 if (isStroked) { |
| 777 innerXRadius = xRadius - scaledStroke.fX; | 775 innerXRadius = xRadius - scaledStroke.fX; |
| 778 innerYRadius = yRadius - scaledStroke.fY; | 776 innerYRadius = yRadius - scaledStroke.fY; |
| 779 isStroked = (innerXRadius > 0 && innerYRadius > 0); | |
| 780 } | 777 } |
| 781 | 778 |
| 782 xRadius += scaledStroke.fX; | 779 xRadius += scaledStroke.fX; |
| 783 yRadius += scaledStroke.fY; | 780 yRadius += scaledStroke.fY; |
| 784 bounds.outset(scaledStroke.fX, scaledStroke.fY); | 781 bounds.outset(scaledStroke.fX, scaledStroke.fY); |
| 785 } | 782 } |
| 786 | 783 |
| 787 GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0); | 784 GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0); |
| 788 if (!geo.succeeded()) { | 785 if (!geo.succeeded()) { |
| 789 GrPrintf("Failed to get space for vertices!\n"); | 786 GrPrintf("Failed to get space for vertices!\n"); |
| 790 return false; | 787 return false; |
| 791 } | 788 } |
| 792 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); | 789 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); |
| 793 | 790 |
| 794 GrEffectRef* effect = EllipseEdgeEffect::Create(isStroked); | 791 GrEffectRef* effect = EllipseEdgeEffect::Create(isStroked && |
| 792 innerXRadius > 0 && inne rYRadius > 0); | |
| 795 static const int kEllipseOffsetAttrIndex = 1; | 793 static const int kEllipseOffsetAttrIndex = 1; |
| 796 static const int kEllipseRadiiAttrIndex = 2; | 794 static const int kEllipseRadiiAttrIndex = 2; |
| 797 drawState->addCoverageEffect(effect, | 795 drawState->addCoverageEffect(effect, |
| 798 kEllipseOffsetAttrIndex, kEllipseRadiiAttrI ndex)->unref(); | 796 kEllipseOffsetAttrIndex, kEllipseRadiiAttrI ndex)->unref(); |
| 799 | 797 |
| 800 // Compute the reciprocals of the radii here to save time in the shader | 798 // Compute the reciprocals of the radii here to save time in the shader |
| 801 SkScalar xRadRecip = SkScalarInvert(xRadius); | 799 SkScalar xRadRecip = SkScalarInvert(xRadius); |
| 802 SkScalar yRadRecip = SkScalarInvert(yRadius); | 800 SkScalar yRadRecip = SkScalarInvert(yRadius); |
| 803 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius); | 801 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius); |
| 804 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius); | 802 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 842 verts->fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip); | 840 verts->fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip); |
| 843 verts++; | 841 verts++; |
| 844 | 842 |
| 845 verts->fPos = SkPoint::Make(bounds.fRight, yCoords[i]); | 843 verts->fPos = SkPoint::Make(bounds.fRight, yCoords[i]); |
| 846 verts->fOffset = SkPoint::Make(xOuterRadius, yOuterOffsets[i]); | 844 verts->fOffset = SkPoint::Make(xOuterRadius, yOuterOffsets[i]); |
| 847 verts->fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); | 845 verts->fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); |
| 848 verts->fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip); | 846 verts->fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip); |
| 849 verts++; | 847 verts++; |
| 850 } | 848 } |
| 851 | 849 |
| 852 // drop out the middle quad if we're stroked | 850 // drop out the middle quad if we're stroked |
|
robertphillips
2013/08/29 17:01:14
It seems like this won't behave exactly the same?
jvanverth1
2013/08/29 18:16:53
Nope, not okay. Good catch.
| |
| 853 int indexCnt = isStroked ? GR_ARRAY_COUNT(gRRectIndices)-6 : GR_ARRAY_CO UNT(gRRectIndices); | 851 int indexCnt = isStroked ? GR_ARRAY_COUNT(gRRectIndices)-6 : GR_ARRAY_CO UNT(gRRectIndices); |
| 854 target->setIndexSourceToBuffer(indexBuffer); | 852 target->setIndexSourceToBuffer(indexBuffer); |
| 855 target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 16, indexCnt, &bou nds); | 853 target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 16, indexCnt, &bou nds); |
| 856 } | 854 } |
| 857 | 855 |
| 858 return true; | 856 return true; |
| 859 } | 857 } |
| OLD | NEW |