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; |
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 |
690 isStroked = (isStroked && innerRadius > 0); | |
jvanverth1
2013/08/30 12:59:08
Revised to reset isStroked because it's used in tw
| |
691 | |
692 GrEffectRef* effect = CircleEdgeEffect::Create(isStroked); | 692 GrEffectRef* effect = CircleEdgeEffect::Create(isStroked); |
693 static const int kCircleEdgeAttrIndex = 1; | 693 static const int kCircleEdgeAttrIndex = 1; |
694 drawState->addCoverageEffect(effect, kCircleEdgeAttrIndex)->unref(); | 694 drawState->addCoverageEffect(effect, kCircleEdgeAttrIndex)->unref(); |
695 | 695 |
696 // The radii are outset for two reasons. First, it allows the shader to simply perform | 696 // 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 | 697 // 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 | 698 // verts of the bounding box that is rendered and the outset ensures the box will cover all |
699 // pixels partially covered by the circle. | 699 // pixels partially covered by the circle. |
700 outerRadius += SK_ScalarHalf; | 700 outerRadius += SK_ScalarHalf; |
701 innerRadius -= SK_ScalarHalf; | 701 innerRadius -= SK_ScalarHalf; |
(...skipping 67 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 | 769 // 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 || | 770 if (scaledStroke.fX*(yRadius*yRadius) < (scaledStroke.fY*scaledStrok e.fY)*xRadius || |
771 scaledStroke.fY*(xRadius*xRadius) < (scaledStroke.fX*scaledStrok e.fX)*yRadius) { | 771 scaledStroke.fY*(xRadius*xRadius) < (scaledStroke.fX*scaledStrok e.fX)*yRadius) { |
772 return false; | 772 return false; |
773 } | 773 } |
774 | 774 |
775 // this is legit only if scale & translation (which should be the ca se at the moment) | 775 // this is legit only if scale & translation (which should be the ca se at the moment) |
776 if (isStroked) { | 776 if (isStroked) { |
777 innerXRadius = xRadius - scaledStroke.fX; | 777 innerXRadius = xRadius - scaledStroke.fX; |
778 innerYRadius = yRadius - scaledStroke.fY; | 778 innerYRadius = yRadius - scaledStroke.fY; |
779 isStroked = (innerXRadius > 0 && innerYRadius > 0); | |
780 } | 779 } |
781 | 780 |
782 xRadius += scaledStroke.fX; | 781 xRadius += scaledStroke.fX; |
783 yRadius += scaledStroke.fY; | 782 yRadius += scaledStroke.fY; |
784 bounds.outset(scaledStroke.fX, scaledStroke.fY); | 783 bounds.outset(scaledStroke.fX, scaledStroke.fY); |
785 } | 784 } |
786 | 785 |
786 isStroked = (isStroked && innerXRadius > 0 && innerYRadius > 0); | |
jvanverth1
2013/08/30 12:59:08
Revised to reset isStroked because it's used in tw
| |
787 | |
787 GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0); | 788 GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0); |
788 if (!geo.succeeded()) { | 789 if (!geo.succeeded()) { |
789 GrPrintf("Failed to get space for vertices!\n"); | 790 GrPrintf("Failed to get space for vertices!\n"); |
790 return false; | 791 return false; |
791 } | 792 } |
792 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); | 793 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); |
793 | 794 |
794 GrEffectRef* effect = EllipseEdgeEffect::Create(isStroked); | 795 GrEffectRef* effect = EllipseEdgeEffect::Create(isStroked); |
795 static const int kEllipseOffsetAttrIndex = 1; | 796 static const int kEllipseOffsetAttrIndex = 1; |
796 static const int kEllipseRadiiAttrIndex = 2; | 797 static const int kEllipseRadiiAttrIndex = 2; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
850 } | 851 } |
851 | 852 |
852 // drop out the middle quad if we're stroked | 853 // drop out the middle quad if we're stroked |
853 int indexCnt = isStroked ? GR_ARRAY_COUNT(gRRectIndices)-6 : GR_ARRAY_CO UNT(gRRectIndices); | 854 int indexCnt = isStroked ? GR_ARRAY_COUNT(gRRectIndices)-6 : GR_ARRAY_CO UNT(gRRectIndices); |
854 target->setIndexSourceToBuffer(indexBuffer); | 855 target->setIndexSourceToBuffer(indexBuffer); |
855 target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 16, indexCnt, &bou nds); | 856 target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 16, indexCnt, &bou nds); |
856 } | 857 } |
857 | 858 |
858 return true; | 859 return true; |
859 } | 860 } |
OLD | NEW |