| 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 |