OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 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 "GrClipStackClip.h" | 8 #include "GrClipStackClip.h" |
9 | 9 |
10 #include "GrAppliedClip.h" | 10 #include "GrAppliedClip.h" |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
482 reducedClip.width(), | 482 reducedClip.width(), |
483 reducedClip.height(), | 483 reducedClip.height(), |
484 config, nullptr)); | 484 config, nullptr)); |
485 if (!dc) { | 485 if (!dc) { |
486 return nullptr; | 486 return nullptr; |
487 } | 487 } |
488 | 488 |
489 // The texture may be larger than necessary, this rect represents the part o
f the texture | 489 // The texture may be larger than necessary, this rect represents the part o
f the texture |
490 // we populate with a rasterization of the clip. | 490 // we populate with a rasterization of the clip. |
491 SkIRect maskSpaceIBounds = SkIRect::MakeWH(reducedClip.width(), reducedClip.
height()); | 491 SkIRect maskSpaceIBounds = SkIRect::MakeWH(reducedClip.width(), reducedClip.
height()); |
| 492 GrFixedClip clip(maskSpaceIBounds); |
492 | 493 |
493 // The scratch texture that we are drawing into can be substantially larger
than the mask. Only | 494 // The scratch texture that we are drawing into can be substantially larger
than the mask. Only |
494 // clear the part that we care about. | 495 // clear the part that we care about. |
495 dc->clear(&maskSpaceIBounds, InitialState::kAllIn == reducedClip.initialStat
e() ? -1 : 0, true); | 496 GrColor initialCoverage = InitialState::kAllIn == reducedClip.initialState()
? -1 : 0; |
| 497 dc->drawContextPriv().clear(clip, initialCoverage, true); |
496 | 498 |
497 // Set the matrix so that rendered clip elements are transformed to mask spa
ce from clip | 499 // Set the matrix so that rendered clip elements are transformed to mask spa
ce from clip |
498 // space. | 500 // space. |
499 const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMa
skOffset.fY); | 501 const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMa
skOffset.fY); |
500 | 502 |
501 // It is important that we use maskSpaceIBounds as the stencil rect in the b
elow loop. | 503 // It is important that we use maskSpaceIBounds as the stencil rect in the b
elow loop. |
502 // The second pass that zeros the stencil buffer renders the rect maskSpaceI
Bounds so the first | 504 // The second pass that zeros the stencil buffer renders the rect maskSpaceI
Bounds so the first |
503 // pass must not set values outside of this bounds or stencil values outside
the rect won't be | 505 // pass must not set values outside of this bounds or stencil values outside
the rect won't be |
504 // cleared. | 506 // cleared. |
505 | 507 |
506 // walk through each clip element and perform its set op | 508 // walk through each clip element and perform its set op |
507 for (ElementList::Iter iter(reducedClip.elements()); iter.get(); iter.next()
) { | 509 for (ElementList::Iter iter(reducedClip.elements()); iter.get(); iter.next()
) { |
508 const Element* element = iter.get(); | 510 const Element* element = iter.get(); |
509 SkRegion::Op op = element->getOp(); | 511 SkRegion::Op op = element->getOp(); |
510 bool invert = element->isInverseFilled(); | 512 bool invert = element->isInverseFilled(); |
511 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere
nce_Op == op) { | 513 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere
nce_Op == op) { |
512 GrFixedClip clip(maskSpaceIBounds); | |
513 | |
514 // draw directly into the result with the stencil set to make the pi
xels affected | 514 // draw directly into the result with the stencil set to make the pi
xels affected |
515 // by the clip shape be non-zero. | 515 // by the clip shape be non-zero. |
516 static constexpr GrUserStencilSettings kStencilInElement( | 516 static constexpr GrUserStencilSettings kStencilInElement( |
517 GrUserStencilSettings::StaticInit< | 517 GrUserStencilSettings::StaticInit< |
518 0xffff, | 518 0xffff, |
519 GrUserStencilTest::kAlways, | 519 GrUserStencilTest::kAlways, |
520 0xffff, | 520 0xffff, |
521 GrUserStencilOp::kReplace, | 521 GrUserStencilOp::kReplace, |
522 GrUserStencilOp::kReplace, | 522 GrUserStencilOp::kReplace, |
523 0xffff>() | 523 0xffff>() |
(...skipping 18 matching lines...) Expand all Loading... |
542 translate, | 542 translate, |
543 SkRect::Make(reducedCl
ip.ibounds()))) { | 543 SkRect::Make(reducedCl
ip.ibounds()))) { |
544 return nullptr; | 544 return nullptr; |
545 } | 545 } |
546 } else { | 546 } else { |
547 // all the remaining ops can just be directly draw into the accumula
tion buffer | 547 // all the remaining ops can just be directly draw into the accumula
tion buffer |
548 GrPaint paint; | 548 GrPaint paint; |
549 paint.setAntiAlias(element->isAA()); | 549 paint.setAntiAlias(element->isAA()); |
550 paint.setCoverageSetOpXPFactory(op, false); | 550 paint.setCoverageSetOpXPFactory(op, false); |
551 | 551 |
552 draw_element(dc.get(), GrNoClip(), paint, translate, element); | 552 draw_element(dc.get(), clip, paint, translate, element); |
553 } | 553 } |
554 } | 554 } |
555 | 555 |
556 sk_sp<GrTexture> texture(dc->asTexture()); | 556 sk_sp<GrTexture> texture(dc->asTexture()); |
557 SkASSERT(texture); | 557 SkASSERT(texture); |
558 texture->resourcePriv().setUniqueKey(key); | 558 texture->resourcePriv().setUniqueKey(key); |
559 return texture; | 559 return texture; |
560 } | 560 } |
561 | 561 |
562 //////////////////////////////////////////////////////////////////////////////// | 562 //////////////////////////////////////////////////////////////////////////////// |
563 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device | 563 // Create a 1-bit clip mask in the stencil buffer. |
564 // (as opposed to canvas) coordinates | 564 |
| 565 class StencilClip final : public GrClip { |
| 566 public: |
| 567 StencilClip(const SkIRect& scissorRect) : fFixedClip(scissorRect) {} |
| 568 const GrFixedClip& fixedClip() const { return fFixedClip; } |
| 569 |
| 570 private: |
| 571 bool quickContains(const SkRect&) const final { |
| 572 return false; |
| 573 } |
| 574 void getConservativeBounds(int width, int height, SkIRect* devResult, bool*
iior) const final { |
| 575 fFixedClip.getConservativeBounds(width, height, devResult, iior); |
| 576 } |
| 577 bool isRRect(const SkRect& rtBounds, SkRRect* rr, bool* aa) const final { |
| 578 return false; |
| 579 } |
| 580 bool apply(GrContext* context, GrDrawContext* drawContext, bool useHWAA, |
| 581 bool hasUserStencilSettings, GrAppliedClip* out) const final { |
| 582 if (!fFixedClip.apply(context, drawContext, useHWAA, hasUserStencilSetti
ngs, out)) { |
| 583 return false; |
| 584 } |
| 585 out->addStencilClip(); |
| 586 return true; |
| 587 } |
| 588 |
| 589 GrFixedClip fFixedClip; |
| 590 |
| 591 typedef GrClip INHERITED; |
| 592 }; |
| 593 |
565 bool GrClipStackClip::CreateStencilClipMask(GrContext* context, | 594 bool GrClipStackClip::CreateStencilClipMask(GrContext* context, |
566 GrDrawContext* drawContext, | 595 GrDrawContext* drawContext, |
567 const GrReducedClip& reducedClip, | 596 const GrReducedClip& reducedClip, |
568 const SkIPoint& clipSpaceToStencilOf
fset) { | 597 const SkIPoint& clipSpaceToStencilOf
fset) { |
569 SkASSERT(drawContext); | 598 SkASSERT(drawContext); |
570 | 599 |
571 GrStencilAttachment* stencilAttachment = context->resourceProvider()->attach
StencilAttachment( | 600 GrStencilAttachment* stencilAttachment = context->resourceProvider()->attach
StencilAttachment( |
572 drawContext->accessRenderTar
get()); | 601 drawContext->accessRenderTar
get()); |
573 if (nullptr == stencilAttachment) { | 602 if (nullptr == stencilAttachment) { |
574 return false; | 603 return false; |
575 } | 604 } |
576 | 605 |
577 // TODO: these need to be swapped over to using a StencilAttachmentProxy | 606 // TODO: these need to be swapped over to using a StencilAttachmentProxy |
578 if (stencilAttachment->mustRenderClip(reducedClip.elementsGenID(), reducedCl
ip.ibounds(), | 607 if (stencilAttachment->mustRenderClip(reducedClip.elementsGenID(), reducedCl
ip.ibounds(), |
579 clipSpaceToStencilOffset)) { | 608 clipSpaceToStencilOffset)) { |
580 stencilAttachment->setLastClip(reducedClip.elementsGenID(), reducedClip.
ibounds(), | 609 stencilAttachment->setLastClip(reducedClip.elementsGenID(), reducedClip.
ibounds(), |
581 clipSpaceToStencilOffset); | 610 clipSpaceToStencilOffset); |
582 // Set the matrix so that rendered clip elements are transformed from cl
ip to stencil space. | 611 // Set the matrix so that rendered clip elements are transformed from cl
ip to stencil space. |
583 SkVector translate = { | 612 SkVector translate = { |
584 SkIntToScalar(clipSpaceToStencilOffset.fX), | 613 SkIntToScalar(clipSpaceToStencilOffset.fX), |
585 SkIntToScalar(clipSpaceToStencilOffset.fY) | 614 SkIntToScalar(clipSpaceToStencilOffset.fY) |
586 }; | 615 }; |
587 SkMatrix viewMatrix; | 616 SkMatrix viewMatrix; |
588 viewMatrix.setTranslate(translate); | 617 viewMatrix.setTranslate(translate); |
589 | 618 |
590 // We set the current clip to the bounds so that our recursive draws are
scissored to them. | 619 // We set the current clip to the bounds so that our recursive draws are
scissored to them. |
591 SkIRect stencilSpaceIBounds(reducedClip.ibounds()); | 620 SkIRect stencilSpaceIBounds(reducedClip.ibounds()); |
592 stencilSpaceIBounds.offset(clipSpaceToStencilOffset); | 621 stencilSpaceIBounds.offset(clipSpaceToStencilOffset); |
593 GrFixedClip clip(stencilSpaceIBounds); | 622 StencilClip stencilClip(stencilSpaceIBounds); |
594 | 623 |
595 bool insideClip = InitialState::kAllIn == reducedClip.initialState(); | 624 bool initialState = InitialState::kAllIn == reducedClip.initialState(); |
596 drawContext->drawContextPriv().clearStencilClip(stencilSpaceIBounds, ins
ideClip); | 625 drawContext->drawContextPriv().clearStencilClip(stencilClip.fixedClip(),
initialState); |
597 | 626 |
598 // walk through each clip element and perform its set op | 627 // walk through each clip element and perform its set op |
599 // with the existing clip. | 628 // with the existing clip. |
600 for (ElementList::Iter iter(reducedClip.elements()); iter.get(); iter.ne
xt()) { | 629 for (ElementList::Iter iter(reducedClip.elements()); iter.get(); iter.ne
xt()) { |
601 const Element* element = iter.get(); | 630 const Element* element = iter.get(); |
602 bool useHWAA = element->isAA() && drawContext->isStencilBufferMultis
ampled(); | 631 bool useHWAA = element->isAA() && drawContext->isStencilBufferMultis
ampled(); |
603 | 632 |
604 bool fillInverted = false; | 633 bool fillInverted = false; |
605 // enabled at bottom of loop | |
606 clip.disableStencilClip(); | |
607 | 634 |
608 // This will be used to determine whether the clip shape can be rend
ered into the | 635 // This will be used to determine whether the clip shape can be rend
ered into the |
609 // stencil with arbitrary stencil settings. | 636 // stencil with arbitrary stencil settings. |
610 GrPathRenderer::StencilSupport stencilSupport; | 637 GrPathRenderer::StencilSupport stencilSupport; |
611 | 638 |
612 SkRegion::Op op = element->getOp(); | 639 SkRegion::Op op = element->getOp(); |
613 | 640 |
614 GrPathRenderer* pr = nullptr; | 641 GrPathRenderer* pr = nullptr; |
615 SkPath clipPath; | 642 SkPath clipPath; |
616 if (Element::kRect_Type == element->getType()) { | 643 if (Element::kRect_Type == element->getType()) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
656 static constexpr GrUserStencilSettings kDrawToStencil( | 683 static constexpr GrUserStencilSettings kDrawToStencil( |
657 GrUserStencilSettings::StaticInit< | 684 GrUserStencilSettings::StaticInit< |
658 0x0000, | 685 0x0000, |
659 GrUserStencilTest::kAlways, | 686 GrUserStencilTest::kAlways, |
660 0xffff, | 687 0xffff, |
661 GrUserStencilOp::kIncMaybeClamp, | 688 GrUserStencilOp::kIncMaybeClamp, |
662 GrUserStencilOp::kIncMaybeClamp, | 689 GrUserStencilOp::kIncMaybeClamp, |
663 0xffff>() | 690 0xffff>() |
664 ); | 691 ); |
665 if (Element::kRect_Type == element->getType()) { | 692 if (Element::kRect_Type == element->getType()) { |
666 drawContext->drawContextPriv().stencilRect(clip, &kDrawToSte
ncil, useHWAA, | 693 drawContext->drawContextPriv().stencilRect(stencilClip.fixed
Clip(), |
| 694 &kDrawToStencil,
useHWAA, |
667 viewMatrix, eleme
nt->getRect()); | 695 viewMatrix, eleme
nt->getRect()); |
668 } else { | 696 } else { |
669 if (!clipPath.isEmpty()) { | 697 if (!clipPath.isEmpty()) { |
670 GrShape shape(clipPath, GrStyle::SimpleFill()); | 698 GrShape shape(clipPath, GrStyle::SimpleFill()); |
671 if (canRenderDirectToStencil) { | 699 if (canRenderDirectToStencil) { |
672 GrPaint paint; | 700 GrPaint paint; |
673 paint.setXPFactory(GrDisableColorXPFactory::Make()); | 701 paint.setXPFactory(GrDisableColorXPFactory::Make()); |
674 paint.setAntiAlias(element->isAA()); | 702 paint.setAntiAlias(element->isAA()); |
675 | 703 |
676 GrPathRenderer::DrawPathArgs args; | 704 GrPathRenderer::DrawPathArgs args; |
677 args.fResourceProvider = context->resourceProvider()
; | 705 args.fResourceProvider = context->resourceProvider()
; |
678 args.fPaint = &paint; | 706 args.fPaint = &paint; |
679 args.fUserStencilSettings = &kDrawToStencil; | 707 args.fUserStencilSettings = &kDrawToStencil; |
680 args.fDrawContext = drawContext; | 708 args.fDrawContext = drawContext; |
681 args.fClip = &clip; | 709 args.fClip = &stencilClip.fixedClip(); |
682 args.fViewMatrix = &viewMatrix; | 710 args.fViewMatrix = &viewMatrix; |
683 args.fShape = &shape; | 711 args.fShape = &shape; |
684 args.fAntiAlias = false; | 712 args.fAntiAlias = false; |
685 args.fGammaCorrect = false; | 713 args.fGammaCorrect = false; |
686 pr->drawPath(args); | 714 pr->drawPath(args); |
687 } else { | 715 } else { |
688 GrPathRenderer::StencilPathArgs args; | 716 GrPathRenderer::StencilPathArgs args; |
689 args.fResourceProvider = context->resourceProvider()
; | 717 args.fResourceProvider = context->resourceProvider()
; |
690 args.fDrawContext = drawContext; | 718 args.fDrawContext = drawContext; |
691 args.fClip = &clip; | 719 args.fClip = &stencilClip.fixedClip(); |
692 args.fViewMatrix = &viewMatrix; | 720 args.fViewMatrix = &viewMatrix; |
693 args.fIsAA = element->isAA(); | 721 args.fIsAA = element->isAA(); |
694 args.fShape = &shape; | 722 args.fShape = &shape; |
695 pr->stencilPath(args); | 723 pr->stencilPath(args); |
696 } | 724 } |
697 } | 725 } |
698 } | 726 } |
699 } | 727 } |
700 | 728 |
701 // Just enable stencil clip. The passes choose whether or not they w
ill actually use it. | |
702 clip.enableStencilClip(); | |
703 | |
704 // now we modify the clip bit by rendering either the clip | 729 // now we modify the clip bit by rendering either the clip |
705 // element directly or a bounding rect of the entire clip. | 730 // element directly or a bounding rect of the entire clip. |
706 for (GrUserStencilSettings const* const* pass = stencilPasses; *pass
; ++pass) { | 731 for (GrUserStencilSettings const* const* pass = stencilPasses; *pass
; ++pass) { |
707 if (drawDirectToClip) { | 732 if (drawDirectToClip) { |
708 if (Element::kRect_Type == element->getType()) { | 733 if (Element::kRect_Type == element->getType()) { |
709 drawContext->drawContextPriv().stencilRect(clip, *pass,
useHWAA, viewMatrix, | 734 drawContext->drawContextPriv().stencilRect(stencilClip,
*pass, useHWAA, |
710 element->getR
ect()); | 735 viewMatrix, e
lement->getRect()); |
711 } else { | 736 } else { |
712 GrShape shape(clipPath, GrStyle::SimpleFill()); | 737 GrShape shape(clipPath, GrStyle::SimpleFill()); |
713 GrPaint paint; | 738 GrPaint paint; |
714 paint.setXPFactory(GrDisableColorXPFactory::Make()); | 739 paint.setXPFactory(GrDisableColorXPFactory::Make()); |
715 paint.setAntiAlias(element->isAA()); | 740 paint.setAntiAlias(element->isAA()); |
716 GrPathRenderer::DrawPathArgs args; | 741 GrPathRenderer::DrawPathArgs args; |
717 args.fResourceProvider = context->resourceProvider(); | 742 args.fResourceProvider = context->resourceProvider(); |
718 args.fPaint = &paint; | 743 args.fPaint = &paint; |
719 args.fUserStencilSettings = *pass; | 744 args.fUserStencilSettings = *pass; |
720 args.fDrawContext = drawContext; | 745 args.fDrawContext = drawContext; |
721 args.fClip = &clip; | 746 args.fClip = &stencilClip; |
722 args.fViewMatrix = &viewMatrix; | 747 args.fViewMatrix = &viewMatrix; |
723 args.fShape = &shape; | 748 args.fShape = &shape; |
724 args.fAntiAlias = false; | 749 args.fAntiAlias = false; |
725 args.fGammaCorrect = false; | 750 args.fGammaCorrect = false; |
726 pr->drawPath(args); | 751 pr->drawPath(args); |
727 } | 752 } |
728 } else { | 753 } else { |
729 // The view matrix is setup to do clip space -> stencil spac
e translation, so | 754 // The view matrix is setup to do clip space -> stencil spac
e translation, so |
730 // draw rect in clip space. | 755 // draw rect in clip space. |
731 drawContext->drawContextPriv().stencilRect(clip, *pass, fals
e, viewMatrix, | 756 drawContext->drawContextPriv().stencilRect(stencilClip, *pas
s, |
| 757 false, viewMatrix
, |
732 SkRect::Make(redu
cedClip.ibounds())); | 758 SkRect::Make(redu
cedClip.ibounds())); |
733 } | 759 } |
734 } | 760 } |
735 } | 761 } |
736 } | 762 } |
737 return true; | 763 return true; |
738 } | 764 } |
739 | 765 |
740 //////////////////////////////////////////////////////////////////////////////// | 766 //////////////////////////////////////////////////////////////////////////////// |
741 sk_sp<GrTexture> GrClipStackClip::CreateSoftwareClipMask(GrTextureProvider* texP
rovider, | 767 sk_sp<GrTexture> GrClipStackClip::CreateSoftwareClipMask(GrTextureProvider* texP
rovider, |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
804 sk_sp<GrTexture> result(texProvider->createApproxTexture(desc)); | 830 sk_sp<GrTexture> result(texProvider->createApproxTexture(desc)); |
805 if (!result) { | 831 if (!result) { |
806 return nullptr; | 832 return nullptr; |
807 } | 833 } |
808 result->resourcePriv().setUniqueKey(key); | 834 result->resourcePriv().setUniqueKey(key); |
809 | 835 |
810 helper.toTexture(result.get()); | 836 helper.toTexture(result.get()); |
811 | 837 |
812 return result; | 838 return result; |
813 } | 839 } |
OLD | NEW |