| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2012 Google Inc. | 3 * Copyright 2012 Google Inc. |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 #include "GrClipMaskManager.h" | 9 #include "GrClipMaskManager.h" |
| 10 #include "GrAAConvexPathRenderer.h" | 10 #include "GrAAConvexPathRenderer.h" |
| (...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 478 | 478 |
| 479 drawState->addColorProcessor( | 479 drawState->addColorProcessor( |
| 480 GrTextureDomainEffect::Create(srcMask, | 480 GrTextureDomainEffect::Create(srcMask, |
| 481 sampleM, | 481 sampleM, |
| 482 GrTextureDomain::MakeTexelDomain(srcMask,
srcBound), | 482 GrTextureDomain::MakeTexelDomain(srcMask,
srcBound), |
| 483 GrTextureDomain::kDecal_Mode, | 483 GrTextureDomain::kDecal_Mode, |
| 484 GrTextureParams::kNone_FilterMode))->unref
(); | 484 GrTextureParams::kNone_FilterMode))->unref
(); |
| 485 fGpu->drawSimpleRect(SkRect::Make(dstBound)); | 485 fGpu->drawSimpleRect(SkRect::Make(dstBound)); |
| 486 } | 486 } |
| 487 | 487 |
| 488 // get a texture to act as a temporary buffer for AA clip boolean operations | 488 GrTexture* GrClipMaskManager::createTempMask(int width, int height) { |
| 489 // TODO: given the expense of createTexture we may want to just cache this too | |
| 490 void GrClipMaskManager::getTemp(int width, int height, GrAutoScratchTexture* tem
p) { | |
| 491 if (temp->texture()) { | |
| 492 // we've already allocated the temp texture | |
| 493 return; | |
| 494 } | |
| 495 | |
| 496 GrTextureDesc desc; | 489 GrTextureDesc desc; |
| 497 desc.fFlags = kRenderTarget_GrTextureFlagBit|kNoStencil_GrTextureFlagBit; | 490 desc.fFlags = kRenderTarget_GrTextureFlagBit|kNoStencil_GrTextureFlagBit; |
| 498 desc.fWidth = width; | 491 desc.fWidth = width; |
| 499 desc.fHeight = height; | 492 desc.fHeight = height; |
| 500 desc.fConfig = kAlpha_8_GrPixelConfig; | 493 desc.fConfig = kAlpha_8_GrPixelConfig; |
| 501 | 494 |
| 502 temp->set(this->getContext(), desc); | 495 return fGpu->getContext()->refScratchTexture(desc, GrContext::kApprox_Scratc
hTexMatch); |
| 503 } | 496 } |
| 504 | 497 |
| 505 //////////////////////////////////////////////////////////////////////////////// | 498 //////////////////////////////////////////////////////////////////////////////// |
| 506 // Return the texture currently in the cache if it exists. Otherwise, return NUL
L | 499 // Return the texture currently in the cache if it exists. Otherwise, return NUL
L |
| 507 GrTexture* GrClipMaskManager::getCachedMaskTexture(int32_t elementsGenID, | 500 GrTexture* GrClipMaskManager::getCachedMaskTexture(int32_t elementsGenID, |
| 508 const SkIRect& clipSpaceIBoun
ds) { | 501 const SkIRect& clipSpaceIBoun
ds) { |
| 509 bool cached = fAACache.canReuse(elementsGenID, clipSpaceIBounds); | 502 bool cached = fAACache.canReuse(elementsGenID, clipSpaceIBounds); |
| 510 if (!cached) { | 503 if (!cached) { |
| 511 return NULL; | 504 return NULL; |
| 512 } | 505 } |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 586 true, | 579 true, |
| 587 result->asRenderTarget()); | 580 result->asRenderTarget()); |
| 588 | 581 |
| 589 // 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. |
| 590 // 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 |
| 591 // 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 |
| 592 // cleared. | 585 // cleared. |
| 593 GrDrawTarget::AutoClipRestore acr(fGpu, maskSpaceIBounds); | 586 GrDrawTarget::AutoClipRestore acr(fGpu, maskSpaceIBounds); |
| 594 drawState->enableState(GrDrawState::kClip_StateBit); | 587 drawState->enableState(GrDrawState::kClip_StateBit); |
| 595 | 588 |
| 596 GrAutoScratchTexture temp; | 589 SkAutoTUnref<GrTexture> temp; |
| 597 // walk through each clip element and perform its set op | 590 // walk through each clip element and perform its set op |
| 598 for (ElementList::Iter iter = elements.headIter(); iter.get(); iter.next())
{ | 591 for (ElementList::Iter iter = elements.headIter(); iter.get(); iter.next())
{ |
| 599 const Element* element = iter.get(); | 592 const Element* element = iter.get(); |
| 600 SkRegion::Op op = element->getOp(); | 593 SkRegion::Op op = element->getOp(); |
| 601 bool invert = element->isInverseFilled(); | 594 bool invert = element->isInverseFilled(); |
| 602 | 595 |
| 603 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere
nce_Op == op) { | 596 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere
nce_Op == op) { |
| 604 GrPathRenderer* pr = NULL; | 597 GrPathRenderer* pr = NULL; |
| 605 bool useTemp = !this->canStencilAndDrawElement(result, element, &pr)
; | 598 bool useTemp = !this->canStencilAndDrawElement(result, element, &pr)
; |
| 606 GrTexture* dst; | 599 GrTexture* dst; |
| 607 // 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 |
| 608 // 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 |
| 609 // 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 |
| 610 // the accumulator. | 603 // the accumulator. |
| 611 SkIRect maskSpaceElementIBounds; | 604 SkIRect maskSpaceElementIBounds; |
| 612 | 605 |
| 613 if (useTemp) { | 606 if (useTemp) { |
| 614 if (invert) { | 607 if (invert) { |
| 615 maskSpaceElementIBounds = maskSpaceIBounds; | 608 maskSpaceElementIBounds = maskSpaceIBounds; |
| 616 } else { | 609 } else { |
| 617 SkRect elementBounds = element->getBounds(); | 610 SkRect elementBounds = element->getBounds(); |
| 618 elementBounds.offset(clipToMaskOffset); | 611 elementBounds.offset(clipToMaskOffset); |
| 619 elementBounds.roundOut(&maskSpaceElementIBounds); | 612 elementBounds.roundOut(&maskSpaceElementIBounds); |
| 620 } | 613 } |
| 621 | 614 |
| 622 this->getTemp(maskSpaceIBounds.fRight, maskSpaceIBounds.fBottom,
&temp); | 615 if (!temp) { |
| 623 if (NULL == temp.texture()) { | 616 temp.reset(this->createTempMask(maskSpaceIBounds.fRight, |
| 624 fAACache.reset(); | 617 maskSpaceIBounds.fBottom)); |
| 625 return NULL; | 618 if (!temp) { |
| 619 fAACache.reset(); |
| 620 return NULL; |
| 621 } |
| 626 } | 622 } |
| 627 dst = temp.texture(); | 623 dst = temp; |
| 628 // clear the temp target and set blend to replace | 624 // clear the temp target and set blend to replace |
| 629 fGpu->clear(&maskSpaceElementIBounds, | 625 fGpu->clear(&maskSpaceElementIBounds, |
| 630 invert ? 0xffffffff : 0x00000000, | 626 invert ? 0xffffffff : 0x00000000, |
| 631 true, | 627 true, |
| 632 dst->asRenderTarget()); | 628 dst->asRenderTarget()); |
| 633 setup_boolean_blendcoeffs(drawState, SkRegion::kReplace_Op); | 629 setup_boolean_blendcoeffs(drawState, SkRegion::kReplace_Op); |
| 634 | 630 |
| 635 } else { | 631 } else { |
| 636 // 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 |
| 637 // by the clip shape be non-zero. | 633 // by the clip shape be non-zero. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 651 | 647 |
| 652 if (!this->drawElement(dst, element, pr)) { | 648 if (!this->drawElement(dst, element, pr)) { |
| 653 fAACache.reset(); | 649 fAACache.reset(); |
| 654 return NULL; | 650 return NULL; |
| 655 } | 651 } |
| 656 | 652 |
| 657 if (useTemp) { | 653 if (useTemp) { |
| 658 // 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 |
| 659 // texture | 655 // texture |
| 660 this->mergeMask(result, | 656 this->mergeMask(result, |
| 661 temp.texture(), | 657 temp, |
| 662 op, | 658 op, |
| 663 maskSpaceIBounds, | 659 maskSpaceIBounds, |
| 664 maskSpaceElementIBounds); | 660 maskSpaceElementIBounds); |
| 665 } else { | 661 } else { |
| 666 // Draw to the exterior pixels (those with a zero stencil value)
. | 662 // Draw to the exterior pixels (those with a zero stencil value)
. |
| 667 drawState->setAlpha(invert ? 0xff : 0x00); | 663 drawState->setAlpha(invert ? 0xff : 0x00); |
| 668 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, | 664 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, |
| 669 kZero_StencilOp, | 665 kZero_StencilOp, |
| 670 kZero_StencilOp, | 666 kZero_StencilOp, |
| 671 kEqual_StencilFunc, | 667 kEqual_StencilFunc, |
| (...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1140 | 1136 |
| 1141 // TODO: dynamically attach a stencil buffer | 1137 // TODO: dynamically attach a stencil buffer |
| 1142 int stencilBits = 0; | 1138 int stencilBits = 0; |
| 1143 GrStencilBuffer* stencilBuffer = | 1139 GrStencilBuffer* stencilBuffer = |
| 1144 drawState.getRenderTarget()->getStencilBuffer(); | 1140 drawState.getRenderTarget()->getStencilBuffer(); |
| 1145 if (stencilBuffer) { | 1141 if (stencilBuffer) { |
| 1146 stencilBits = stencilBuffer->bits(); | 1142 stencilBits = stencilBuffer->bits(); |
| 1147 this->adjustStencilParams(settings, clipMode, stencilBits); | 1143 this->adjustStencilParams(settings, clipMode, stencilBits); |
| 1148 } | 1144 } |
| 1149 } | 1145 } |
| OLD | NEW |