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" |
11 #include "GrDrawTarget.h" | 11 #include "GrDrawTarget.h" |
| 12 #include "GrGpuResourcePriv.h" |
12 #include "GrPaint.h" | 13 #include "GrPaint.h" |
13 #include "GrPathRenderer.h" | 14 #include "GrPathRenderer.h" |
14 #include "GrRenderTarget.h" | 15 #include "GrRenderTarget.h" |
15 #include "GrRenderTargetPriv.h" | 16 #include "GrRenderTargetPriv.h" |
| 17 #include "GrResourceProvider.h" |
16 #include "GrStencilAttachment.h" | 18 #include "GrStencilAttachment.h" |
17 #include "GrSWMaskHelper.h" | 19 #include "GrSWMaskHelper.h" |
18 #include "SkRasterClip.h" | 20 #include "SkRasterClip.h" |
19 #include "SkTLazy.h" | 21 #include "SkTLazy.h" |
20 #include "effects/GrConvexPolyEffect.h" | 22 #include "effects/GrConvexPolyEffect.h" |
21 #include "effects/GrPorterDuffXferProcessor.h" | 23 #include "effects/GrPorterDuffXferProcessor.h" |
22 #include "effects/GrRRectEffect.h" | 24 #include "effects/GrRRectEffect.h" |
23 #include "effects/GrTextureDomain.h" | 25 #include "effects/GrTextureDomain.h" |
24 | 26 |
25 typedef SkClipStack::Element Element; | 27 typedef SkClipStack::Element Element; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 GrPathRendererChain::kColorAntiAlias_Dr
awType : | 73 GrPathRendererChain::kColorAntiAlias_Dr
awType : |
72 GrPathRendererChain::kColor_DrawType; | 74 GrPathRendererChain::kColor_DrawType; |
73 | 75 |
74 return nullptr == context->getPathRenderer(gpu, &pipelineBuilder, viewMatrix
, *path, stroke, | 76 return nullptr == context->getPathRenderer(gpu, &pipelineBuilder, viewMatrix
, *path, stroke, |
75 false, type); | 77 false, type); |
76 } | 78 } |
77 } | 79 } |
78 | 80 |
79 GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget) | 81 GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget) |
80 : fCurrClipMaskType(kNone_ClipMaskType) | 82 : fCurrClipMaskType(kNone_ClipMaskType) |
81 , fAACache(drawTarget->cmmAccess().resourceProvider()) | |
82 , fDrawTarget(drawTarget) | 83 , fDrawTarget(drawTarget) |
83 , fClipMode(kIgnoreClip_StencilClipMode) { | 84 , fClipMode(kIgnoreClip_StencilClipMode) { |
84 } | 85 } |
85 | 86 |
86 GrContext* GrClipMaskManager::getContext() { return fDrawTarget->cmmAccess().con
text(); } | 87 GrContext* GrClipMaskManager::getContext() { return fDrawTarget->cmmAccess().con
text(); } |
87 | 88 |
88 /* | 89 /* |
89 * This method traverses the clip stack to see if the GrSoftwarePathRenderer | 90 * This method traverses the clip stack to see if the GrSoftwarePathRenderer |
90 * will be used on any element. If so, it returns true to indicate that the | 91 * will be used on any element. If so, it returns true to indicate that the |
91 * entire clip should be rendered in SW and then uploaded en masse to the gpu. | 92 * entire clip should be rendered in SW and then uploaded en masse to the gpu. |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 // clipSpace bounds. We determine the mask's position WRT to the ren
der target here. | 338 // clipSpace bounds. We determine the mask's position WRT to the ren
der target here. |
338 SkIRect rtSpaceMaskBounds = clipSpaceIBounds; | 339 SkIRect rtSpaceMaskBounds = clipSpaceIBounds; |
339 rtSpaceMaskBounds.offset(-clip.origin()); | 340 rtSpaceMaskBounds.offset(-clip.origin()); |
340 setup_drawstate_aaclip(pipelineBuilder, result, arfps, rtSpaceMaskBo
unds); | 341 setup_drawstate_aaclip(pipelineBuilder, result, arfps, rtSpaceMaskBo
unds); |
341 this->setPipelineBuilderStencil(pipelineBuilder, ars); | 342 this->setPipelineBuilderStencil(pipelineBuilder, ars); |
342 return true; | 343 return true; |
343 } | 344 } |
344 // if alpha clip mask creation fails fall through to the non-AA code pat
hs | 345 // if alpha clip mask creation fails fall through to the non-AA code pat
hs |
345 } | 346 } |
346 | 347 |
347 // Either a hard (stencil buffer) clip was explicitly requested or an anti-a
liased clip couldn't | |
348 // be created. In either case, free up the texture in the anti-aliased mask
cache. | |
349 // TODO: this may require more investigation. Ganesh performs a lot of utili
ty draws (e.g., | |
350 // clears, GrBufferedDrawTarget playbacks) that hit the stencil buffer path.
These may be | |
351 // "incorrectly" clearing the AA cache. | |
352 fAACache.reset(); | |
353 | |
354 // use the stencil clip if we can't represent the clip as a rectangle. | 348 // use the stencil clip if we can't represent the clip as a rectangle. |
355 SkIPoint clipSpaceToStencilSpaceOffset = -clip.origin(); | 349 SkIPoint clipSpaceToStencilSpaceOffset = -clip.origin(); |
356 this->createStencilClipMask(rt, | 350 this->createStencilClipMask(rt, |
357 genID, | 351 genID, |
358 initialState, | 352 initialState, |
359 elements, | 353 elements, |
360 clipSpaceIBounds, | 354 clipSpaceIBounds, |
361 clipSpaceToStencilSpaceOffset); | 355 clipSpaceToStencilSpaceOffset); |
362 | 356 |
363 // This must occur after createStencilClipMask. That function may change the
scissor. Also, it | 357 // This must occur after createStencilClipMask. That function may change the
scissor. Also, it |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
509 if (this->getContext()->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, f
alse)) { | 503 if (this->getContext()->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, f
alse)) { |
510 desc.fConfig = kAlpha_8_GrPixelConfig; | 504 desc.fConfig = kAlpha_8_GrPixelConfig; |
511 } else { | 505 } else { |
512 desc.fConfig = kRGBA_8888_GrPixelConfig; | 506 desc.fConfig = kRGBA_8888_GrPixelConfig; |
513 } | 507 } |
514 | 508 |
515 return this->getContext()->textureProvider()->createApproxTexture(desc); | 509 return this->getContext()->textureProvider()->createApproxTexture(desc); |
516 } | 510 } |
517 | 511 |
518 //////////////////////////////////////////////////////////////////////////////// | 512 //////////////////////////////////////////////////////////////////////////////// |
519 // Return the texture currently in the cache if it exists. Otherwise, return nul
lptr | |
520 GrTexture* GrClipMaskManager::getCachedMaskTexture(int32_t elementsGenID, | |
521 const SkIRect& clipSpaceIBoun
ds) { | |
522 bool cached = fAACache.canReuse(elementsGenID, clipSpaceIBounds); | |
523 if (!cached) { | |
524 return nullptr; | |
525 } | |
526 | |
527 return fAACache.getLastMask(); | |
528 } | |
529 | |
530 //////////////////////////////////////////////////////////////////////////////// | |
531 // Allocate a texture in the texture cache. This function returns the texture | |
532 // allocated (or nullptr on error). | |
533 GrTexture* GrClipMaskManager::allocMaskTexture(int32_t elementsGenID, | |
534 const SkIRect& clipSpaceIBounds, | |
535 bool willUpload) { | |
536 // Since we are setting up the cache we should free up the | |
537 // currently cached mask so it can be reused. | |
538 fAACache.reset(); | |
539 | |
540 GrSurfaceDesc desc; | |
541 desc.fFlags = willUpload ? kNone_GrSurfaceFlags : kRenderTarget_GrSurfaceFla
g; | |
542 desc.fWidth = clipSpaceIBounds.width(); | |
543 desc.fHeight = clipSpaceIBounds.height(); | |
544 desc.fConfig = kRGBA_8888_GrPixelConfig; | |
545 if (willUpload || | |
546 this->getContext()->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, f
alse)) { | |
547 // We would always like A8 but it isn't supported on all platforms | |
548 desc.fConfig = kAlpha_8_GrPixelConfig; | |
549 } | |
550 | |
551 fAACache.acquireMask(elementsGenID, desc, clipSpaceIBounds); | |
552 return fAACache.getLastMask(); | |
553 } | |
554 | |
555 //////////////////////////////////////////////////////////////////////////////// | |
556 // Create a 8-bit clip mask in alpha | 513 // Create a 8-bit clip mask in alpha |
| 514 |
| 515 static void GetClipMaskKey(int32_t clipGenID, const SkIRect& bounds, GrUniqueKey
* key) { |
| 516 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); |
| 517 GrUniqueKey::Builder builder(key, kDomain, 3); |
| 518 builder[0] = clipGenID; |
| 519 builder[1] = SkToU16(bounds.fLeft) | (SkToU16(bounds.fRight) << 16); |
| 520 builder[2] = SkToU16(bounds.fTop) | (SkToU16(bounds.fBottom) << 16); |
| 521 } |
| 522 |
| 523 GrTexture* GrClipMaskManager::createCachedMask(int width, int height, const GrUn
iqueKey& key, |
| 524 bool renderTarget) { |
| 525 GrSurfaceDesc desc; |
| 526 desc.fWidth = width; |
| 527 desc.fHeight = height; |
| 528 desc.fFlags = renderTarget ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFl
ags; |
| 529 if (!renderTarget || fDrawTarget->caps()->isConfigRenderable(kAlpha_8_GrPixe
lConfig, false)) { |
| 530 desc.fConfig = kAlpha_8_GrPixelConfig; |
| 531 } else { |
| 532 desc.fConfig = kRGBA_8888_GrPixelConfig; |
| 533 } |
| 534 |
| 535 GrTexture* texture = fDrawTarget->cmmAccess().resourceProvider()->createAppr
oxTexture(desc, 0); |
| 536 if (!texture) { |
| 537 return nullptr; |
| 538 } |
| 539 texture->resourcePriv().setUniqueKey(key); |
| 540 return texture; |
| 541 } |
| 542 |
557 GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, | 543 GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, |
558 GrReducedClip::InitialState in
itialState, | 544 GrReducedClip::InitialState in
itialState, |
559 const GrReducedClip::ElementLi
st& elements, | 545 const GrReducedClip::ElementLi
st& elements, |
560 const SkVector& clipToMaskOffs
et, | 546 const SkVector& clipToMaskOffs
et, |
561 const SkIRect& clipSpaceIBound
s) { | 547 const SkIRect& clipSpaceIBound
s) { |
562 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); | 548 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); |
563 | 549 GrResourceProvider* resourceProvider = fDrawTarget->cmmAccess().resourceProv
ider(); |
564 // First, check for cached texture | 550 GrUniqueKey key; |
565 GrTexture* result = this->getCachedMaskTexture(elementsGenID, clipSpaceIBoun
ds); | 551 GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key); |
566 if (result) { | 552 if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key)
) { |
567 fCurrClipMaskType = kAlpha_ClipMaskType; | 553 fCurrClipMaskType = kAlpha_ClipMaskType; |
568 return result; | 554 return texture; |
569 } | 555 } |
570 | 556 |
| 557 SkAutoTUnref<GrTexture> texture(this->createCachedMask( |
| 558 clipSpaceIBounds.width(), clipSpaceIBounds.height(), key, true)); |
| 559 |
571 // There's no texture in the cache. Let's try to allocate it then. | 560 // There's no texture in the cache. Let's try to allocate it then. |
572 result = this->allocMaskTexture(elementsGenID, clipSpaceIBounds, false); | 561 if (!texture) { |
573 if (nullptr == result) { | |
574 fAACache.reset(); | |
575 return nullptr; | 562 return nullptr; |
576 } | 563 } |
577 | 564 |
578 // Set the matrix so that rendered clip elements are transformed to mask spa
ce from clip | 565 // Set the matrix so that rendered clip elements are transformed to mask spa
ce from clip |
579 // space. | 566 // space. |
580 SkMatrix translate; | 567 SkMatrix translate; |
581 translate.setTranslate(clipToMaskOffset); | 568 translate.setTranslate(clipToMaskOffset); |
582 | 569 |
583 // The texture may be larger than necessary, this rect represents the part o
f the texture | 570 // The texture may be larger than necessary, this rect represents the part o
f the texture |
584 // we populate with a rasterization of the clip. | 571 // we populate with a rasterization of the clip. |
585 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa
ceIBounds.height()); | 572 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa
ceIBounds.height()); |
586 | 573 |
587 // The scratch texture that we are drawing into can be substantially larger
than the mask. Only | 574 // The scratch texture that we are drawing into can be substantially larger
than the mask. Only |
588 // clear the part that we care about. | 575 // clear the part that we care about. |
589 fDrawTarget->clear(&maskSpaceIBounds, | 576 fDrawTarget->clear(&maskSpaceIBounds, |
590 GrReducedClip::kAllIn_InitialState == initialState ? 0xff
ffffff : 0x00000000, | 577 GrReducedClip::kAllIn_InitialState == initialState ? 0xff
ffffff : 0x00000000, |
591 true, | 578 true, |
592 result->asRenderTarget()); | 579 texture->asRenderTarget()); |
593 | 580 |
594 // When we use the stencil in the below loop it is important to have this cl
ip installed. | 581 // When we use the stencil in the below loop it is important to have this cl
ip installed. |
595 // The second pass that zeros the stencil buffer renders the rect maskSpaceI
Bounds so the first | 582 // The second pass that zeros the stencil buffer renders the rect maskSpaceI
Bounds so the first |
596 // pass must not set values outside of this bounds or stencil values outside
the rect won't be | 583 // pass must not set values outside of this bounds or stencil values outside
the rect won't be |
597 // cleared. | 584 // cleared. |
598 GrClip clip(maskSpaceIBounds); | 585 GrClip clip(maskSpaceIBounds); |
599 SkAutoTUnref<GrTexture> temp; | 586 SkAutoTUnref<GrTexture> temp; |
600 | 587 |
601 // walk through each clip element and perform its set op | 588 // walk through each clip element and perform its set op |
602 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get()
; iter.next()) { | 589 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get()
; iter.next()) { |
603 const Element* element = iter.get(); | 590 const Element* element = iter.get(); |
604 SkRegion::Op op = element->getOp(); | 591 SkRegion::Op op = element->getOp(); |
605 bool invert = element->isInverseFilled(); | 592 bool invert = element->isInverseFilled(); |
606 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere
nce_Op == op) { | 593 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere
nce_Op == op) { |
607 GrPipelineBuilder pipelineBuilder; | 594 GrPipelineBuilder pipelineBuilder; |
608 | 595 |
609 pipelineBuilder.setClip(clip); | 596 pipelineBuilder.setClip(clip); |
610 GrPathRenderer* pr = nullptr; | 597 GrPathRenderer* pr = nullptr; |
611 bool useTemp = !this->canStencilAndDrawElement(&pipelineBuilder, res
ult, &pr, element); | 598 bool useTemp = !this->canStencilAndDrawElement(&pipelineBuilder, tex
ture, &pr, element); |
612 GrTexture* dst; | 599 GrTexture* dst; |
613 // This is the bounds of the clip element in the space of the alpha-
mask. The temporary | 600 // This is the bounds of the clip element in the space of the alpha-
mask. The temporary |
614 // mask buffer can be substantially larger than the actually clip st
ack element. We | 601 // mask buffer can be substantially larger than the actually clip st
ack element. We |
615 // touch the minimum number of pixels necessary and use decal mode t
o combine it with | 602 // touch the minimum number of pixels necessary and use decal mode t
o combine it with |
616 // the accumulator. | 603 // the accumulator. |
617 SkIRect maskSpaceElementIBounds; | 604 SkIRect maskSpaceElementIBounds; |
618 | 605 |
619 if (useTemp) { | 606 if (useTemp) { |
620 if (invert) { | 607 if (invert) { |
621 maskSpaceElementIBounds = maskSpaceIBounds; | 608 maskSpaceElementIBounds = maskSpaceIBounds; |
622 } else { | 609 } else { |
623 SkRect elementBounds = element->getBounds(); | 610 SkRect elementBounds = element->getBounds(); |
624 elementBounds.offset(clipToMaskOffset); | 611 elementBounds.offset(clipToMaskOffset); |
625 elementBounds.roundOut(&maskSpaceElementIBounds); | 612 elementBounds.roundOut(&maskSpaceElementIBounds); |
626 } | 613 } |
627 | 614 |
628 if (!temp) { | 615 if (!temp) { |
629 temp.reset(this->createTempMask(maskSpaceIBounds.fRight, | 616 temp.reset(this->createTempMask(maskSpaceIBounds.fRight, |
630 maskSpaceIBounds.fBottom)); | 617 maskSpaceIBounds.fBottom)); |
631 if (!temp) { | 618 if (!temp) { |
632 fAACache.reset(); | 619 texture->resourcePriv().removeUniqueKey(); |
633 return nullptr; | 620 return nullptr; |
634 } | 621 } |
635 } | 622 } |
636 dst = temp; | 623 dst = temp; |
637 // clear the temp target and set blend to replace | 624 // clear the temp target and set blend to replace |
638 fDrawTarget->clear(&maskSpaceElementIBounds, | 625 fDrawTarget->clear(&maskSpaceElementIBounds, |
639 invert ? 0xffffffff : 0x00000000, | 626 invert ? 0xffffffff : 0x00000000, |
640 true, | 627 true, |
641 dst->asRenderTarget()); | 628 dst->asRenderTarget()); |
642 set_coverage_drawing_xpf(SkRegion::kReplace_Op, invert, &pipelin
eBuilder); | 629 set_coverage_drawing_xpf(SkRegion::kReplace_Op, invert, &pipelin
eBuilder); |
643 } else { | 630 } else { |
644 // draw directly into the result with the stencil set to make th
e pixels affected | 631 // draw directly into the result with the stencil set to make th
e pixels affected |
645 // by the clip shape be non-zero. | 632 // by the clip shape be non-zero. |
646 dst = result; | 633 dst = texture; |
647 GR_STATIC_CONST_SAME_STENCIL(kStencilInElement, | 634 GR_STATIC_CONST_SAME_STENCIL(kStencilInElement, |
648 kReplace_StencilOp, | 635 kReplace_StencilOp, |
649 kReplace_StencilOp, | 636 kReplace_StencilOp, |
650 kAlways_StencilFunc, | 637 kAlways_StencilFunc, |
651 0xffff, | 638 0xffff, |
652 0xffff, | 639 0xffff, |
653 0xffff); | 640 0xffff); |
654 pipelineBuilder.setStencil(kStencilInElement); | 641 pipelineBuilder.setStencil(kStencilInElement); |
655 set_coverage_drawing_xpf(op, invert, &pipelineBuilder); | 642 set_coverage_drawing_xpf(op, invert, &pipelineBuilder); |
656 } | 643 } |
657 | 644 |
658 if (!this->drawElement(&pipelineBuilder, translate, dst, element, pr
)) { | 645 if (!this->drawElement(&pipelineBuilder, translate, dst, element, pr
)) { |
659 fAACache.reset(); | 646 texture->resourcePriv().removeUniqueKey(); |
660 return nullptr; | 647 return nullptr; |
661 } | 648 } |
662 | 649 |
663 if (useTemp) { | 650 if (useTemp) { |
664 GrPipelineBuilder backgroundPipelineBuilder; | 651 GrPipelineBuilder backgroundPipelineBuilder; |
665 backgroundPipelineBuilder.setRenderTarget(result->asRenderTarget
()); | 652 backgroundPipelineBuilder.setRenderTarget(texture->asRenderTarge
t()); |
666 | 653 |
667 // Now draw into the accumulator using the real operation and th
e temp buffer as a | 654 // Now draw into the accumulator using the real operation and th
e temp buffer as a |
668 // texture | 655 // texture |
669 this->mergeMask(&backgroundPipelineBuilder, | 656 this->mergeMask(&backgroundPipelineBuilder, |
670 result, | 657 texture, |
671 temp, | 658 temp, |
672 op, | 659 op, |
673 maskSpaceIBounds, | 660 maskSpaceIBounds, |
674 maskSpaceElementIBounds); | 661 maskSpaceElementIBounds); |
675 } else { | 662 } else { |
676 GrPipelineBuilder backgroundPipelineBuilder; | 663 GrPipelineBuilder backgroundPipelineBuilder; |
677 backgroundPipelineBuilder.setRenderTarget(result->asRenderTarget
()); | 664 backgroundPipelineBuilder.setRenderTarget(texture->asRenderTarge
t()); |
678 | 665 |
679 set_coverage_drawing_xpf(op, !invert, &backgroundPipelineBuilder
); | 666 set_coverage_drawing_xpf(op, !invert, &backgroundPipelineBuilder
); |
680 // Draw to the exterior pixels (those with a zero stencil value)
. | 667 // Draw to the exterior pixels (those with a zero stencil value)
. |
681 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, | 668 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, |
682 kZero_StencilOp, | 669 kZero_StencilOp, |
683 kZero_StencilOp, | 670 kZero_StencilOp, |
684 kEqual_StencilFunc, | 671 kEqual_StencilFunc, |
685 0xffff, | 672 0xffff, |
686 0x0000, | 673 0x0000, |
687 0xffff); | 674 0xffff); |
688 backgroundPipelineBuilder.setStencil(kDrawOutsideElement); | 675 backgroundPipelineBuilder.setStencil(kDrawOutsideElement); |
689 | 676 |
690 // The color passed in here does not matter since the coverageSe
tOpXP won't read it. | 677 // The color passed in here does not matter since the coverageSe
tOpXP won't read it. |
691 fDrawTarget->drawNonAARect(backgroundPipelineBuilder, GrColor_WH
ITE, translate, | 678 fDrawTarget->drawNonAARect(backgroundPipelineBuilder, GrColor_WH
ITE, translate, |
692 clipSpaceIBounds); | 679 clipSpaceIBounds); |
693 } | 680 } |
694 } else { | 681 } else { |
695 GrPipelineBuilder pipelineBuilder; | 682 GrPipelineBuilder pipelineBuilder; |
696 | 683 |
697 // all the remaining ops can just be directly draw into the accumula
tion buffer | 684 // all the remaining ops can just be directly draw into the accumula
tion buffer |
698 set_coverage_drawing_xpf(op, false, &pipelineBuilder); | 685 set_coverage_drawing_xpf(op, false, &pipelineBuilder); |
699 // The color passed in here does not matter since the coverageSetOpX
P won't read it. | 686 // The color passed in here does not matter since the coverageSetOpX
P won't read it. |
700 this->drawElement(&pipelineBuilder, translate, result, element); | 687 this->drawElement(&pipelineBuilder, translate, texture, element); |
701 } | 688 } |
702 } | 689 } |
703 | 690 |
704 fCurrClipMaskType = kAlpha_ClipMaskType; | 691 fCurrClipMaskType = kAlpha_ClipMaskType; |
705 return result; | 692 return texture.detach(); |
706 } | 693 } |
707 | 694 |
708 //////////////////////////////////////////////////////////////////////////////// | 695 //////////////////////////////////////////////////////////////////////////////// |
709 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device | 696 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device |
710 // (as opposed to canvas) coordinates | 697 // (as opposed to canvas) coordinates |
711 bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt, | 698 bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt, |
712 int32_t elementsGenID, | 699 int32_t elementsGenID, |
713 GrReducedClip::InitialState initia
lState, | 700 GrReducedClip::InitialState initia
lState, |
714 const GrReducedClip::ElementList&
elements, | 701 const GrReducedClip::ElementList&
elements, |
715 const SkIRect& clipSpaceIBounds, | 702 const SkIRect& clipSpaceIBounds, |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1072 } | 1059 } |
1073 } | 1060 } |
1074 | 1061 |
1075 //////////////////////////////////////////////////////////////////////////////// | 1062 //////////////////////////////////////////////////////////////////////////////// |
1076 GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID, | 1063 GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID, |
1077 GrReducedClip::InitialState
initialState, | 1064 GrReducedClip::InitialState
initialState, |
1078 const GrReducedClip::Elemen
tList& elements, | 1065 const GrReducedClip::Elemen
tList& elements, |
1079 const SkVector& clipToMaskO
ffset, | 1066 const SkVector& clipToMaskO
ffset, |
1080 const SkIRect& clipSpaceIBo
unds) { | 1067 const SkIRect& clipSpaceIBo
unds) { |
1081 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); | 1068 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); |
1082 | 1069 GrUniqueKey key; |
1083 GrTexture* result = this->getCachedMaskTexture(elementsGenID, clipSpaceIBoun
ds); | 1070 GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key); |
1084 if (result) { | 1071 GrResourceProvider* resourceProvider = fDrawTarget->cmmAccess().resourceProv
ider(); |
1085 return result; | 1072 if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key)
) { |
| 1073 return texture; |
1086 } | 1074 } |
1087 | 1075 |
1088 // The mask texture may be larger than necessary. We round out the clip spac
e bounds and pin | 1076 // The mask texture may be larger than necessary. We round out the clip spac
e bounds and pin |
1089 // the top left corner of the resulting rect to the top left of the texture. | 1077 // the top left corner of the resulting rect to the top left of the texture. |
1090 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa
ceIBounds.height()); | 1078 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa
ceIBounds.height()); |
1091 | 1079 |
1092 GrSWMaskHelper helper(this->getContext()); | 1080 GrSWMaskHelper helper(this->getContext()); |
1093 | 1081 |
1094 // Set the matrix so that rendered clip elements are transformed to mask spa
ce from clip | 1082 // Set the matrix so that rendered clip elements are transformed to mask spa
ce from clip |
1095 // space. | 1083 // space. |
(...skipping 30 matching lines...) Expand all Loading... |
1126 if (Element::kRect_Type == element->getType()) { | 1114 if (Element::kRect_Type == element->getType()) { |
1127 helper.draw(element->getRect(), op, element->isAA(), 0xFF); | 1115 helper.draw(element->getRect(), op, element->isAA(), 0xFF); |
1128 } else { | 1116 } else { |
1129 SkPath path; | 1117 SkPath path; |
1130 element->asPath(&path); | 1118 element->asPath(&path); |
1131 helper.draw(path, stroke, op, element->isAA(), 0xFF); | 1119 helper.draw(path, stroke, op, element->isAA(), 0xFF); |
1132 } | 1120 } |
1133 } | 1121 } |
1134 | 1122 |
1135 // Allocate clip mask texture | 1123 // Allocate clip mask texture |
1136 result = this->allocMaskTexture(elementsGenID, clipSpaceIBounds, true); | 1124 GrTexture* result = this->createCachedMask(clipSpaceIBounds.width(), clipSpa
ceIBounds.height(), |
| 1125 key, false); |
1137 if (nullptr == result) { | 1126 if (nullptr == result) { |
1138 fAACache.reset(); | |
1139 return nullptr; | 1127 return nullptr; |
1140 } | 1128 } |
1141 helper.toTexture(result); | 1129 helper.toTexture(result); |
1142 | 1130 |
1143 fCurrClipMaskType = kAlpha_ClipMaskType; | 1131 fCurrClipMaskType = kAlpha_ClipMaskType; |
1144 return result; | 1132 return result; |
1145 } | 1133 } |
1146 | 1134 |
1147 //////////////////////////////////////////////////////////////////////////////// | 1135 //////////////////////////////////////////////////////////////////////////////// |
1148 void GrClipMaskManager::purgeResources() { | |
1149 fAACache.purgeResources(); | |
1150 } | |
1151 | 1136 |
1152 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc
ilAttachment, | 1137 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc
ilAttachment, |
1153 GrStencilSettings* settings) { | 1138 GrStencilSettings* settings) { |
1154 if (stencilAttachment) { | 1139 if (stencilAttachment) { |
1155 int stencilBits = stencilAttachment->bits(); | 1140 int stencilBits = stencilAttachment->bits(); |
1156 this->adjustStencilParams(settings, fClipMode, stencilBits); | 1141 this->adjustStencilParams(settings, fClipMode, stencilBits); |
1157 } | 1142 } |
1158 } | 1143 } |
OLD | NEW |