| 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 17 matching lines...) Expand all Loading... |
| 28 using namespace GrReducedClip; | 28 using namespace GrReducedClip; |
| 29 | 29 |
| 30 //////////////////////////////////////////////////////////////////////////////// | 30 //////////////////////////////////////////////////////////////////////////////// |
| 31 namespace { | 31 namespace { |
| 32 // set up the draw state to enable the aa clipping mask. Besides setting up the | 32 // set up the draw state to enable the aa clipping mask. Besides setting up the |
| 33 // stage matrix this also alters the vertex layout | 33 // stage matrix this also alters the vertex layout |
| 34 void setup_drawstate_aaclip(GrGpu* gpu, | 34 void setup_drawstate_aaclip(GrGpu* gpu, |
| 35 GrTexture* result, | 35 GrTexture* result, |
| 36 const SkIRect &devBound) { | 36 const SkIRect &devBound) { |
| 37 GrDrawState* drawState = gpu->drawState(); | 37 GrDrawState* drawState = gpu->drawState(); |
| 38 GrAssert(drawState); | 38 SkASSERT(drawState); |
| 39 | 39 |
| 40 SkMatrix mat; | 40 SkMatrix mat; |
| 41 // We want to use device coords to compute the texture coordinates. We set o
ur matrix to be | 41 // We want to use device coords to compute the texture coordinates. We set o
ur matrix to be |
| 42 // equal to the view matrix followed by an offset to the devBound, and then
a scaling matrix to | 42 // equal to the view matrix followed by an offset to the devBound, and then
a scaling matrix to |
| 43 // normalized coords. We apply this matrix to the vertex positions rather th
an local coords. | 43 // normalized coords. We apply this matrix to the vertex positions rather th
an local coords. |
| 44 mat.setIDiv(result->width(), result->height()); | 44 mat.setIDiv(result->width(), result->height()); |
| 45 mat.preTranslate(SkIntToScalar(-devBound.fLeft), | 45 mat.preTranslate(SkIntToScalar(-devBound.fLeft), |
| 46 SkIntToScalar(-devBound.fTop)); | 46 SkIntToScalar(-devBound.fTop)); |
| 47 mat.preConcat(drawState->getViewMatrix()); | 47 mat.preConcat(drawState->getViewMatrix()); |
| 48 | 48 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 ElementList elements(16); | 114 ElementList elements(16); |
| 115 InitialState initialState; | 115 InitialState initialState; |
| 116 SkIRect clipSpaceIBounds; | 116 SkIRect clipSpaceIBounds; |
| 117 bool requiresAA; | 117 bool requiresAA; |
| 118 bool isRect = false; | 118 bool isRect = false; |
| 119 | 119 |
| 120 GrDrawState* drawState = fGpu->drawState(); | 120 GrDrawState* drawState = fGpu->drawState(); |
| 121 | 121 |
| 122 const GrRenderTarget* rt = drawState->getRenderTarget(); | 122 const GrRenderTarget* rt = drawState->getRenderTarget(); |
| 123 // GrDrawTarget should have filtered this for us | 123 // GrDrawTarget should have filtered this for us |
| 124 GrAssert(NULL != rt); | 124 SkASSERT(NULL != rt); |
| 125 | 125 |
| 126 bool ignoreClip = !drawState->isClipState() || clipDataIn->fClipStack->isWid
eOpen(); | 126 bool ignoreClip = !drawState->isClipState() || clipDataIn->fClipStack->isWid
eOpen(); |
| 127 | 127 |
| 128 if (!ignoreClip) { | 128 if (!ignoreClip) { |
| 129 SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height()); | 129 SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height()); |
| 130 clipSpaceRTIBounds.offset(clipDataIn->fOrigin); | 130 clipSpaceRTIBounds.offset(clipDataIn->fOrigin); |
| 131 ReduceClipStack(*clipDataIn->fClipStack, | 131 ReduceClipStack(*clipDataIn->fClipStack, |
| 132 clipSpaceRTIBounds, | 132 clipSpaceRTIBounds, |
| 133 &elements, | 133 &elements, |
| 134 &initialState, | 134 &initialState, |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 251 case SkRegion::kXOR_Op: | 251 case SkRegion::kXOR_Op: |
| 252 drawState->setBlendFunc(kIDC_GrBlendCoeff, kISC_GrBlendCoeff); | 252 drawState->setBlendFunc(kIDC_GrBlendCoeff, kISC_GrBlendCoeff); |
| 253 break; | 253 break; |
| 254 case SkRegion::kDifference_Op: | 254 case SkRegion::kDifference_Op: |
| 255 drawState->setBlendFunc(kZero_GrBlendCoeff, kISC_GrBlendCoeff); | 255 drawState->setBlendFunc(kZero_GrBlendCoeff, kISC_GrBlendCoeff); |
| 256 break; | 256 break; |
| 257 case SkRegion::kReverseDifference_Op: | 257 case SkRegion::kReverseDifference_Op: |
| 258 drawState->setBlendFunc(kIDC_GrBlendCoeff, kZero_GrBlendCoeff); | 258 drawState->setBlendFunc(kIDC_GrBlendCoeff, kZero_GrBlendCoeff); |
| 259 break; | 259 break; |
| 260 default: | 260 default: |
| 261 GrAssert(false); | 261 SkASSERT(false); |
| 262 break; | 262 break; |
| 263 } | 263 } |
| 264 } | 264 } |
| 265 | 265 |
| 266 } | 266 } |
| 267 | 267 |
| 268 //////////////////////////////////////////////////////////////////////////////// | 268 //////////////////////////////////////////////////////////////////////////////// |
| 269 bool GrClipMaskManager::drawElement(GrTexture* target, | 269 bool GrClipMaskManager::drawElement(GrTexture* target, |
| 270 const SkClipStack::Element* element, | 270 const SkClipStack::Element* element, |
| 271 GrPathRenderer* pr) { | 271 GrPathRenderer* pr) { |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 *result = fAACache.getLastMask(); | 416 *result = fAACache.getLastMask(); |
| 417 return cached; | 417 return cached; |
| 418 } | 418 } |
| 419 | 419 |
| 420 //////////////////////////////////////////////////////////////////////////////// | 420 //////////////////////////////////////////////////////////////////////////////// |
| 421 // Create a 8-bit clip mask in alpha | 421 // Create a 8-bit clip mask in alpha |
| 422 GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t clipStackGenID, | 422 GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t clipStackGenID, |
| 423 InitialState initialState, | 423 InitialState initialState, |
| 424 const ElementList& elements, | 424 const ElementList& elements, |
| 425 const SkIRect& clipSpaceIBound
s) { | 425 const SkIRect& clipSpaceIBound
s) { |
| 426 GrAssert(kNone_ClipMaskType == fCurrClipMaskType); | 426 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); |
| 427 | 427 |
| 428 GrTexture* result; | 428 GrTexture* result; |
| 429 if (this->getMaskTexture(clipStackGenID, clipSpaceIBounds, &result)) { | 429 if (this->getMaskTexture(clipStackGenID, clipSpaceIBounds, &result)) { |
| 430 fCurrClipMaskType = kAlpha_ClipMaskType; | 430 fCurrClipMaskType = kAlpha_ClipMaskType; |
| 431 return result; | 431 return result; |
| 432 } | 432 } |
| 433 | 433 |
| 434 if (NULL == result) { | 434 if (NULL == result) { |
| 435 fAACache.reset(); | 435 fAACache.reset(); |
| 436 return NULL; | 436 return NULL; |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 563 } | 563 } |
| 564 | 564 |
| 565 //////////////////////////////////////////////////////////////////////////////// | 565 //////////////////////////////////////////////////////////////////////////////// |
| 566 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device | 566 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device |
| 567 // (as opposed to canvas) coordinates | 567 // (as opposed to canvas) coordinates |
| 568 bool GrClipMaskManager::createStencilClipMask(InitialState initialState, | 568 bool GrClipMaskManager::createStencilClipMask(InitialState initialState, |
| 569 const ElementList& elements, | 569 const ElementList& elements, |
| 570 const SkIRect& clipSpaceIBounds, | 570 const SkIRect& clipSpaceIBounds, |
| 571 const SkIPoint& clipSpaceToStencil
Offset) { | 571 const SkIPoint& clipSpaceToStencil
Offset) { |
| 572 | 572 |
| 573 GrAssert(kNone_ClipMaskType == fCurrClipMaskType); | 573 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); |
| 574 | 574 |
| 575 GrDrawState* drawState = fGpu->drawState(); | 575 GrDrawState* drawState = fGpu->drawState(); |
| 576 GrAssert(drawState->isClipState()); | 576 SkASSERT(drawState->isClipState()); |
| 577 | 577 |
| 578 GrRenderTarget* rt = drawState->getRenderTarget(); | 578 GrRenderTarget* rt = drawState->getRenderTarget(); |
| 579 GrAssert(NULL != rt); | 579 SkASSERT(NULL != rt); |
| 580 | 580 |
| 581 // TODO: dynamically attach a SB when needed. | 581 // TODO: dynamically attach a SB when needed. |
| 582 GrStencilBuffer* stencilBuffer = rt->getStencilBuffer(); | 582 GrStencilBuffer* stencilBuffer = rt->getStencilBuffer(); |
| 583 if (NULL == stencilBuffer) { | 583 if (NULL == stencilBuffer) { |
| 584 return false; | 584 return false; |
| 585 } | 585 } |
| 586 int32_t genID = elements.tail()->getGenID(); | 586 int32_t genID = elements.tail()->getGenID(); |
| 587 | 587 |
| 588 if (stencilBuffer->mustRenderClip(genID, clipSpaceIBounds, clipSpaceToStenci
lOffset)) { | 588 if (stencilBuffer->mustRenderClip(genID, clipSpaceIBounds, clipSpaceToStenci
lOffset)) { |
| 589 | 589 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); | 636 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); |
| 637 | 637 |
| 638 SkRegion::Op op = element->getOp(); | 638 SkRegion::Op op = element->getOp(); |
| 639 | 639 |
| 640 GrPathRenderer* pr = NULL; | 640 GrPathRenderer* pr = NULL; |
| 641 SkTCopyOnFirstWrite<SkPath> clipPath; | 641 SkTCopyOnFirstWrite<SkPath> clipPath; |
| 642 if (Element::kRect_Type == element->getType()) { | 642 if (Element::kRect_Type == element->getType()) { |
| 643 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; | 643 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; |
| 644 fillInverted = false; | 644 fillInverted = false; |
| 645 } else { | 645 } else { |
| 646 GrAssert(Element::kPath_Type == element->getType()); | 646 SkASSERT(Element::kPath_Type == element->getType()); |
| 647 clipPath.init(element->getPath()); | 647 clipPath.init(element->getPath()); |
| 648 fillInverted = clipPath->isInverseFillType(); | 648 fillInverted = clipPath->isInverseFillType(); |
| 649 if (fillInverted) { | 649 if (fillInverted) { |
| 650 clipPath.writable()->toggleInverseFillType(); | 650 clipPath.writable()->toggleInverseFillType(); |
| 651 } | 651 } |
| 652 pr = this->getContext()->getPathRenderer(*clipPath, | 652 pr = this->getContext()->getPathRenderer(*clipPath, |
| 653 stroke, | 653 stroke, |
| 654 fGpu, | 654 fGpu, |
| 655 false, | 655 false, |
| 656 GrPathRendererChain::kS
tencilOnly_DrawType, | 656 GrPathRendererChain::kS
tencilOnly_DrawType, |
| (...skipping 26 matching lines...) Expand all Loading... |
| 683 kIncClamp_StencilOp, | 683 kIncClamp_StencilOp, |
| 684 kAlways_StencilFunc, | 684 kAlways_StencilFunc, |
| 685 0xffff, | 685 0xffff, |
| 686 0x0000, | 686 0x0000, |
| 687 0xffff); | 687 0xffff); |
| 688 SET_RANDOM_COLOR | 688 SET_RANDOM_COLOR |
| 689 if (Element::kRect_Type == element->getType()) { | 689 if (Element::kRect_Type == element->getType()) { |
| 690 *drawState->stencil() = gDrawToStencil; | 690 *drawState->stencil() = gDrawToStencil; |
| 691 fGpu->drawSimpleRect(element->getRect(), NULL); | 691 fGpu->drawSimpleRect(element->getRect(), NULL); |
| 692 } else { | 692 } else { |
| 693 GrAssert(Element::kPath_Type == element->getType()); | 693 SkASSERT(Element::kPath_Type == element->getType()); |
| 694 if (!clipPath->isEmpty()) { | 694 if (!clipPath->isEmpty()) { |
| 695 if (canRenderDirectToStencil) { | 695 if (canRenderDirectToStencil) { |
| 696 *drawState->stencil() = gDrawToStencil; | 696 *drawState->stencil() = gDrawToStencil; |
| 697 pr->drawPath(*clipPath, stroke, fGpu, false); | 697 pr->drawPath(*clipPath, stroke, fGpu, false); |
| 698 } else { | 698 } else { |
| 699 pr->stencilPath(*clipPath, stroke, fGpu); | 699 pr->stencilPath(*clipPath, stroke, fGpu); |
| 700 } | 700 } |
| 701 } | 701 } |
| 702 } | 702 } |
| 703 } | 703 } |
| 704 | 704 |
| 705 // now we modify the clip bit by rendering either the clip | 705 // now we modify the clip bit by rendering either the clip |
| 706 // element directly or a bounding rect of the entire clip. | 706 // element directly or a bounding rect of the entire clip. |
| 707 drawState->enableState(GrGpu::kModifyStencilClip_StateBit); | 707 drawState->enableState(GrGpu::kModifyStencilClip_StateBit); |
| 708 for (int p = 0; p < passes; ++p) { | 708 for (int p = 0; p < passes; ++p) { |
| 709 *drawState->stencil() = stencilSettings[p]; | 709 *drawState->stencil() = stencilSettings[p]; |
| 710 if (canDrawDirectToClip) { | 710 if (canDrawDirectToClip) { |
| 711 if (Element::kRect_Type == element->getType()) { | 711 if (Element::kRect_Type == element->getType()) { |
| 712 SET_RANDOM_COLOR | 712 SET_RANDOM_COLOR |
| 713 fGpu->drawSimpleRect(element->getRect(), NULL); | 713 fGpu->drawSimpleRect(element->getRect(), NULL); |
| 714 } else { | 714 } else { |
| 715 GrAssert(Element::kPath_Type == element->getType()); | 715 SkASSERT(Element::kPath_Type == element->getType()); |
| 716 SET_RANDOM_COLOR | 716 SET_RANDOM_COLOR |
| 717 pr->drawPath(*clipPath, stroke, fGpu, false); | 717 pr->drawPath(*clipPath, stroke, fGpu, false); |
| 718 } | 718 } |
| 719 } else { | 719 } else { |
| 720 SET_RANDOM_COLOR | 720 SET_RANDOM_COLOR |
| 721 // The view matrix is setup to do clip space -> stencil spac
e translation, so | 721 // The view matrix is setup to do clip space -> stencil spac
e translation, so |
| 722 // draw rect in clip space. | 722 // draw rect in clip space. |
| 723 fGpu->drawSimpleRect(SkRect::MakeFromIRect(clipSpaceIBounds)
, NULL); | 723 fGpu->drawSimpleRect(SkRect::MakeFromIRect(clipSpaceIBounds)
, NULL); |
| 724 } | 724 } |
| 725 } | 725 } |
| 726 } | 726 } |
| 727 } | 727 } |
| 728 // set this last because recursive draws may overwrite it back to kNone. | 728 // set this last because recursive draws may overwrite it back to kNone. |
| 729 GrAssert(kNone_ClipMaskType == fCurrClipMaskType); | 729 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); |
| 730 fCurrClipMaskType = kStencil_ClipMaskType; | 730 fCurrClipMaskType = kStencil_ClipMaskType; |
| 731 return true; | 731 return true; |
| 732 } | 732 } |
| 733 | 733 |
| 734 | 734 |
| 735 // mapping of clip-respecting stencil funcs to normal stencil funcs | 735 // mapping of clip-respecting stencil funcs to normal stencil funcs |
| 736 // mapping depends on whether stencil-clipping is in effect. | 736 // mapping depends on whether stencil-clipping is in effect. |
| 737 static const GrStencilFunc | 737 static const GrStencilFunc |
| 738 gSpecialToBasicStencilFunc[2][kClipStencilFuncCount] = { | 738 gSpecialToBasicStencilFunc[2][kClipStencilFuncCount] = { |
| 739 {// Stencil-Clipping is DISABLED, we are effectively always inside the clip | 739 {// Stencil-Clipping is DISABLED, we are effectively always inside the clip |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 791 // GrGpu's fStencilSettings and eliminate the stack copy here. | 791 // GrGpu's fStencilSettings and eliminate the stack copy here. |
| 792 | 792 |
| 793 const GrDrawState& drawState = fGpu->getDrawState(); | 793 const GrDrawState& drawState = fGpu->getDrawState(); |
| 794 | 794 |
| 795 // use stencil for clipping if clipping is enabled and the clip | 795 // use stencil for clipping if clipping is enabled and the clip |
| 796 // has been written into the stencil. | 796 // has been written into the stencil. |
| 797 GrClipMaskManager::StencilClipMode clipMode; | 797 GrClipMaskManager::StencilClipMode clipMode; |
| 798 if (this->isClipInStencil() && drawState.isClipState()) { | 798 if (this->isClipInStencil() && drawState.isClipState()) { |
| 799 clipMode = GrClipMaskManager::kRespectClip_StencilClipMode; | 799 clipMode = GrClipMaskManager::kRespectClip_StencilClipMode; |
| 800 // We can't be modifying the clip and respecting it at the same time. | 800 // We can't be modifying the clip and respecting it at the same time. |
| 801 GrAssert(!drawState.isStateFlagEnabled( | 801 SkASSERT(!drawState.isStateFlagEnabled( |
| 802 GrGpu::kModifyStencilClip_StateBit)); | 802 GrGpu::kModifyStencilClip_StateBit)); |
| 803 } else if (drawState.isStateFlagEnabled( | 803 } else if (drawState.isStateFlagEnabled( |
| 804 GrGpu::kModifyStencilClip_StateBit)) { | 804 GrGpu::kModifyStencilClip_StateBit)) { |
| 805 clipMode = GrClipMaskManager::kModifyClip_StencilClipMode; | 805 clipMode = GrClipMaskManager::kModifyClip_StencilClipMode; |
| 806 } else { | 806 } else { |
| 807 clipMode = GrClipMaskManager::kIgnoreClip_StencilClipMode; | 807 clipMode = GrClipMaskManager::kIgnoreClip_StencilClipMode; |
| 808 } | 808 } |
| 809 | 809 |
| 810 GrStencilSettings settings; | 810 GrStencilSettings settings; |
| 811 // The GrGpu client may not be using the stencil buffer but we may need to | 811 // The GrGpu client may not be using the stencil buffer but we may need to |
| (...skipping 10 matching lines...) Expand all Loading... |
| 822 } | 822 } |
| 823 | 823 |
| 824 // TODO: dynamically attach a stencil buffer | 824 // TODO: dynamically attach a stencil buffer |
| 825 int stencilBits = 0; | 825 int stencilBits = 0; |
| 826 GrStencilBuffer* stencilBuffer = | 826 GrStencilBuffer* stencilBuffer = |
| 827 drawState.getRenderTarget()->getStencilBuffer(); | 827 drawState.getRenderTarget()->getStencilBuffer(); |
| 828 if (NULL != stencilBuffer) { | 828 if (NULL != stencilBuffer) { |
| 829 stencilBits = stencilBuffer->bits(); | 829 stencilBits = stencilBuffer->bits(); |
| 830 } | 830 } |
| 831 | 831 |
| 832 GrAssert(fGpu->caps()->stencilWrapOpsSupport() || !settings.usesWrapOp()); | 832 SkASSERT(fGpu->caps()->stencilWrapOpsSupport() || !settings.usesWrapOp()); |
| 833 GrAssert(fGpu->caps()->twoSidedStencilSupport() || !settings.isTwoSided()); | 833 SkASSERT(fGpu->caps()->twoSidedStencilSupport() || !settings.isTwoSided()); |
| 834 this->adjustStencilParams(&settings, clipMode, stencilBits); | 834 this->adjustStencilParams(&settings, clipMode, stencilBits); |
| 835 fGpu->setStencilSettings(settings); | 835 fGpu->setStencilSettings(settings); |
| 836 } | 836 } |
| 837 | 837 |
| 838 void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings, | 838 void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings, |
| 839 StencilClipMode mode, | 839 StencilClipMode mode, |
| 840 int stencilBitCnt) { | 840 int stencilBitCnt) { |
| 841 GrAssert(stencilBitCnt > 0); | 841 SkASSERT(stencilBitCnt > 0); |
| 842 | 842 |
| 843 if (kModifyClip_StencilClipMode == mode) { | 843 if (kModifyClip_StencilClipMode == mode) { |
| 844 // We assume that this clip manager itself is drawing to the GrGpu and | 844 // We assume that this clip manager itself is drawing to the GrGpu and |
| 845 // has already setup the correct values. | 845 // has already setup the correct values. |
| 846 return; | 846 return; |
| 847 } | 847 } |
| 848 | 848 |
| 849 unsigned int clipBit = (1 << (stencilBitCnt - 1)); | 849 unsigned int clipBit = (1 << (stencilBitCnt - 1)); |
| 850 unsigned int userBits = clipBit - 1; | 850 unsigned int userBits = clipBit - 1; |
| 851 | 851 |
| 852 GrStencilSettings::Face face = GrStencilSettings::kFront_Face; | 852 GrStencilSettings::Face face = GrStencilSettings::kFront_Face; |
| 853 bool twoSided = fGpu->caps()->twoSidedStencilSupport(); | 853 bool twoSided = fGpu->caps()->twoSidedStencilSupport(); |
| 854 | 854 |
| 855 bool finished = false; | 855 bool finished = false; |
| 856 while (!finished) { | 856 while (!finished) { |
| 857 GrStencilFunc func = settings->func(face); | 857 GrStencilFunc func = settings->func(face); |
| 858 uint16_t writeMask = settings->writeMask(face); | 858 uint16_t writeMask = settings->writeMask(face); |
| 859 uint16_t funcMask = settings->funcMask(face); | 859 uint16_t funcMask = settings->funcMask(face); |
| 860 uint16_t funcRef = settings->funcRef(face); | 860 uint16_t funcRef = settings->funcRef(face); |
| 861 | 861 |
| 862 GrAssert((unsigned) func < kStencilFuncCount); | 862 SkASSERT((unsigned) func < kStencilFuncCount); |
| 863 | 863 |
| 864 writeMask &= userBits; | 864 writeMask &= userBits; |
| 865 | 865 |
| 866 if (func >= kBasicStencilFuncCount) { | 866 if (func >= kBasicStencilFuncCount) { |
| 867 int respectClip = kRespectClip_StencilClipMode == mode; | 867 int respectClip = kRespectClip_StencilClipMode == mode; |
| 868 if (respectClip) { | 868 if (respectClip) { |
| 869 // The GrGpu class should have checked this | 869 // The GrGpu class should have checked this |
| 870 GrAssert(this->isClipInStencil()); | 870 SkASSERT(this->isClipInStencil()); |
| 871 switch (func) { | 871 switch (func) { |
| 872 case kAlwaysIfInClip_StencilFunc: | 872 case kAlwaysIfInClip_StencilFunc: |
| 873 funcMask = clipBit; | 873 funcMask = clipBit; |
| 874 funcRef = clipBit; | 874 funcRef = clipBit; |
| 875 break; | 875 break; |
| 876 case kEqualIfInClip_StencilFunc: | 876 case kEqualIfInClip_StencilFunc: |
| 877 case kLessIfInClip_StencilFunc: | 877 case kLessIfInClip_StencilFunc: |
| 878 case kLEqualIfInClip_StencilFunc: | 878 case kLEqualIfInClip_StencilFunc: |
| 879 funcMask = (funcMask & userBits) | clipBit; | 879 funcMask = (funcMask & userBits) | clipBit; |
| 880 funcRef = (funcRef & userBits) | clipBit; | 880 funcRef = (funcRef & userBits) | clipBit; |
| 881 break; | 881 break; |
| 882 case kNonZeroIfInClip_StencilFunc: | 882 case kNonZeroIfInClip_StencilFunc: |
| 883 funcMask = (funcMask & userBits) | clipBit; | 883 funcMask = (funcMask & userBits) | clipBit; |
| 884 funcRef = clipBit; | 884 funcRef = clipBit; |
| 885 break; | 885 break; |
| 886 default: | 886 default: |
| 887 GrCrash("Unknown stencil func"); | 887 GrCrash("Unknown stencil func"); |
| 888 } | 888 } |
| 889 } else { | 889 } else { |
| 890 funcMask &= userBits; | 890 funcMask &= userBits; |
| 891 funcRef &= userBits; | 891 funcRef &= userBits; |
| 892 } | 892 } |
| 893 const GrStencilFunc* table = | 893 const GrStencilFunc* table = |
| 894 gSpecialToBasicStencilFunc[respectClip]; | 894 gSpecialToBasicStencilFunc[respectClip]; |
| 895 func = table[func - kBasicStencilFuncCount]; | 895 func = table[func - kBasicStencilFuncCount]; |
| 896 GrAssert(func >= 0 && func < kBasicStencilFuncCount); | 896 SkASSERT(func >= 0 && func < kBasicStencilFuncCount); |
| 897 } else { | 897 } else { |
| 898 funcMask &= userBits; | 898 funcMask &= userBits; |
| 899 funcRef &= userBits; | 899 funcRef &= userBits; |
| 900 } | 900 } |
| 901 | 901 |
| 902 settings->setFunc(face, func); | 902 settings->setFunc(face, func); |
| 903 settings->setWriteMask(face, writeMask); | 903 settings->setWriteMask(face, writeMask); |
| 904 settings->setFuncMask(face, funcMask); | 904 settings->setFuncMask(face, funcMask); |
| 905 settings->setFuncRef(face, funcRef); | 905 settings->setFuncRef(face, funcRef); |
| 906 | 906 |
| 907 if (GrStencilSettings::kFront_Face == face) { | 907 if (GrStencilSettings::kFront_Face == face) { |
| 908 face = GrStencilSettings::kBack_Face; | 908 face = GrStencilSettings::kBack_Face; |
| 909 finished = !twoSided; | 909 finished = !twoSided; |
| 910 } else { | 910 } else { |
| 911 finished = true; | 911 finished = true; |
| 912 } | 912 } |
| 913 } | 913 } |
| 914 if (!twoSided) { | 914 if (!twoSided) { |
| 915 settings->copyFrontSettingsToBack(); | 915 settings->copyFrontSettingsToBack(); |
| 916 } | 916 } |
| 917 } | 917 } |
| 918 | 918 |
| 919 //////////////////////////////////////////////////////////////////////////////// | 919 //////////////////////////////////////////////////////////////////////////////// |
| 920 GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t clipStackGenID, | 920 GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t clipStackGenID, |
| 921 GrReducedClip::InitialState
initialState, | 921 GrReducedClip::InitialState
initialState, |
| 922 const GrReducedClip::Elemen
tList& elements, | 922 const GrReducedClip::Elemen
tList& elements, |
| 923 const SkIRect& clipSpaceIBo
unds) { | 923 const SkIRect& clipSpaceIBo
unds) { |
| 924 GrAssert(kNone_ClipMaskType == fCurrClipMaskType); | 924 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); |
| 925 | 925 |
| 926 GrTexture* result; | 926 GrTexture* result; |
| 927 if (this->getMaskTexture(clipStackGenID, clipSpaceIBounds, &result)) { | 927 if (this->getMaskTexture(clipStackGenID, clipSpaceIBounds, &result)) { |
| 928 return result; | 928 return result; |
| 929 } | 929 } |
| 930 | 930 |
| 931 if (NULL == result) { | 931 if (NULL == result) { |
| 932 fAACache.reset(); | 932 fAACache.reset(); |
| 933 return NULL; | 933 return NULL; |
| 934 } | 934 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 967 if (Element::kRect_Type == element->getType()) { | 967 if (Element::kRect_Type == element->getType()) { |
| 968 // convert the rect to a path so we can invert the fill | 968 // convert the rect to a path so we can invert the fill |
| 969 SkPath temp; | 969 SkPath temp; |
| 970 temp.addRect(element->getRect()); | 970 temp.addRect(element->getRect()); |
| 971 temp.setFillType(SkPath::kInverseEvenOdd_FillType); | 971 temp.setFillType(SkPath::kInverseEvenOdd_FillType); |
| 972 | 972 |
| 973 helper.draw(temp, stroke, SkRegion::kReplace_Op, | 973 helper.draw(temp, stroke, SkRegion::kReplace_Op, |
| 974 element->isAA(), | 974 element->isAA(), |
| 975 0x00); | 975 0x00); |
| 976 } else { | 976 } else { |
| 977 GrAssert(Element::kPath_Type == element->getType()); | 977 SkASSERT(Element::kPath_Type == element->getType()); |
| 978 SkPath clipPath = element->getPath(); | 978 SkPath clipPath = element->getPath(); |
| 979 clipPath.toggleInverseFillType(); | 979 clipPath.toggleInverseFillType(); |
| 980 helper.draw(clipPath, stroke, | 980 helper.draw(clipPath, stroke, |
| 981 SkRegion::kReplace_Op, | 981 SkRegion::kReplace_Op, |
| 982 element->isAA(), | 982 element->isAA(), |
| 983 0x00); | 983 0x00); |
| 984 } | 984 } |
| 985 | 985 |
| 986 continue; | 986 continue; |
| 987 } | 987 } |
| 988 | 988 |
| 989 // The other ops (union, xor, diff) only affect pixels inside | 989 // The other ops (union, xor, diff) only affect pixels inside |
| 990 // the geometry so they can just be drawn normally | 990 // the geometry so they can just be drawn normally |
| 991 if (Element::kRect_Type == element->getType()) { | 991 if (Element::kRect_Type == element->getType()) { |
| 992 helper.draw(element->getRect(), op, element->isAA(), 0xFF); | 992 helper.draw(element->getRect(), op, element->isAA(), 0xFF); |
| 993 } else { | 993 } else { |
| 994 GrAssert(Element::kPath_Type == element->getType()); | 994 SkASSERT(Element::kPath_Type == element->getType()); |
| 995 helper.draw(element->getPath(), stroke, op, element->isAA(), 0xFF); | 995 helper.draw(element->getPath(), stroke, op, element->isAA(), 0xFF); |
| 996 } | 996 } |
| 997 } | 997 } |
| 998 | 998 |
| 999 helper.toTexture(result); | 999 helper.toTexture(result); |
| 1000 | 1000 |
| 1001 fCurrClipMaskType = kAlpha_ClipMaskType; | 1001 fCurrClipMaskType = kAlpha_ClipMaskType; |
| 1002 return result; | 1002 return result; |
| 1003 } | 1003 } |
| 1004 | 1004 |
| 1005 //////////////////////////////////////////////////////////////////////////////// | 1005 //////////////////////////////////////////////////////////////////////////////// |
| 1006 void GrClipMaskManager::releaseResources() { | 1006 void GrClipMaskManager::releaseResources() { |
| 1007 fAACache.releaseResources(); | 1007 fAACache.releaseResources(); |
| 1008 } | 1008 } |
| 1009 | 1009 |
| 1010 void GrClipMaskManager::setGpu(GrGpu* gpu) { | 1010 void GrClipMaskManager::setGpu(GrGpu* gpu) { |
| 1011 fGpu = gpu; | 1011 fGpu = gpu; |
| 1012 fAACache.setContext(gpu->getContext()); | 1012 fAACache.setContext(gpu->getContext()); |
| 1013 } | 1013 } |
| OLD | NEW |