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 |