| 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 "GrDrawingManager.h" | 10 #include "GrDrawingManager.h" |
| (...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 668 if (Element::kRect_Type != element->getType() && !pr) { | 668 if (Element::kRect_Type != element->getType() && !pr) { |
| 669 // UseSWOnlyPath should now filter out all cases where gpu-side
mask merging would | 669 // UseSWOnlyPath should now filter out all cases where gpu-side
mask merging would |
| 670 // be performed (i.e., pr would be NULL for a non-rect path). | 670 // be performed (i.e., pr would be NULL for a non-rect path). |
| 671 // See https://bug.skia.org/4519 for rationale and details. | 671 // See https://bug.skia.org/4519 for rationale and details. |
| 672 SkASSERT(0); | 672 SkASSERT(0); |
| 673 } | 673 } |
| 674 #endif | 674 #endif |
| 675 | 675 |
| 676 // draw directly into the result with the stencil set to make the pi
xels affected | 676 // draw directly into the result with the stencil set to make the pi
xels affected |
| 677 // by the clip shape be non-zero. | 677 // by the clip shape be non-zero. |
| 678 GR_STATIC_CONST_SAME_STENCIL(kStencilInElement, | 678 static constexpr GrStencilSettings kStencilInElement( |
| 679 kReplace_StencilOp, | 679 kReplace_StencilOp, |
| 680 kReplace_StencilOp, | 680 kReplace_StencilOp, |
| 681 kAlways_StencilFunc, | 681 kAlways_StencilFunc, |
| 682 0xffff, | 682 0xffff, |
| 683 0xffff, | 683 0xffff, |
| 684 0xffff) | 684 0xffff); |
| 685 if (!stencil_element(dc.get(), &maskSpaceIBounds, kStencilInElement, | 685 if (!stencil_element(dc.get(), &maskSpaceIBounds, kStencilInElement, |
| 686 translate, element)) { | 686 translate, element)) { |
| 687 texture->resourcePriv().removeUniqueKey(); | 687 texture->resourcePriv().removeUniqueKey(); |
| 688 return nullptr; | 688 return nullptr; |
| 689 } | 689 } |
| 690 | 690 |
| 691 // Draw to the exterior pixels (those with a zero stencil value). | 691 // Draw to the exterior pixels (those with a zero stencil value). |
| 692 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, | 692 static constexpr GrStencilSettings kDrawOutsideElement( |
| 693 kZero_StencilOp, | 693 kZero_StencilOp, |
| 694 kZero_StencilOp, | 694 kZero_StencilOp, |
| 695 kEqual_StencilFunc, | 695 kEqual_StencilFunc, |
| 696 0xffff, | 696 0xffff, |
| 697 0x0000, | 697 0x0000, |
| 698 0xffff); | 698 0xffff); |
| 699 if (!dc->drawContextPriv().drawAndStencilRect(&maskSpaceIBounds, kDr
awOutsideElement, | 699 if (!dc->drawContextPriv().drawAndStencilRect(&maskSpaceIBounds, kDr
awOutsideElement, |
| 700 op, !invert, false, | 700 op, !invert, false, |
| 701 translate, | 701 translate, |
| 702 SkRect::Make(clipSpace
IBounds))) { | 702 SkRect::Make(clipSpace
IBounds))) { |
| 703 texture->resourcePriv().removeUniqueKey(); | 703 texture->resourcePriv().removeUniqueKey(); |
| 704 return nullptr; | 704 return nullptr; |
| 705 } | 705 } |
| 706 } else { | 706 } else { |
| 707 // all the remaining ops can just be directly draw into the accumula
tion buffer | 707 // all the remaining ops can just be directly draw into the accumula
tion buffer |
| 708 GrPaint paint; | 708 GrPaint paint; |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 823 // stencil bit used for clipping. | 823 // stencil bit used for clipping. |
| 824 canDrawDirectToClip = GrStencilSettings::GetClipPasses(op, | 824 canDrawDirectToClip = GrStencilSettings::GetClipPasses(op, |
| 825 canRenderDire
ctToStencil, | 825 canRenderDire
ctToStencil, |
| 826 clipBit, | 826 clipBit, |
| 827 fillInverted, | 827 fillInverted, |
| 828 &passes, | 828 &passes, |
| 829 stencilSettin
gs); | 829 stencilSettin
gs); |
| 830 | 830 |
| 831 // draw the element to the client stencil bits if necessary | 831 // draw the element to the client stencil bits if necessary |
| 832 if (!canDrawDirectToClip) { | 832 if (!canDrawDirectToClip) { |
| 833 GR_STATIC_CONST_SAME_STENCIL(gDrawToStencil, | 833 static constexpr GrStencilSettings kDrawToStencil( |
| 834 kIncClamp_StencilOp, | 834 kIncClamp_StencilOp, |
| 835 kIncClamp_StencilOp, | 835 kIncClamp_StencilOp, |
| 836 kAlways_StencilFunc, | 836 kAlways_StencilFunc, |
| 837 0xffff, | 837 0xffff, |
| 838 0x0000, | 838 0x0000, |
| 839 0xffff); | 839 0xffff); |
| 840 if (Element::kRect_Type == element->getType()) { | 840 if (Element::kRect_Type == element->getType()) { |
| 841 *pipelineBuilder.stencil() = gDrawToStencil; | 841 *pipelineBuilder.stencil() = kDrawToStencil; |
| 842 | 842 |
| 843 draw_non_aa_rect(fDrawTarget, pipelineBuilder, GrColor_WHITE
, viewMatrix, | 843 draw_non_aa_rect(fDrawTarget, pipelineBuilder, GrColor_WHITE
, viewMatrix, |
| 844 element->getRect()); | 844 element->getRect()); |
| 845 } else { | 845 } else { |
| 846 if (!clipPath.isEmpty()) { | 846 if (!clipPath.isEmpty()) { |
| 847 if (canRenderDirectToStencil) { | 847 if (canRenderDirectToStencil) { |
| 848 *pipelineBuilder.stencil() = gDrawToStencil; | 848 *pipelineBuilder.stencil() = kDrawToStencil; |
| 849 | 849 |
| 850 GrPathRenderer::DrawPathArgs args; | 850 GrPathRenderer::DrawPathArgs args; |
| 851 args.fTarget = fDrawTarget; | 851 args.fTarget = fDrawTarget; |
| 852 args.fResourceProvider = this->getContext()->resourc
eProvider(); | 852 args.fResourceProvider = this->getContext()->resourc
eProvider(); |
| 853 args.fPipelineBuilder = &pipelineBuilder; | 853 args.fPipelineBuilder = &pipelineBuilder; |
| 854 args.fColor = GrColor_WHITE; | 854 args.fColor = GrColor_WHITE; |
| 855 args.fViewMatrix = &viewMatrix; | 855 args.fViewMatrix = &viewMatrix; |
| 856 args.fPath = &clipPath; | 856 args.fPath = &clipPath; |
| 857 args.fStroke = &stroke; | 857 args.fStroke = &stroke; |
| 858 args.fAntiAlias = false; | 858 args.fAntiAlias = false; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 904 } | 904 } |
| 905 } | 905 } |
| 906 } | 906 } |
| 907 fClipMode = kRespectClip_StencilClipMode; | 907 fClipMode = kRespectClip_StencilClipMode; |
| 908 return true; | 908 return true; |
| 909 } | 909 } |
| 910 | 910 |
| 911 // mapping of clip-respecting stencil funcs to normal stencil funcs | 911 // mapping of clip-respecting stencil funcs to normal stencil funcs |
| 912 // mapping depends on whether stencil-clipping is in effect. | 912 // mapping depends on whether stencil-clipping is in effect. |
| 913 static const GrStencilFunc | 913 static const GrStencilFunc |
| 914 gSpecialToBasicStencilFunc[2][kClipStencilFuncCount] = { | 914 gSpecialToBasicStencilFunc[2][kClipStencilFuncCnt] = { |
| 915 {// Stencil-Clipping is DISABLED, we are effectively always inside the clip | 915 {// Stencil-Clipping is DISABLED, we are effectively always inside the clip |
| 916 // In the Clip Funcs | 916 // In the Clip Funcs |
| 917 kAlways_StencilFunc, // kAlwaysIfInClip_StencilFunc | 917 kAlways_StencilFunc, // kAlwaysIfInClip_StencilFunc |
| 918 kEqual_StencilFunc, // kEqualIfInClip_StencilFunc | 918 kEqual_StencilFunc, // kEqualIfInClip_StencilFunc |
| 919 kLess_StencilFunc, // kLessIfInClip_StencilFunc | 919 kLess_StencilFunc, // kLessIfInClip_StencilFunc |
| 920 kLEqual_StencilFunc, // kLEqualIfInClip_StencilFunc | 920 kLEqual_StencilFunc, // kLEqualIfInClip_StencilFunc |
| 921 // Special in the clip func that forces user's ref to be 0. | 921 // Special in the clip func that forces user's ref to be 0. |
| 922 kNotEqual_StencilFunc, // kNonZeroIfInClip_StencilFunc | 922 kNotEqual_StencilFunc, // kNonZeroIfInClip_StencilFunc |
| 923 // make ref 0 and do normal nequal. | 923 // make ref 0 and do normal nequal. |
| 924 }, | 924 }, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 937 // the clip bit to the mask and | 937 // the clip bit to the mask and |
| 938 // ref and compare as normal | 938 // ref and compare as normal |
| 939 // Special in the clip func that forces user's ref to be 0. | 939 // Special in the clip func that forces user's ref to be 0. |
| 940 kLess_StencilFunc, // kNonZeroIfInClip_StencilFunc | 940 kLess_StencilFunc, // kNonZeroIfInClip_StencilFunc |
| 941 // make ref have only the clip bit set | 941 // make ref have only the clip bit set |
| 942 // and make comparison be less | 942 // and make comparison be less |
| 943 // 10..0 < 1..user_bits.. | 943 // 10..0 < 1..user_bits.. |
| 944 } | 944 } |
| 945 }; | 945 }; |
| 946 | 946 |
| 947 namespace { | |
| 948 // Sets the settings to clip against the stencil buffer clip while ignoring the | |
| 949 // client bits. | |
| 950 const GrStencilSettings& basic_apply_stencil_clip_settings() { | |
| 951 // stencil settings to use when clip is in stencil | |
| 952 GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings, | |
| 953 kKeep_StencilOp, | |
| 954 kKeep_StencilOp, | |
| 955 kAlwaysIfInClip_StencilFunc, | |
| 956 0x0000, | |
| 957 0x0000, | |
| 958 0x0000); | |
| 959 return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings); | |
| 960 } | |
| 961 } | |
| 962 | |
| 963 void GrClipMaskManager::setPipelineBuilderStencil(const GrPipelineBuilder& pipel
ineBuilder, | 947 void GrClipMaskManager::setPipelineBuilderStencil(const GrPipelineBuilder& pipel
ineBuilder, |
| 964 GrPipelineBuilder::AutoRestore
Stencil* ars) { | 948 GrPipelineBuilder::AutoRestore
Stencil* ars) { |
| 965 // We make two copies of the StencilSettings here (except in the early | 949 // We make two copies of the StencilSettings here (except in the early |
| 966 // exit scenario. One copy from draw state to the stack var. Then another | 950 // exit scenario. One copy from draw state to the stack var. Then another |
| 967 // from the stack var to the gpu. We could make this class hold a ptr to | 951 // from the stack var to the gpu. We could make this class hold a ptr to |
| 968 // GrGpu's fStencilSettings and eliminate the stack copy here. | 952 // GrGpu's fStencilSettings and eliminate the stack copy here. |
| 969 | 953 |
| 970 // use stencil for clipping if clipping is enabled and the clip | 954 // use stencil for clipping if clipping is enabled and the clip |
| 971 // has been written into the stencil. | 955 // has been written into the stencil. |
| 972 GrStencilSettings settings; | 956 GrStencilSettings settings; |
| 973 | 957 |
| 974 // The GrGpu client may not be using the stencil buffer but we may need to | 958 // The GrGpu client may not be using the stencil buffer but we may need to |
| 975 // enable it in order to respect a stencil clip. | 959 // enable it in order to respect a stencil clip. |
| 976 if (pipelineBuilder.getStencil().isDisabled()) { | 960 if (pipelineBuilder.getStencil().isDisabled()) { |
| 977 if (GrClipMaskManager::kRespectClip_StencilClipMode == fClipMode) { | 961 if (GrClipMaskManager::kRespectClip_StencilClipMode == fClipMode) { |
| 978 settings = basic_apply_stencil_clip_settings(); | 962 static constexpr GrStencilSettings kBasicApplyClipSettings( |
| 963 kKeep_StencilOp, |
| 964 kKeep_StencilOp, |
| 965 kAlwaysIfInClip_StencilFunc, |
| 966 0x0000, |
| 967 0x0000, |
| 968 0x0000); |
| 969 settings = kBasicApplyClipSettings; |
| 979 } else { | 970 } else { |
| 980 return; | 971 return; |
| 981 } | 972 } |
| 982 } else { | 973 } else { |
| 983 settings = pipelineBuilder.getStencil(); | 974 settings = pipelineBuilder.getStencil(); |
| 984 } | 975 } |
| 985 | 976 |
| 986 int stencilBits = 0; | 977 int stencilBits = 0; |
| 987 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); | 978 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); |
| 988 GrStencilAttachment* stencilAttachment = this->resourceProvider()->attachSte
ncilAttachment(rt); | 979 GrStencilAttachment* stencilAttachment = this->resourceProvider()->attachSte
ncilAttachment(rt); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1014 GrStencilSettings::Face face = GrStencilSettings::kFront_Face; | 1005 GrStencilSettings::Face face = GrStencilSettings::kFront_Face; |
| 1015 bool twoSided = this->caps()->twoSidedStencilSupport(); | 1006 bool twoSided = this->caps()->twoSidedStencilSupport(); |
| 1016 | 1007 |
| 1017 bool finished = false; | 1008 bool finished = false; |
| 1018 while (!finished) { | 1009 while (!finished) { |
| 1019 GrStencilFunc func = settings->func(face); | 1010 GrStencilFunc func = settings->func(face); |
| 1020 uint16_t writeMask = settings->writeMask(face); | 1011 uint16_t writeMask = settings->writeMask(face); |
| 1021 uint16_t funcMask = settings->funcMask(face); | 1012 uint16_t funcMask = settings->funcMask(face); |
| 1022 uint16_t funcRef = settings->funcRef(face); | 1013 uint16_t funcRef = settings->funcRef(face); |
| 1023 | 1014 |
| 1024 SkASSERT((unsigned) func < kStencilFuncCount); | 1015 SkASSERT((unsigned) func < kStencilFuncCnt); |
| 1025 | 1016 |
| 1026 writeMask &= userBits; | 1017 writeMask &= userBits; |
| 1027 | 1018 |
| 1028 if (func >= kBasicStencilFuncCount) { | 1019 if (func >= kBasicStencilFuncCnt) { |
| 1029 int respectClip = kRespectClip_StencilClipMode == mode; | 1020 int respectClip = kRespectClip_StencilClipMode == mode; |
| 1030 if (respectClip) { | 1021 if (respectClip) { |
| 1031 switch (func) { | 1022 switch (func) { |
| 1032 case kAlwaysIfInClip_StencilFunc: | 1023 case kAlwaysIfInClip_StencilFunc: |
| 1033 funcMask = clipBit; | 1024 funcMask = clipBit; |
| 1034 funcRef = clipBit; | 1025 funcRef = clipBit; |
| 1035 break; | 1026 break; |
| 1036 case kEqualIfInClip_StencilFunc: | 1027 case kEqualIfInClip_StencilFunc: |
| 1037 case kLessIfInClip_StencilFunc: | 1028 case kLessIfInClip_StencilFunc: |
| 1038 case kLEqualIfInClip_StencilFunc: | 1029 case kLEqualIfInClip_StencilFunc: |
| 1039 funcMask = (funcMask & userBits) | clipBit; | 1030 funcMask = (funcMask & userBits) | clipBit; |
| 1040 funcRef = (funcRef & userBits) | clipBit; | 1031 funcRef = (funcRef & userBits) | clipBit; |
| 1041 break; | 1032 break; |
| 1042 case kNonZeroIfInClip_StencilFunc: | 1033 case kNonZeroIfInClip_StencilFunc: |
| 1043 funcMask = (funcMask & userBits) | clipBit; | 1034 funcMask = (funcMask & userBits) | clipBit; |
| 1044 funcRef = clipBit; | 1035 funcRef = clipBit; |
| 1045 break; | 1036 break; |
| 1046 default: | 1037 default: |
| 1047 SkFAIL("Unknown stencil func"); | 1038 SkFAIL("Unknown stencil func"); |
| 1048 } | 1039 } |
| 1049 } else { | 1040 } else { |
| 1050 funcMask &= userBits; | 1041 funcMask &= userBits; |
| 1051 funcRef &= userBits; | 1042 funcRef &= userBits; |
| 1052 } | 1043 } |
| 1053 const GrStencilFunc* table = | 1044 const GrStencilFunc* table = |
| 1054 gSpecialToBasicStencilFunc[respectClip]; | 1045 gSpecialToBasicStencilFunc[respectClip]; |
| 1055 func = table[func - kBasicStencilFuncCount]; | 1046 func = table[func - kBasicStencilFuncCnt]; |
| 1056 SkASSERT(func >= 0 && func < kBasicStencilFuncCount); | 1047 SkASSERT(func >= 0 && func < kBasicStencilFuncCnt); |
| 1057 } else { | 1048 } else { |
| 1058 funcMask &= userBits; | 1049 funcMask &= userBits; |
| 1059 funcRef &= userBits; | 1050 funcRef &= userBits; |
| 1060 } | 1051 } |
| 1061 | 1052 |
| 1062 settings->setFunc(face, func); | 1053 settings->setFunc(face, func); |
| 1063 settings->setWriteMask(face, writeMask); | 1054 settings->setWriteMask(face, writeMask); |
| 1064 settings->setFuncMask(face, funcMask); | 1055 settings->setFuncMask(face, funcMask); |
| 1065 settings->setFuncRef(face, funcRef); | 1056 settings->setFuncRef(face, funcRef); |
| 1066 | 1057 |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1156 | 1147 |
| 1157 //////////////////////////////////////////////////////////////////////////////// | 1148 //////////////////////////////////////////////////////////////////////////////// |
| 1158 | 1149 |
| 1159 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc
ilAttachment, | 1150 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc
ilAttachment, |
| 1160 GrStencilSettings* settings) { | 1151 GrStencilSettings* settings) { |
| 1161 if (stencilAttachment) { | 1152 if (stencilAttachment) { |
| 1162 int stencilBits = stencilAttachment->bits(); | 1153 int stencilBits = stencilAttachment->bits(); |
| 1163 this->adjustStencilParams(settings, fClipMode, stencilBits); | 1154 this->adjustStencilParams(settings, fClipMode, stencilBits); |
| 1164 } | 1155 } |
| 1165 } | 1156 } |
| OLD | NEW |