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.fConfig = kAlpha_8_GrPixelConfig; | |
527 desc.fWidth = width; | |
528 desc.fHeight = height; | |
529 desc.fFlags = renderTarget ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFl ags; | |
robertphillips
2015/09/30 12:33:05
Since we set fConfig to A8 by default, reverse the
bsalomon
2015/09/30 19:59:39
Removed the default setting (meant to do that the
| |
530 if (!renderTarget || fDrawTarget->caps()->isConfigRenderable(kAlpha_8_GrPixe lConfig, false)) { | |
531 desc.fConfig = kAlpha_8_GrPixelConfig; | |
532 } else { | |
533 desc.fConfig = kRGBA_8888_GrPixelConfig; | |
534 } | |
535 | |
536 GrTexture* texture = fDrawTarget->cmmAccess().resourceProvider()->createAppr oxTexture(desc, 0); | |
537 if (!texture) { | |
538 return nullptr; | |
539 } | |
540 texture->resourcePriv().setUniqueKey(key); | |
541 return texture; | |
542 } | |
543 | |
557 GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, | 544 GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, |
558 GrReducedClip::InitialState in itialState, | 545 GrReducedClip::InitialState in itialState, |
559 const GrReducedClip::ElementLi st& elements, | 546 const GrReducedClip::ElementLi st& elements, |
560 const SkVector& clipToMaskOffs et, | 547 const SkVector& clipToMaskOffs et, |
561 const SkIRect& clipSpaceIBound s) { | 548 const SkIRect& clipSpaceIBound s) { |
562 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); | 549 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); |
563 | 550 GrResourceProvider* resourceProvider = fDrawTarget->cmmAccess().resourceProv ider(); |
564 // First, check for cached texture | 551 GrUniqueKey key; |
565 GrTexture* result = this->getCachedMaskTexture(elementsGenID, clipSpaceIBoun ds); | 552 GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key); |
566 if (result) { | 553 if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key) ) { |
567 fCurrClipMaskType = kAlpha_ClipMaskType; | 554 fCurrClipMaskType = kAlpha_ClipMaskType; |
568 return result; | 555 return texture; |
569 } | 556 } |
570 | 557 |
558 SkAutoTUnref<GrTexture> texture(this->createCachedMask( | |
559 clipSpaceIBounds.width(), clipSpaceIBounds.height(), key, true)); | |
560 | |
571 // There's no texture in the cache. Let's try to allocate it then. | 561 // There's no texture in the cache. Let's try to allocate it then. |
572 result = this->allocMaskTexture(elementsGenID, clipSpaceIBounds, false); | 562 if (!texture) { |
573 if (nullptr == result) { | |
574 fAACache.reset(); | |
575 return nullptr; | 563 return nullptr; |
576 } | 564 } |
577 | 565 |
578 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip | 566 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip |
579 // space. | 567 // space. |
580 SkMatrix translate; | 568 SkMatrix translate; |
581 translate.setTranslate(clipToMaskOffset); | 569 translate.setTranslate(clipToMaskOffset); |
582 | 570 |
583 // The texture may be larger than necessary, this rect represents the part o f the texture | 571 // 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. | 572 // we populate with a rasterization of the clip. |
585 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa ceIBounds.height()); | 573 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa ceIBounds.height()); |
586 | 574 |
587 // The scratch texture that we are drawing into can be substantially larger than the mask. Only | 575 // The scratch texture that we are drawing into can be substantially larger than the mask. Only |
588 // clear the part that we care about. | 576 // clear the part that we care about. |
589 fDrawTarget->clear(&maskSpaceIBounds, | 577 fDrawTarget->clear(&maskSpaceIBounds, |
590 GrReducedClip::kAllIn_InitialState == initialState ? 0xff ffffff : 0x00000000, | 578 GrReducedClip::kAllIn_InitialState == initialState ? 0xff ffffff : 0x00000000, |
591 true, | 579 true, |
592 result->asRenderTarget()); | 580 texture->asRenderTarget()); |
593 | 581 |
594 // When we use the stencil in the below loop it is important to have this cl ip installed. | 582 // 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 | 583 // 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 | 584 // pass must not set values outside of this bounds or stencil values outside the rect won't be |
597 // cleared. | 585 // cleared. |
598 GrClip clip(maskSpaceIBounds); | 586 GrClip clip(maskSpaceIBounds); |
599 SkAutoTUnref<GrTexture> temp; | 587 SkAutoTUnref<GrTexture> temp; |
600 | 588 |
601 // walk through each clip element and perform its set op | 589 // walk through each clip element and perform its set op |
602 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get() ; iter.next()) { | 590 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get() ; iter.next()) { |
603 const Element* element = iter.get(); | 591 const Element* element = iter.get(); |
604 SkRegion::Op op = element->getOp(); | 592 SkRegion::Op op = element->getOp(); |
605 bool invert = element->isInverseFilled(); | 593 bool invert = element->isInverseFilled(); |
606 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere nce_Op == op) { | 594 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere nce_Op == op) { |
607 GrPipelineBuilder pipelineBuilder; | 595 GrPipelineBuilder pipelineBuilder; |
608 | 596 |
609 pipelineBuilder.setClip(clip); | 597 pipelineBuilder.setClip(clip); |
610 GrPathRenderer* pr = nullptr; | 598 GrPathRenderer* pr = nullptr; |
611 bool useTemp = !this->canStencilAndDrawElement(&pipelineBuilder, res ult, &pr, element); | 599 bool useTemp = !this->canStencilAndDrawElement(&pipelineBuilder, tex ture, &pr, element); |
612 GrTexture* dst; | 600 GrTexture* dst; |
613 // This is the bounds of the clip element in the space of the alpha- mask. The temporary | 601 // 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 | 602 // 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 | 603 // touch the minimum number of pixels necessary and use decal mode t o combine it with |
616 // the accumulator. | 604 // the accumulator. |
617 SkIRect maskSpaceElementIBounds; | 605 SkIRect maskSpaceElementIBounds; |
618 | 606 |
619 if (useTemp) { | 607 if (useTemp) { |
620 if (invert) { | 608 if (invert) { |
621 maskSpaceElementIBounds = maskSpaceIBounds; | 609 maskSpaceElementIBounds = maskSpaceIBounds; |
622 } else { | 610 } else { |
623 SkRect elementBounds = element->getBounds(); | 611 SkRect elementBounds = element->getBounds(); |
624 elementBounds.offset(clipToMaskOffset); | 612 elementBounds.offset(clipToMaskOffset); |
625 elementBounds.roundOut(&maskSpaceElementIBounds); | 613 elementBounds.roundOut(&maskSpaceElementIBounds); |
626 } | 614 } |
627 | 615 |
628 if (!temp) { | 616 if (!temp) { |
629 temp.reset(this->createTempMask(maskSpaceIBounds.fRight, | 617 temp.reset(this->createTempMask(maskSpaceIBounds.fRight, |
630 maskSpaceIBounds.fBottom)); | 618 maskSpaceIBounds.fBottom)); |
631 if (!temp) { | 619 if (!temp) { |
632 fAACache.reset(); | 620 texture->resourcePriv().removeUniqueKey(); |
633 return nullptr; | 621 return nullptr; |
634 } | 622 } |
635 } | 623 } |
636 dst = temp; | 624 dst = temp; |
637 // clear the temp target and set blend to replace | 625 // clear the temp target and set blend to replace |
638 fDrawTarget->clear(&maskSpaceElementIBounds, | 626 fDrawTarget->clear(&maskSpaceElementIBounds, |
639 invert ? 0xffffffff : 0x00000000, | 627 invert ? 0xffffffff : 0x00000000, |
640 true, | 628 true, |
641 dst->asRenderTarget()); | 629 dst->asRenderTarget()); |
642 set_coverage_drawing_xpf(SkRegion::kReplace_Op, invert, &pipelin eBuilder); | 630 set_coverage_drawing_xpf(SkRegion::kReplace_Op, invert, &pipelin eBuilder); |
643 } else { | 631 } else { |
644 // draw directly into the result with the stencil set to make th e pixels affected | 632 // draw directly into the result with the stencil set to make th e pixels affected |
645 // by the clip shape be non-zero. | 633 // by the clip shape be non-zero. |
646 dst = result; | 634 dst = texture; |
647 GR_STATIC_CONST_SAME_STENCIL(kStencilInElement, | 635 GR_STATIC_CONST_SAME_STENCIL(kStencilInElement, |
648 kReplace_StencilOp, | 636 kReplace_StencilOp, |
649 kReplace_StencilOp, | 637 kReplace_StencilOp, |
650 kAlways_StencilFunc, | 638 kAlways_StencilFunc, |
651 0xffff, | 639 0xffff, |
652 0xffff, | 640 0xffff, |
653 0xffff); | 641 0xffff); |
654 pipelineBuilder.setStencil(kStencilInElement); | 642 pipelineBuilder.setStencil(kStencilInElement); |
655 set_coverage_drawing_xpf(op, invert, &pipelineBuilder); | 643 set_coverage_drawing_xpf(op, invert, &pipelineBuilder); |
656 } | 644 } |
657 | 645 |
658 if (!this->drawElement(&pipelineBuilder, translate, dst, element, pr )) { | 646 if (!this->drawElement(&pipelineBuilder, translate, dst, element, pr )) { |
659 fAACache.reset(); | 647 texture->resourcePriv().removeUniqueKey(); |
660 return nullptr; | 648 return nullptr; |
661 } | 649 } |
662 | 650 |
663 if (useTemp) { | 651 if (useTemp) { |
664 GrPipelineBuilder backgroundPipelineBuilder; | 652 GrPipelineBuilder backgroundPipelineBuilder; |
665 backgroundPipelineBuilder.setRenderTarget(result->asRenderTarget ()); | 653 backgroundPipelineBuilder.setRenderTarget(texture->asRenderTarge t()); |
666 | 654 |
667 // Now draw into the accumulator using the real operation and th e temp buffer as a | 655 // Now draw into the accumulator using the real operation and th e temp buffer as a |
668 // texture | 656 // texture |
669 this->mergeMask(&backgroundPipelineBuilder, | 657 this->mergeMask(&backgroundPipelineBuilder, |
670 result, | 658 texture, |
671 temp, | 659 temp, |
672 op, | 660 op, |
673 maskSpaceIBounds, | 661 maskSpaceIBounds, |
674 maskSpaceElementIBounds); | 662 maskSpaceElementIBounds); |
675 } else { | 663 } else { |
676 GrPipelineBuilder backgroundPipelineBuilder; | 664 GrPipelineBuilder backgroundPipelineBuilder; |
677 backgroundPipelineBuilder.setRenderTarget(result->asRenderTarget ()); | 665 backgroundPipelineBuilder.setRenderTarget(texture->asRenderTarge t()); |
678 | 666 |
679 set_coverage_drawing_xpf(op, !invert, &backgroundPipelineBuilder ); | 667 set_coverage_drawing_xpf(op, !invert, &backgroundPipelineBuilder ); |
680 // Draw to the exterior pixels (those with a zero stencil value) . | 668 // Draw to the exterior pixels (those with a zero stencil value) . |
681 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, | 669 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, |
682 kZero_StencilOp, | 670 kZero_StencilOp, |
683 kZero_StencilOp, | 671 kZero_StencilOp, |
684 kEqual_StencilFunc, | 672 kEqual_StencilFunc, |
685 0xffff, | 673 0xffff, |
686 0x0000, | 674 0x0000, |
687 0xffff); | 675 0xffff); |
688 backgroundPipelineBuilder.setStencil(kDrawOutsideElement); | 676 backgroundPipelineBuilder.setStencil(kDrawOutsideElement); |
689 | 677 |
690 // The color passed in here does not matter since the coverageSe tOpXP won't read it. | 678 // The color passed in here does not matter since the coverageSe tOpXP won't read it. |
691 fDrawTarget->drawNonAARect(backgroundPipelineBuilder, GrColor_WH ITE, translate, | 679 fDrawTarget->drawNonAARect(backgroundPipelineBuilder, GrColor_WH ITE, translate, |
692 clipSpaceIBounds); | 680 clipSpaceIBounds); |
693 } | 681 } |
694 } else { | 682 } else { |
695 GrPipelineBuilder pipelineBuilder; | 683 GrPipelineBuilder pipelineBuilder; |
696 | 684 |
697 // all the remaining ops can just be directly draw into the accumula tion buffer | 685 // all the remaining ops can just be directly draw into the accumula tion buffer |
698 set_coverage_drawing_xpf(op, false, &pipelineBuilder); | 686 set_coverage_drawing_xpf(op, false, &pipelineBuilder); |
699 // The color passed in here does not matter since the coverageSetOpX P won't read it. | 687 // The color passed in here does not matter since the coverageSetOpX P won't read it. |
700 this->drawElement(&pipelineBuilder, translate, result, element); | 688 this->drawElement(&pipelineBuilder, translate, texture, element); |
701 } | 689 } |
702 } | 690 } |
703 | 691 |
704 fCurrClipMaskType = kAlpha_ClipMaskType; | 692 fCurrClipMaskType = kAlpha_ClipMaskType; |
705 return result; | 693 return texture.detach(); |
706 } | 694 } |
707 | 695 |
708 //////////////////////////////////////////////////////////////////////////////// | 696 //////////////////////////////////////////////////////////////////////////////// |
709 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device | 697 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device |
710 // (as opposed to canvas) coordinates | 698 // (as opposed to canvas) coordinates |
711 bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt, | 699 bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt, |
712 int32_t elementsGenID, | 700 int32_t elementsGenID, |
713 GrReducedClip::InitialState initia lState, | 701 GrReducedClip::InitialState initia lState, |
714 const GrReducedClip::ElementList& elements, | 702 const GrReducedClip::ElementList& elements, |
715 const SkIRect& clipSpaceIBounds, | 703 const SkIRect& clipSpaceIBounds, |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1072 } | 1060 } |
1073 } | 1061 } |
1074 | 1062 |
1075 //////////////////////////////////////////////////////////////////////////////// | 1063 //////////////////////////////////////////////////////////////////////////////// |
1076 GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID, | 1064 GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID, |
1077 GrReducedClip::InitialState initialState, | 1065 GrReducedClip::InitialState initialState, |
1078 const GrReducedClip::Elemen tList& elements, | 1066 const GrReducedClip::Elemen tList& elements, |
1079 const SkVector& clipToMaskO ffset, | 1067 const SkVector& clipToMaskO ffset, |
1080 const SkIRect& clipSpaceIBo unds) { | 1068 const SkIRect& clipSpaceIBo unds) { |
1081 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); | 1069 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); |
1082 | 1070 GrUniqueKey key; |
1083 GrTexture* result = this->getCachedMaskTexture(elementsGenID, clipSpaceIBoun ds); | 1071 GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key); |
1084 if (result) { | 1072 GrResourceProvider* resourceProvider = fDrawTarget->cmmAccess().resourceProv ider(); |
1085 return result; | 1073 if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key) ) { |
1074 return texture; | |
1086 } | 1075 } |
1087 | 1076 |
1088 // The mask texture may be larger than necessary. We round out the clip spac e bounds and pin | 1077 // 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. | 1078 // 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()); | 1079 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa ceIBounds.height()); |
1091 | 1080 |
1092 GrSWMaskHelper helper(this->getContext()); | 1081 GrSWMaskHelper helper(this->getContext()); |
1093 | 1082 |
1094 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip | 1083 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip |
1095 // space. | 1084 // space. |
(...skipping 30 matching lines...) Expand all Loading... | |
1126 if (Element::kRect_Type == element->getType()) { | 1115 if (Element::kRect_Type == element->getType()) { |
1127 helper.draw(element->getRect(), op, element->isAA(), 0xFF); | 1116 helper.draw(element->getRect(), op, element->isAA(), 0xFF); |
1128 } else { | 1117 } else { |
1129 SkPath path; | 1118 SkPath path; |
1130 element->asPath(&path); | 1119 element->asPath(&path); |
1131 helper.draw(path, stroke, op, element->isAA(), 0xFF); | 1120 helper.draw(path, stroke, op, element->isAA(), 0xFF); |
1132 } | 1121 } |
1133 } | 1122 } |
1134 | 1123 |
1135 // Allocate clip mask texture | 1124 // Allocate clip mask texture |
1136 result = this->allocMaskTexture(elementsGenID, clipSpaceIBounds, true); | 1125 GrTexture* result = this->createCachedMask(clipSpaceIBounds.width(), clipSpa ceIBounds.height(), |
1126 key, false); | |
1137 if (nullptr == result) { | 1127 if (nullptr == result) { |
1138 fAACache.reset(); | |
1139 return nullptr; | 1128 return nullptr; |
1140 } | 1129 } |
1141 helper.toTexture(result); | 1130 helper.toTexture(result); |
1142 | 1131 |
1143 fCurrClipMaskType = kAlpha_ClipMaskType; | 1132 fCurrClipMaskType = kAlpha_ClipMaskType; |
1144 return result; | 1133 return result; |
1145 } | 1134 } |
1146 | 1135 |
1147 //////////////////////////////////////////////////////////////////////////////// | 1136 //////////////////////////////////////////////////////////////////////////////// |
1148 void GrClipMaskManager::purgeResources() { | |
1149 fAACache.purgeResources(); | |
1150 } | |
1151 | 1137 |
1152 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc ilAttachment, | 1138 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc ilAttachment, |
1153 GrStencilSettings* settings) { | 1139 GrStencilSettings* settings) { |
1154 if (stencilAttachment) { | 1140 if (stencilAttachment) { |
1155 int stencilBits = stencilAttachment->bits(); | 1141 int stencilBits = stencilAttachment->bits(); |
1156 this->adjustStencilParams(settings, fClipMode, stencilBits); | 1142 this->adjustStencilParams(settings, fClipMode, stencilBits); |
1157 } | 1143 } |
1158 } | 1144 } |
OLD | NEW |