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 fClipMode = kRespectClip_StencilClipMode; |
848 return true; | 852 return true; |
849 } | 853 } |
850 | 854 |
851 | 855 |
852 // mapping of clip-respecting stencil funcs to normal stencil funcs | 856 // mapping of clip-respecting stencil funcs to normal stencil funcs |
853 // mapping depends on whether stencil-clipping is in effect. | 857 // mapping depends on whether stencil-clipping is in effect. |
854 static const GrStencilFunc | 858 static const GrStencilFunc |
855 gSpecialToBasicStencilFunc[2][kClipStencilFuncCount] = { | 859 gSpecialToBasicStencilFunc[2][kClipStencilFuncCount] = { |
856 {// Stencil-Clipping is DISABLED, we are effectively always inside the clip | 860 {// Stencil-Clipping is DISABLED, we are effectively always inside the clip |
857 // In the Clip Funcs | 861 // In the Clip Funcs |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
904 void GrClipMaskManager::setDrawStateStencil(GrDrawState::AutoRestoreStencil* ars
) { | 908 void GrClipMaskManager::setDrawStateStencil(GrDrawState::AutoRestoreStencil* ars
) { |
905 // We make two copies of the StencilSettings here (except in the early | 909 // 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 | 910 // 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 | 911 // 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. | 912 // GrGpu's fStencilSettings and eliminate the stack copy here. |
909 | 913 |
910 const GrDrawState& drawState = fClipTarget->getDrawState(); | 914 const GrDrawState& drawState = fClipTarget->getDrawState(); |
911 | 915 |
912 // use stencil for clipping if clipping is enabled and the clip | 916 // use stencil for clipping if clipping is enabled and the clip |
913 // has been written into the stencil. | 917 // 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 | 918 |
925 GrStencilSettings settings; | 919 GrStencilSettings settings; |
926 // The GrGpu client may not be using the stencil buffer but we may need to | 920 // 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. | 921 // enable it in order to respect a stencil clip. |
928 if (drawState.getStencil().isDisabled()) { | 922 if (drawState.getStencil().isDisabled()) { |
929 if (GrClipMaskManager::kRespectClip_StencilClipMode == clipMode) { | 923 if (GrClipMaskManager::kRespectClip_StencilClipMode == fClipMode) { |
930 settings = basic_apply_stencil_clip_settings(); | 924 settings = basic_apply_stencil_clip_settings(); |
931 } else { | 925 } else { |
932 return; | 926 return; |
933 } | 927 } |
934 } else { | 928 } else { |
935 settings = drawState.getStencil(); | 929 settings = drawState.getStencil(); |
936 } | 930 } |
937 | 931 |
938 // TODO: dynamically attach a stencil buffer | 932 // TODO: dynamically attach a stencil buffer |
939 int stencilBits = 0; | 933 int stencilBits = 0; |
940 GrStencilBuffer* stencilBuffer = drawState.getRenderTarget()->getStencilBuff
er(); | 934 GrStencilBuffer* stencilBuffer = drawState.getRenderTarget()->getStencilBuff
er(); |
941 if (stencilBuffer) { | 935 if (stencilBuffer) { |
942 stencilBits = stencilBuffer->bits(); | 936 stencilBits = stencilBuffer->bits(); |
943 } | 937 } |
944 | 938 |
945 SkASSERT(fClipTarget->caps()->stencilWrapOpsSupport() || !settings.usesWrapO
p()); | 939 SkASSERT(fClipTarget->caps()->stencilWrapOpsSupport() || !settings.usesWrapO
p()); |
946 SkASSERT(fClipTarget->caps()->twoSidedStencilSupport() || !settings.isTwoSid
ed()); | 940 SkASSERT(fClipTarget->caps()->twoSidedStencilSupport() || !settings.isTwoSid
ed()); |
947 this->adjustStencilParams(&settings, clipMode, stencilBits); | 941 this->adjustStencilParams(&settings, fClipMode, stencilBits); |
948 ars->set(fClipTarget->drawState()); | 942 ars->set(fClipTarget->drawState()); |
949 fClipTarget->drawState()->setStencil(settings); | 943 fClipTarget->drawState()->setStencil(settings); |
950 } | 944 } |
951 | 945 |
952 void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings, | 946 void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings, |
953 StencilClipMode mode, | 947 StencilClipMode mode, |
954 int stencilBitCnt) { | 948 int stencilBitCnt) { |
955 SkASSERT(stencilBitCnt > 0); | 949 SkASSERT(stencilBitCnt > 0); |
956 | 950 |
957 if (kModifyClip_StencilClipMode == mode) { | 951 if (kModifyClip_StencilClipMode == mode) { |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1109 fAACache.purgeResources(); | 1103 fAACache.purgeResources(); |
1110 } | 1104 } |
1111 | 1105 |
1112 void GrClipMaskManager::setClipTarget(GrClipTarget* clipTarget) { | 1106 void GrClipMaskManager::setClipTarget(GrClipTarget* clipTarget) { |
1113 fClipTarget = clipTarget; | 1107 fClipTarget = clipTarget; |
1114 fAACache.setContext(clipTarget->getContext()); | 1108 fAACache.setContext(clipTarget->getContext()); |
1115 } | 1109 } |
1116 | 1110 |
1117 void GrClipMaskManager::adjustPathStencilParams(GrStencilSettings* settings) { | 1111 void GrClipMaskManager::adjustPathStencilParams(GrStencilSettings* settings) { |
1118 const GrDrawState& drawState = fClipTarget->getDrawState(); | 1112 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 | 1113 |
1130 // TODO: dynamically attach a stencil buffer | 1114 // TODO: dynamically attach a stencil buffer |
1131 int stencilBits = 0; | 1115 int stencilBits = 0; |
1132 GrStencilBuffer* stencilBuffer = drawState.getRenderTarget()->getStencilBuff
er(); | 1116 GrStencilBuffer* stencilBuffer = drawState.getRenderTarget()->getStencilBuff
er(); |
1133 if (stencilBuffer) { | 1117 if (stencilBuffer) { |
1134 stencilBits = stencilBuffer->bits(); | 1118 stencilBits = stencilBuffer->bits(); |
1135 this->adjustStencilParams(settings, clipMode, stencilBits); | 1119 this->adjustStencilParams(settings, fClipMode, stencilBits); |
1136 } | 1120 } |
1137 } | 1121 } |
OLD | NEW |