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 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
209 | 209 |
210 //////////////////////////////////////////////////////////////////////////////// | 210 //////////////////////////////////////////////////////////////////////////////// |
211 // sort out what kind of clip mask needs to be created: alpha, stencil, | 211 // sort out what kind of clip mask needs to be created: alpha, stencil, |
212 // scissor, or entirely software | 212 // scissor, or entirely software |
213 bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn, | 213 bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn, |
214 const SkRect* devBounds, | 214 const SkRect* devBounds, |
215 GrDrawState::AutoRestoreEffects* are, | 215 GrDrawState::AutoRestoreEffects* are, |
216 GrDrawState::AutoRestoreStencil* ars, | 216 GrDrawState::AutoRestoreStencil* ars, |
217 ScissorState* scissorState) { | 217 ScissorState* scissorState) { |
218 fCurrClipMaskType = kNone_ClipMaskType; | 218 fCurrClipMaskType = kNone_ClipMaskType; |
219 if (kRespectClip_StencilClipMode == fClipMode) { | |
220 fClipMode = kIgnoreClip_StencilClipMode; | |
221 } | |
219 | 222 |
220 GrReducedClip::ElementList elements(16); | 223 GrReducedClip::ElementList elements(16); |
221 int32_t genID; | 224 int32_t genID; |
222 GrReducedClip::InitialState initialState; | 225 GrReducedClip::InitialState initialState; |
223 SkIRect clipSpaceIBounds; | 226 SkIRect clipSpaceIBounds; |
224 bool requiresAA; | 227 bool requiresAA; |
225 | 228 |
226 GrDrawState* drawState = fClipTarget->drawState(); | 229 GrDrawState* drawState = fClipTarget->drawState(); |
227 | 230 |
228 const GrRenderTarget* rt = drawState->getRenderTarget(); | 231 const GrRenderTarget* rt = drawState->getRenderTarget(); |
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
736 fClipTarget->clearStencilClip(stencilSpaceIBounds, | 739 fClipTarget->clearStencilClip(stencilSpaceIBounds, |
737 GrReducedClip::kAllIn_InitialState == init ialState, | 740 GrReducedClip::kAllIn_InitialState == init ialState, |
738 rt); | 741 rt); |
739 | 742 |
740 // walk through each clip element and perform its set op | 743 // walk through each clip element and perform its set op |
741 // with the existing clip. | 744 // with the existing clip. |
742 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.ge t(); iter.next()) { | 745 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.ge t(); iter.next()) { |
743 const Element* element = iter.get(); | 746 const Element* element = iter.get(); |
744 bool fillInverted = false; | 747 bool fillInverted = false; |
745 // enabled at bottom of loop | 748 // enabled at bottom of loop |
746 drawState->disableState(kModifyStencilClip_StateBit); | 749 fClipMode = kIgnoreClip_StencilClipMode; |
747 // if the target is MSAA then we want MSAA enabled when the clip is soft | 750 // if the target is MSAA then we want MSAA enabled when the clip is soft |
748 if (rt->isMultisampled()) { | 751 if (rt->isMultisampled()) { |
749 drawState->setState(GrDrawState::kHWAntialias_StateBit, element- >isAA()); | 752 drawState->setState(GrDrawState::kHWAntialias_StateBit, element- >isAA()); |
750 } | 753 } |
751 | 754 |
752 // This will be used to determine whether the clip shape can be rend ered into the | 755 // This will be used to determine whether the clip shape can be rend ered into the |
753 // stencil with arbitrary stencil settings. | 756 // stencil with arbitrary stencil settings. |
754 GrPathRenderer::StencilSupport stencilSupport; | 757 GrPathRenderer::StencilSupport stencilSupport; |
755 | 758 |
756 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); | 759 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
815 pr->drawPath(clipPath, stroke, fClipTarget, false); | 818 pr->drawPath(clipPath, stroke, fClipTarget, false); |
816 } else { | 819 } else { |
817 pr->stencilPath(clipPath, stroke, fClipTarget); | 820 pr->stencilPath(clipPath, stroke, fClipTarget); |
818 } | 821 } |
819 } | 822 } |
820 } | 823 } |
821 } | 824 } |
822 | 825 |
823 // now we modify the clip bit by rendering either the clip | 826 // now we modify the clip bit by rendering either the clip |
824 // element directly or a bounding rect of the entire clip. | 827 // element directly or a bounding rect of the entire clip. |
825 drawState->enableState(kModifyStencilClip_StateBit); | 828 fClipMode = kModifyClip_StencilClipMode; |
826 for (int p = 0; p < passes; ++p) { | 829 for (int p = 0; p < passes; ++p) { |
827 *drawState->stencil() = stencilSettings[p]; | 830 *drawState->stencil() = stencilSettings[p]; |
828 if (canDrawDirectToClip) { | 831 if (canDrawDirectToClip) { |
829 if (Element::kRect_Type == element->getType()) { | 832 if (Element::kRect_Type == element->getType()) { |
830 SET_RANDOM_COLOR | 833 SET_RANDOM_COLOR |
831 fClipTarget->drawSimpleRect(element->getRect()); | 834 fClipTarget->drawSimpleRect(element->getRect()); |
832 } else { | 835 } else { |
833 SET_RANDOM_COLOR | 836 SET_RANDOM_COLOR |
834 pr->drawPath(clipPath, stroke, fClipTarget, false); | 837 pr->drawPath(clipPath, stroke, fClipTarget, false); |
835 } | 838 } |
836 } else { | 839 } else { |
837 SET_RANDOM_COLOR | 840 SET_RANDOM_COLOR |
838 // The view matrix is setup to do clip space -> stencil spac e translation, so | 841 // The view matrix is setup to do clip space -> stencil spac e translation, so |
839 // draw rect in clip space. | 842 // draw rect in clip space. |
840 fClipTarget->drawSimpleRect(SkRect::Make(clipSpaceIBounds)); | 843 fClipTarget->drawSimpleRect(SkRect::Make(clipSpaceIBounds)); |
841 } | 844 } |
842 } | 845 } |
843 } | 846 } |
844 } | 847 } |
845 // set this last because recursive draws may overwrite it back to kNone. | 848 // set this last because recursive draws may overwrite it back to kNone. |
846 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); | 849 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); |
847 fCurrClipMaskType = kStencil_ClipMaskType; | 850 fCurrClipMaskType = kStencil_ClipMaskType; |
851 if (drawState->isClipState()) { | |
bsalomon
2014/10/29 17:08:24
Can we get here w/o this condition being true? I d
| |
852 fClipMode = kRespectClip_StencilClipMode; | |
853 } | |
848 return true; | 854 return true; |
849 } | 855 } |
850 | 856 |
851 | 857 |
852 // mapping of clip-respecting stencil funcs to normal stencil funcs | 858 // mapping of clip-respecting stencil funcs to normal stencil funcs |
853 // mapping depends on whether stencil-clipping is in effect. | 859 // mapping depends on whether stencil-clipping is in effect. |
854 static const GrStencilFunc | 860 static const GrStencilFunc |
855 gSpecialToBasicStencilFunc[2][kClipStencilFuncCount] = { | 861 gSpecialToBasicStencilFunc[2][kClipStencilFuncCount] = { |
856 {// Stencil-Clipping is DISABLED, we are effectively always inside the clip | 862 {// Stencil-Clipping is DISABLED, we are effectively always inside the clip |
857 // In the Clip Funcs | 863 // In the Clip Funcs |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
904 void GrClipMaskManager::setDrawStateStencil(GrDrawState::AutoRestoreStencil* ars ) { | 910 void GrClipMaskManager::setDrawStateStencil(GrDrawState::AutoRestoreStencil* ars ) { |
905 // We make two copies of the StencilSettings here (except in the early | 911 // We make two copies of the StencilSettings here (except in the early |
906 // exit scenario. One copy from draw state to the stack var. Then another | 912 // exit scenario. One copy from draw state to the stack var. Then another |
907 // from the stack var to the gpu. We could make this class hold a ptr to | 913 // from the stack var to the gpu. We could make this class hold a ptr to |
908 // GrGpu's fStencilSettings and eliminate the stack copy here. | 914 // GrGpu's fStencilSettings and eliminate the stack copy here. |
909 | 915 |
910 const GrDrawState& drawState = fClipTarget->getDrawState(); | 916 const GrDrawState& drawState = fClipTarget->getDrawState(); |
911 | 917 |
912 // use stencil for clipping if clipping is enabled and the clip | 918 // use stencil for clipping if clipping is enabled and the clip |
913 // has been written into the stencil. | 919 // has been written into the stencil. |
914 GrClipMaskManager::StencilClipMode clipMode; | |
915 if (this->isClipInStencil() && drawState.isClipState()) { | |
916 clipMode = GrClipMaskManager::kRespectClip_StencilClipMode; | |
917 // We can't be modifying the clip and respecting it at the same time. | |
918 SkASSERT(!drawState.isStateFlagEnabled(kModifyStencilClip_StateBit)); | |
919 } else if (drawState.isStateFlagEnabled(kModifyStencilClip_StateBit)) { | |
920 clipMode = GrClipMaskManager::kModifyClip_StencilClipMode; | |
921 } else { | |
922 clipMode = GrClipMaskManager::kIgnoreClip_StencilClipMode; | |
923 } | |
924 | 920 |
925 GrStencilSettings settings; | 921 GrStencilSettings settings; |
926 // The GrGpu client may not be using the stencil buffer but we may need to | 922 // The GrGpu client may not be using the stencil buffer but we may need to |
927 // enable it in order to respect a stencil clip. | 923 // enable it in order to respect a stencil clip. |
928 if (drawState.getStencil().isDisabled()) { | 924 if (drawState.getStencil().isDisabled()) { |
929 if (GrClipMaskManager::kRespectClip_StencilClipMode == clipMode) { | 925 if (GrClipMaskManager::kRespectClip_StencilClipMode == fClipMode) { |
930 settings = basic_apply_stencil_clip_settings(); | 926 settings = basic_apply_stencil_clip_settings(); |
931 } else { | 927 } else { |
932 return; | 928 return; |
933 } | 929 } |
934 } else { | 930 } else { |
935 settings = drawState.getStencil(); | 931 settings = drawState.getStencil(); |
936 } | 932 } |
937 | 933 |
938 // TODO: dynamically attach a stencil buffer | 934 // TODO: dynamically attach a stencil buffer |
939 int stencilBits = 0; | 935 int stencilBits = 0; |
940 GrStencilBuffer* stencilBuffer = drawState.getRenderTarget()->getStencilBuff er(); | 936 GrStencilBuffer* stencilBuffer = drawState.getRenderTarget()->getStencilBuff er(); |
941 if (stencilBuffer) { | 937 if (stencilBuffer) { |
942 stencilBits = stencilBuffer->bits(); | 938 stencilBits = stencilBuffer->bits(); |
943 } | 939 } |
944 | 940 |
945 SkASSERT(fClipTarget->caps()->stencilWrapOpsSupport() || !settings.usesWrapO p()); | 941 SkASSERT(fClipTarget->caps()->stencilWrapOpsSupport() || !settings.usesWrapO p()); |
946 SkASSERT(fClipTarget->caps()->twoSidedStencilSupport() || !settings.isTwoSid ed()); | 942 SkASSERT(fClipTarget->caps()->twoSidedStencilSupport() || !settings.isTwoSid ed()); |
947 this->adjustStencilParams(&settings, clipMode, stencilBits); | 943 this->adjustStencilParams(&settings, fClipMode, stencilBits); |
948 ars->set(fClipTarget->drawState()); | 944 ars->set(fClipTarget->drawState()); |
949 fClipTarget->drawState()->setStencil(settings); | 945 fClipTarget->drawState()->setStencil(settings); |
950 } | 946 } |
951 | 947 |
952 void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings, | 948 void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings, |
953 StencilClipMode mode, | 949 StencilClipMode mode, |
954 int stencilBitCnt) { | 950 int stencilBitCnt) { |
955 SkASSERT(stencilBitCnt > 0); | 951 SkASSERT(stencilBitCnt > 0); |
956 | 952 |
957 if (kModifyClip_StencilClipMode == mode) { | 953 if (kModifyClip_StencilClipMode == mode) { |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1109 fAACache.purgeResources(); | 1105 fAACache.purgeResources(); |
1110 } | 1106 } |
1111 | 1107 |
1112 void GrClipMaskManager::setClipTarget(GrClipTarget* clipTarget) { | 1108 void GrClipMaskManager::setClipTarget(GrClipTarget* clipTarget) { |
1113 fClipTarget = clipTarget; | 1109 fClipTarget = clipTarget; |
1114 fAACache.setContext(clipTarget->getContext()); | 1110 fAACache.setContext(clipTarget->getContext()); |
1115 } | 1111 } |
1116 | 1112 |
1117 void GrClipMaskManager::adjustPathStencilParams(GrStencilSettings* settings) { | 1113 void GrClipMaskManager::adjustPathStencilParams(GrStencilSettings* settings) { |
1118 const GrDrawState& drawState = fClipTarget->getDrawState(); | 1114 const GrDrawState& drawState = fClipTarget->getDrawState(); |
1119 GrClipMaskManager::StencilClipMode clipMode; | |
1120 if (this->isClipInStencil() && drawState.isClipState()) { | |
1121 clipMode = GrClipMaskManager::kRespectClip_StencilClipMode; | |
1122 // We can't be modifying the clip and respecting it at the same time. | |
1123 SkASSERT(!drawState.isStateFlagEnabled(kModifyStencilClip_StateBit)); | |
1124 } else if (drawState.isStateFlagEnabled(kModifyStencilClip_StateBit)) { | |
1125 clipMode = GrClipMaskManager::kModifyClip_StencilClipMode; | |
1126 } else { | |
1127 clipMode = GrClipMaskManager::kIgnoreClip_StencilClipMode; | |
1128 } | |
1129 | 1115 |
1130 // TODO: dynamically attach a stencil buffer | 1116 // TODO: dynamically attach a stencil buffer |
1131 int stencilBits = 0; | 1117 int stencilBits = 0; |
1132 GrStencilBuffer* stencilBuffer = drawState.getRenderTarget()->getStencilBuff er(); | 1118 GrStencilBuffer* stencilBuffer = drawState.getRenderTarget()->getStencilBuff er(); |
1133 if (stencilBuffer) { | 1119 if (stencilBuffer) { |
1134 stencilBits = stencilBuffer->bits(); | 1120 stencilBits = stencilBuffer->bits(); |
1135 this->adjustStencilParams(settings, clipMode, stencilBits); | 1121 this->adjustStencilParams(settings, fClipMode, stencilBits); |
1136 } | 1122 } |
1137 } | 1123 } |
OLD | NEW |