Chromium Code Reviews| 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 |