OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 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 "GrClipMaskManager.h" | 8 #include "GrClipMaskManager.h" |
9 #include "GrCaps.h" | 9 #include "GrCaps.h" |
10 #include "GrDrawContext.h" | 10 #include "GrDrawContext.h" |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 if (prOut) { | 92 if (prOut) { |
93 *prOut = pr; | 93 *prOut = pr; |
94 } | 94 } |
95 return SkToBool(!pr); | 95 return SkToBool(!pr); |
96 } | 96 } |
97 } | 97 } |
98 | 98 |
99 // Determines whether it is possible to draw the element to both the stencil buf
fer and the | 99 // Determines whether it is possible to draw the element to both the stencil buf
fer and the |
100 // alpha mask simultaneously. If so and the element is a path a compatible path
renderer is | 100 // alpha mask simultaneously. If so and the element is a path a compatible path
renderer is |
101 // also returned. | 101 // also returned. |
102 static bool can_stencil_and_draw_element(GrContext* context, | 102 static GrPathRenderer* get_path_renderer(GrContext* context, |
103 GrPipelineBuilder* pipelineBuilder, | 103 GrPipelineBuilder* pipelineBuilder, |
104 GrTexture* texture, | |
105 const SkMatrix& viewMatrix, | 104 const SkMatrix& viewMatrix, |
106 const SkClipStack::Element* element, | 105 const SkClipStack::Element* element) { |
107 GrPathRenderer** pr) { | 106 GrPathRenderer* pr; |
108 pipelineBuilder->setRenderTarget(texture->asRenderTarget()); | |
109 | |
110 static const bool kNeedsStencil = true; | 107 static const bool kNeedsStencil = true; |
111 return !path_needs_SW_renderer(context, | 108 path_needs_SW_renderer(context, *pipelineBuilder, viewMatrix, element, &pr,
kNeedsStencil); |
112 *pipelineBuilder, | 109 return pr; |
113 viewMatrix, | |
114 element, | |
115 pr, | |
116 kNeedsStencil); | |
117 } | 110 } |
118 | 111 |
119 GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget) | 112 GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget) |
120 : fDrawTarget(drawTarget) | 113 : fDrawTarget(drawTarget) |
121 , fClipMode(kIgnoreClip_StencilClipMode) { | 114 , fClipMode(kIgnoreClip_StencilClipMode) { |
122 } | 115 } |
123 | 116 |
124 GrContext* GrClipMaskManager::getContext() { return fDrawTarget->cmmAccess().con
text(); } | 117 GrContext* GrClipMaskManager::getContext() { |
| 118 return fDrawTarget->cmmAccess().context(); |
| 119 } |
125 | 120 |
| 121 const GrCaps* GrClipMaskManager::caps() const { |
| 122 return fDrawTarget->caps(); |
| 123 } |
| 124 |
| 125 GrResourceProvider* GrClipMaskManager::resourceProvider() { |
| 126 return fDrawTarget->cmmAccess().resourceProvider(); |
| 127 } |
126 /* | 128 /* |
127 * This method traverses the clip stack to see if the GrSoftwarePathRenderer | 129 * This method traverses the clip stack to see if the GrSoftwarePathRenderer |
128 * will be used on any element. If so, it returns true to indicate that the | 130 * will be used on any element. If so, it returns true to indicate that the |
129 * entire clip should be rendered in SW and then uploaded en masse to the gpu. | 131 * entire clip should be rendered in SW and then uploaded en masse to the gpu. |
130 */ | 132 */ |
131 bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder& pipelineBuilder, | 133 bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder& pipelineBuilder, |
132 const SkVector& clipToMaskOffset, | 134 const SkVector& clipToMaskOffset, |
133 const GrReducedClip::ElementList& elements
) { | 135 const GrReducedClip::ElementList& elements
) { |
134 // TODO: generalize this function so that when | 136 // TODO: generalize this function so that when |
135 // a clip gets complex enough it can just be done in SW regardless | 137 // a clip gets complex enough it can just be done in SW regardless |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 args.fPath = &path; | 477 args.fPath = &path; |
476 args.fStroke = &stroke; | 478 args.fStroke = &stroke; |
477 args.fAntiAlias = element->isAA(); | 479 args.fAntiAlias = element->isAA(); |
478 pr->drawPath(args); | 480 pr->drawPath(args); |
479 break; | 481 break; |
480 } | 482 } |
481 } | 483 } |
482 return true; | 484 return true; |
483 } | 485 } |
484 | 486 |
485 void GrClipMaskManager::mergeMask(GrPipelineBuilder* pipelineBuilder, | |
486 GrTexture* dstMask, | |
487 GrTexture* srcMask, | |
488 SkRegion::Op op, | |
489 const SkIRect& dstBound, | |
490 const SkIRect& srcBound) { | |
491 pipelineBuilder->setRenderTarget(dstMask->asRenderTarget()); | |
492 | |
493 // We want to invert the coverage here | |
494 set_coverage_drawing_xpf(op, false, pipelineBuilder); | |
495 | |
496 SkMatrix sampleM; | |
497 sampleM.setIDiv(srcMask->width(), srcMask->height()); | |
498 | |
499 pipelineBuilder->addCoverageFragmentProcessor( | |
500 GrTextureDomainEffect::Create(srcMask, | |
501 sampleM, | |
502 GrTextureDomain::MakeTexelDomain(srcMask,
srcBound), | |
503 GrTextureDomain::kDecal_Mode, | |
504 GrTextureParams::kNone_FilterMode))->unref
(); | |
505 | |
506 // The color passed in here does not matter since the coverageSetOpXP won't
read it. | |
507 fDrawTarget->drawNonAARect(*pipelineBuilder, | |
508 GrColor_WHITE, | |
509 SkMatrix::I(), | |
510 SkRect::Make(dstBound)); | |
511 } | |
512 | |
513 GrTexture* GrClipMaskManager::createTempMask(int width, int height) { | |
514 GrSurfaceDesc desc; | |
515 desc.fFlags = kRenderTarget_GrSurfaceFlag; | |
516 desc.fWidth = width; | |
517 desc.fHeight = height; | |
518 if (this->getContext()->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, f
alse)) { | |
519 desc.fConfig = kAlpha_8_GrPixelConfig; | |
520 } else { | |
521 desc.fConfig = kRGBA_8888_GrPixelConfig; | |
522 } | |
523 | |
524 return this->getContext()->textureProvider()->createApproxTexture(desc); | |
525 } | |
526 | |
527 //////////////////////////////////////////////////////////////////////////////// | 487 //////////////////////////////////////////////////////////////////////////////// |
528 // Create a 8-bit clip mask in alpha | 488 // Create a 8-bit clip mask in alpha |
529 | 489 |
530 static void GetClipMaskKey(int32_t clipGenID, const SkIRect& bounds, GrUniqueKey
* key) { | 490 static void GetClipMaskKey(int32_t clipGenID, const SkIRect& bounds, GrUniqueKey
* key) { |
531 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); | 491 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); |
532 GrUniqueKey::Builder builder(key, kDomain, 3); | 492 GrUniqueKey::Builder builder(key, kDomain, 3); |
533 builder[0] = clipGenID; | 493 builder[0] = clipGenID; |
534 builder[1] = SkToU16(bounds.fLeft) | (SkToU16(bounds.fRight) << 16); | 494 builder[1] = SkToU16(bounds.fLeft) | (SkToU16(bounds.fRight) << 16); |
535 builder[2] = SkToU16(bounds.fTop) | (SkToU16(bounds.fBottom) << 16); | 495 builder[2] = SkToU16(bounds.fTop) | (SkToU16(bounds.fBottom) << 16); |
536 } | 496 } |
537 | 497 |
538 GrTexture* GrClipMaskManager::createCachedMask(int width, int height, const GrUn
iqueKey& key, | 498 GrTexture* GrClipMaskManager::createCachedMask(int width, int height, const GrUn
iqueKey& key, |
539 bool renderTarget) { | 499 bool renderTarget) { |
540 GrSurfaceDesc desc; | 500 GrSurfaceDesc desc; |
541 desc.fWidth = width; | 501 desc.fWidth = width; |
542 desc.fHeight = height; | 502 desc.fHeight = height; |
543 desc.fFlags = renderTarget ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFl
ags; | 503 desc.fFlags = renderTarget ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFl
ags; |
544 if (!renderTarget || fDrawTarget->caps()->isConfigRenderable(kAlpha_8_GrPixe
lConfig, false)) { | 504 if (!renderTarget || this->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig
, false)) { |
545 desc.fConfig = kAlpha_8_GrPixelConfig; | 505 desc.fConfig = kAlpha_8_GrPixelConfig; |
546 } else { | 506 } else { |
547 desc.fConfig = kRGBA_8888_GrPixelConfig; | 507 desc.fConfig = kRGBA_8888_GrPixelConfig; |
548 } | 508 } |
549 | 509 |
550 GrTexture* texture = fDrawTarget->cmmAccess().resourceProvider()->createAppr
oxTexture(desc, 0); | 510 GrTexture* texture = this->resourceProvider()->createApproxTexture(desc, 0); |
551 if (!texture) { | 511 if (!texture) { |
552 return nullptr; | 512 return nullptr; |
553 } | 513 } |
554 texture->resourcePriv().setUniqueKey(key); | 514 texture->resourcePriv().setUniqueKey(key); |
555 return texture; | 515 return texture; |
556 } | 516 } |
557 | 517 |
558 GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, | 518 GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, |
559 GrReducedClip::InitialState in
itialState, | 519 GrReducedClip::InitialState in
itialState, |
560 const GrReducedClip::ElementLi
st& elements, | 520 const GrReducedClip::ElementLi
st& elements, |
561 const SkVector& clipToMaskOffs
et, | 521 const SkVector& clipToMaskOffs
et, |
562 const SkIRect& clipSpaceIBound
s) { | 522 const SkIRect& clipSpaceIBound
s) { |
563 GrResourceProvider* resourceProvider = fDrawTarget->cmmAccess().resourceProv
ider(); | 523 GrResourceProvider* resourceProvider = this->resourceProvider(); |
564 GrUniqueKey key; | 524 GrUniqueKey key; |
565 GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key); | 525 GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key); |
566 if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key)
) { | 526 if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key)
) { |
567 return texture; | 527 return texture; |
568 } | 528 } |
569 | 529 |
| 530 // There's no texture in the cache. Let's try to allocate it then. |
570 SkAutoTUnref<GrTexture> texture(this->createCachedMask( | 531 SkAutoTUnref<GrTexture> texture(this->createCachedMask( |
571 clipSpaceIBounds.width(), clipSpaceIBounds.height(), key, true)); | 532 clipSpaceIBounds.width(), clipSpaceIBounds.height(), key, true)); |
572 | |
573 // There's no texture in the cache. Let's try to allocate it then. | |
574 if (!texture) { | 533 if (!texture) { |
575 return nullptr; | 534 return nullptr; |
576 } | 535 } |
577 | 536 |
578 // Set the matrix so that rendered clip elements are transformed to mask spa
ce from clip | 537 // Set the matrix so that rendered clip elements are transformed to mask spa
ce from clip |
579 // space. | 538 // space. |
580 const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMa
skOffset.fY); | 539 const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMa
skOffset.fY); |
581 | 540 |
582 // The texture may be larger than necessary, this rect represents the part o
f the texture | 541 // The texture may be larger than necessary, this rect represents the part o
f the texture |
583 // we populate with a rasterization of the clip. | 542 // we populate with a rasterization of the clip. |
584 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa
ceIBounds.height()); | 543 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa
ceIBounds.height()); |
585 | 544 |
586 // The scratch texture that we are drawing into can be substantially larger
than the mask. Only | 545 // The scratch texture that we are drawing into can be substantially larger
than the mask. Only |
587 // clear the part that we care about. | 546 // clear the part that we care about. |
588 fDrawTarget->clear(&maskSpaceIBounds, | 547 fDrawTarget->clear(&maskSpaceIBounds, |
589 GrReducedClip::kAllIn_InitialState == initialState ? 0xff
ffffff : 0x00000000, | 548 GrReducedClip::kAllIn_InitialState == initialState ? 0xff
ffffff : 0x00000000, |
590 true, | 549 true, |
591 texture->asRenderTarget()); | 550 texture->asRenderTarget()); |
592 | 551 |
593 // When we use the stencil in the below loop it is important to have this cl
ip installed. | 552 // When we use the stencil in the below loop it is important to have this cl
ip installed. |
594 // The second pass that zeros the stencil buffer renders the rect maskSpaceI
Bounds so the first | 553 // The second pass that zeros the stencil buffer renders the rect maskSpaceI
Bounds so the first |
595 // pass must not set values outside of this bounds or stencil values outside
the rect won't be | 554 // pass must not set values outside of this bounds or stencil values outside
the rect won't be |
596 // cleared. | 555 // cleared. |
597 GrClip clip(maskSpaceIBounds); | 556 const GrClip clip(maskSpaceIBounds); |
598 SkAutoTUnref<GrTexture> temp; | |
599 | 557 |
600 // walk through each clip element and perform its set op | 558 // walk through each clip element and perform its set op |
601 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get()
; iter.next()) { | 559 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get()
; iter.next()) { |
602 const Element* element = iter.get(); | 560 const Element* element = iter.get(); |
603 SkRegion::Op op = element->getOp(); | 561 SkRegion::Op op = element->getOp(); |
604 bool invert = element->isInverseFilled(); | 562 bool invert = element->isInverseFilled(); |
605 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere
nce_Op == op) { | 563 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere
nce_Op == op) { |
606 GrPipelineBuilder pipelineBuilder; | 564 GrPipelineBuilder pipelineBuilder; |
607 | 565 |
608 pipelineBuilder.setClip(clip); | 566 pipelineBuilder.setClip(clip); |
609 GrPathRenderer* pr = nullptr; | 567 pipelineBuilder.setRenderTarget(texture->asRenderTarget()); |
610 bool useTemp = !can_stencil_and_draw_element(this->getContext(), &pi
pelineBuilder, | |
611 texture, translate, ele
ment, &pr); | |
612 | 568 |
613 // useSWOnlyPath should now filter out all cases where gpu-side mask
merging is | 569 GrPathRenderer* pr = get_path_renderer(this->getContext(), &pipeline
Builder, |
614 // performed. See skbug.com/4519 for rationale and details. | 570 translate, element); |
615 SkASSERT(!useTemp); | 571 if (Element::kRect_Type != element->getType() && !pr) { |
616 | 572 // useSWOnlyPath should now filter out all cases where gpu-side
mask merging would |
617 GrTexture* dst; | 573 // be performed (i.e., pr would be NULL for a non-rect path). Se
e skbug.com/4519 |
618 // This is the bounds of the clip element in the space of the alpha-
mask. The temporary | 574 // for rationale and details. |
619 // mask buffer can be substantially larger than the actually clip st
ack element. We | 575 SkASSERT(0); |
620 // touch the minimum number of pixels necessary and use decal mode t
o combine it with | 576 continue; |
621 // the accumulator. | |
622 SkIRect maskSpaceElementIBounds; | |
623 | |
624 if (useTemp) { | |
625 if (invert) { | |
626 maskSpaceElementIBounds = maskSpaceIBounds; | |
627 } else { | |
628 SkRect elementBounds = element->getBounds(); | |
629 elementBounds.offset(clipToMaskOffset); | |
630 elementBounds.roundOut(&maskSpaceElementIBounds); | |
631 } | |
632 | |
633 if (!temp) { | |
634 temp.reset(this->createTempMask(maskSpaceIBounds.fRight, | |
635 maskSpaceIBounds.fBottom)); | |
636 if (!temp) { | |
637 texture->resourcePriv().removeUniqueKey(); | |
638 return nullptr; | |
639 } | |
640 } | |
641 dst = temp; | |
642 // clear the temp target and set blend to replace | |
643 fDrawTarget->clear(&maskSpaceElementIBounds, | |
644 invert ? 0xffffffff : 0x00000000, | |
645 true, | |
646 dst->asRenderTarget()); | |
647 set_coverage_drawing_xpf(SkRegion::kReplace_Op, invert, &pipelin
eBuilder); | |
648 } else { | |
649 // draw directly into the result with the stencil set to make th
e pixels affected | |
650 // by the clip shape be non-zero. | |
651 dst = texture; | |
652 GR_STATIC_CONST_SAME_STENCIL(kStencilInElement, | |
653 kReplace_StencilOp, | |
654 kReplace_StencilOp, | |
655 kAlways_StencilFunc, | |
656 0xffff, | |
657 0xffff, | |
658 0xffff); | |
659 pipelineBuilder.setStencil(kStencilInElement); | |
660 set_coverage_drawing_xpf(op, invert, &pipelineBuilder); | |
661 } | 577 } |
662 | 578 |
663 if (!this->drawElement(&pipelineBuilder, translate, dst, element, pr
)) { | 579 // draw directly into the result with the stencil set to make the pi
xels affected |
| 580 // by the clip shape be non-zero. |
| 581 GR_STATIC_CONST_SAME_STENCIL(kStencilInElement, |
| 582 kReplace_StencilOp, |
| 583 kReplace_StencilOp, |
| 584 kAlways_StencilFunc, |
| 585 0xffff, |
| 586 0xffff, |
| 587 0xffff); |
| 588 pipelineBuilder.setStencil(kStencilInElement); |
| 589 set_coverage_drawing_xpf(op, invert, &pipelineBuilder); |
| 590 |
| 591 if (!this->drawElement(&pipelineBuilder, translate, texture, element
, pr)) { |
664 texture->resourcePriv().removeUniqueKey(); | 592 texture->resourcePriv().removeUniqueKey(); |
665 return nullptr; | 593 return nullptr; |
666 } | 594 } |
667 | 595 |
668 if (useTemp) { | 596 { |
669 GrPipelineBuilder backgroundPipelineBuilder; | 597 GrPipelineBuilder backgroundPipelineBuilder; |
670 backgroundPipelineBuilder.setRenderTarget(texture->asRenderTarge
t()); | 598 backgroundPipelineBuilder.setRenderTarget(texture->asRenderTarge
t()); |
671 | 599 |
672 // Now draw into the accumulator using the real operation and th
e temp buffer as a | |
673 // texture | |
674 this->mergeMask(&backgroundPipelineBuilder, | |
675 texture, | |
676 temp, | |
677 op, | |
678 maskSpaceIBounds, | |
679 maskSpaceElementIBounds); | |
680 } else { | |
681 GrPipelineBuilder backgroundPipelineBuilder; | |
682 backgroundPipelineBuilder.setRenderTarget(texture->asRenderTarge
t()); | |
683 | |
684 set_coverage_drawing_xpf(op, !invert, &backgroundPipelineBuilder
); | 600 set_coverage_drawing_xpf(op, !invert, &backgroundPipelineBuilder
); |
685 // Draw to the exterior pixels (those with a zero stencil value)
. | 601 // Draw to the exterior pixels (those with a zero stencil value)
. |
686 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, | 602 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, |
687 kZero_StencilOp, | 603 kZero_StencilOp, |
688 kZero_StencilOp, | 604 kZero_StencilOp, |
689 kEqual_StencilFunc, | 605 kEqual_StencilFunc, |
690 0xffff, | 606 0xffff, |
691 0x0000, | 607 0x0000, |
692 0xffff); | 608 0xffff); |
693 backgroundPipelineBuilder.setStencil(kDrawOutsideElement); | 609 backgroundPipelineBuilder.setStencil(kDrawOutsideElement); |
(...skipping 19 matching lines...) Expand all Loading... |
713 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device | 629 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device |
714 // (as opposed to canvas) coordinates | 630 // (as opposed to canvas) coordinates |
715 bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt, | 631 bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt, |
716 int32_t elementsGenID, | 632 int32_t elementsGenID, |
717 GrReducedClip::InitialState initia
lState, | 633 GrReducedClip::InitialState initia
lState, |
718 const GrReducedClip::ElementList&
elements, | 634 const GrReducedClip::ElementList&
elements, |
719 const SkIRect& clipSpaceIBounds, | 635 const SkIRect& clipSpaceIBounds, |
720 const SkIPoint& clipSpaceToStencil
Offset) { | 636 const SkIPoint& clipSpaceToStencil
Offset) { |
721 SkASSERT(rt); | 637 SkASSERT(rt); |
722 | 638 |
723 GrStencilAttachment* stencilAttachment = | 639 GrStencilAttachment* stencilAttachment = this->resourceProvider()->attachSte
ncilAttachment(rt); |
724 fDrawTarget->cmmAccess().resourceProvider()->attachStencilAttachment(rt)
; | |
725 if (nullptr == stencilAttachment) { | 640 if (nullptr == stencilAttachment) { |
726 return false; | 641 return false; |
727 } | 642 } |
728 | 643 |
729 if (stencilAttachment->mustRenderClip(elementsGenID, clipSpaceIBounds, clipS
paceToStencilOffset)) { | 644 if (stencilAttachment->mustRenderClip(elementsGenID, clipSpaceIBounds, clipS
paceToStencilOffset)) { |
730 stencilAttachment->setLastClip(elementsGenID, clipSpaceIBounds, clipSpac
eToStencilOffset); | 645 stencilAttachment->setLastClip(elementsGenID, clipSpaceIBounds, clipSpac
eToStencilOffset); |
731 // Set the matrix so that rendered clip elements are transformed from cl
ip to stencil space. | 646 // Set the matrix so that rendered clip elements are transformed from cl
ip to stencil space. |
732 SkVector translate = { | 647 SkVector translate = { |
733 SkIntToScalar(clipSpaceToStencilOffset.fX), | 648 SkIntToScalar(clipSpaceToStencilOffset.fX), |
734 SkIntToScalar(clipSpaceToStencilOffset.fY) | 649 SkIntToScalar(clipSpaceToStencilOffset.fY) |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
970 settings = basic_apply_stencil_clip_settings(); | 885 settings = basic_apply_stencil_clip_settings(); |
971 } else { | 886 } else { |
972 return; | 887 return; |
973 } | 888 } |
974 } else { | 889 } else { |
975 settings = pipelineBuilder.getStencil(); | 890 settings = pipelineBuilder.getStencil(); |
976 } | 891 } |
977 | 892 |
978 int stencilBits = 0; | 893 int stencilBits = 0; |
979 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); | 894 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); |
980 GrStencilAttachment* stencilAttachment = | 895 GrStencilAttachment* stencilAttachment = this->resourceProvider()->attachSte
ncilAttachment(rt); |
981 fDrawTarget->cmmAccess().resourceProvider()->attachStencilAttachment(rt)
; | |
982 if (stencilAttachment) { | 896 if (stencilAttachment) { |
983 stencilBits = stencilAttachment->bits(); | 897 stencilBits = stencilAttachment->bits(); |
984 } | 898 } |
985 | 899 |
986 SkASSERT(fDrawTarget->caps()->stencilWrapOpsSupport() || !settings.usesWrapO
p()); | 900 SkASSERT(this->caps()->stencilWrapOpsSupport() || !settings.usesWrapOp()); |
987 SkASSERT(fDrawTarget->caps()->twoSidedStencilSupport() || !settings.isTwoSid
ed()); | 901 SkASSERT(this->caps()->twoSidedStencilSupport() || !settings.isTwoSided()); |
988 this->adjustStencilParams(&settings, fClipMode, stencilBits); | 902 this->adjustStencilParams(&settings, fClipMode, stencilBits); |
989 ars->set(&pipelineBuilder); | 903 ars->set(&pipelineBuilder); |
990 ars->setStencil(settings); | 904 ars->setStencil(settings); |
991 } | 905 } |
992 | 906 |
993 void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings, | 907 void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings, |
994 StencilClipMode mode, | 908 StencilClipMode mode, |
995 int stencilBitCnt) { | 909 int stencilBitCnt) { |
996 SkASSERT(stencilBitCnt > 0); | 910 SkASSERT(stencilBitCnt > 0); |
997 | 911 |
998 if (kModifyClip_StencilClipMode == mode) { | 912 if (kModifyClip_StencilClipMode == mode) { |
999 // We assume that this clip manager itself is drawing to the GrGpu and | 913 // We assume that this clip manager itself is drawing to the GrGpu and |
1000 // has already setup the correct values. | 914 // has already setup the correct values. |
1001 return; | 915 return; |
1002 } | 916 } |
1003 | 917 |
1004 unsigned int clipBit = (1 << (stencilBitCnt - 1)); | 918 unsigned int clipBit = (1 << (stencilBitCnt - 1)); |
1005 unsigned int userBits = clipBit - 1; | 919 unsigned int userBits = clipBit - 1; |
1006 | 920 |
1007 GrStencilSettings::Face face = GrStencilSettings::kFront_Face; | 921 GrStencilSettings::Face face = GrStencilSettings::kFront_Face; |
1008 bool twoSided = fDrawTarget->caps()->twoSidedStencilSupport(); | 922 bool twoSided = this->caps()->twoSidedStencilSupport(); |
1009 | 923 |
1010 bool finished = false; | 924 bool finished = false; |
1011 while (!finished) { | 925 while (!finished) { |
1012 GrStencilFunc func = settings->func(face); | 926 GrStencilFunc func = settings->func(face); |
1013 uint16_t writeMask = settings->writeMask(face); | 927 uint16_t writeMask = settings->writeMask(face); |
1014 uint16_t funcMask = settings->funcMask(face); | 928 uint16_t funcMask = settings->funcMask(face); |
1015 uint16_t funcRef = settings->funcRef(face); | 929 uint16_t funcRef = settings->funcRef(face); |
1016 | 930 |
1017 SkASSERT((unsigned) func < kStencilFuncCount); | 931 SkASSERT((unsigned) func < kStencilFuncCount); |
1018 | 932 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1070 } | 984 } |
1071 | 985 |
1072 //////////////////////////////////////////////////////////////////////////////// | 986 //////////////////////////////////////////////////////////////////////////////// |
1073 GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID, | 987 GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID, |
1074 GrReducedClip::InitialState
initialState, | 988 GrReducedClip::InitialState
initialState, |
1075 const GrReducedClip::Elemen
tList& elements, | 989 const GrReducedClip::Elemen
tList& elements, |
1076 const SkVector& clipToMaskO
ffset, | 990 const SkVector& clipToMaskO
ffset, |
1077 const SkIRect& clipSpaceIBo
unds) { | 991 const SkIRect& clipSpaceIBo
unds) { |
1078 GrUniqueKey key; | 992 GrUniqueKey key; |
1079 GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key); | 993 GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key); |
1080 GrResourceProvider* resourceProvider = fDrawTarget->cmmAccess().resourceProv
ider(); | 994 GrResourceProvider* resourceProvider = this->resourceProvider(); |
1081 if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key)
) { | 995 if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key)
) { |
1082 return texture; | 996 return texture; |
1083 } | 997 } |
1084 | 998 |
1085 // The mask texture may be larger than necessary. We round out the clip spac
e bounds and pin | 999 // The mask texture may be larger than necessary. We round out the clip spac
e bounds and pin |
1086 // the top left corner of the resulting rect to the top left of the texture. | 1000 // the top left corner of the resulting rect to the top left of the texture. |
1087 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa
ceIBounds.height()); | 1001 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa
ceIBounds.height()); |
1088 | 1002 |
1089 GrSWMaskHelper helper(this->getContext()); | 1003 GrSWMaskHelper helper(this->getContext()); |
1090 | 1004 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1142 | 1056 |
1143 //////////////////////////////////////////////////////////////////////////////// | 1057 //////////////////////////////////////////////////////////////////////////////// |
1144 | 1058 |
1145 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc
ilAttachment, | 1059 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc
ilAttachment, |
1146 GrStencilSettings* settings) { | 1060 GrStencilSettings* settings) { |
1147 if (stencilAttachment) { | 1061 if (stencilAttachment) { |
1148 int stencilBits = stencilAttachment->bits(); | 1062 int stencilBits = stencilAttachment->bits(); |
1149 this->adjustStencilParams(settings, fClipMode, stencilBits); | 1063 this->adjustStencilParams(settings, fClipMode, stencilBits); |
1150 } | 1064 } |
1151 } | 1065 } |
OLD | NEW |