| 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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 } else { | 78 } else { |
| 79 // We shouldn't get here with an empty clip element. | 79 // We shouldn't get here with an empty clip element. |
| 80 SkASSERT(Element::kEmpty_Type != element->getType()); | 80 SkASSERT(Element::kEmpty_Type != element->getType()); |
| 81 | 81 |
| 82 // the gpu alpha mask will draw the inverse paths as non-inverse to a te
mp buffer | 82 // the gpu alpha mask will draw the inverse paths as non-inverse to a te
mp buffer |
| 83 SkPath path; | 83 SkPath path; |
| 84 element->asPath(&path); | 84 element->asPath(&path); |
| 85 if (path.isInverseFillType()) { | 85 if (path.isInverseFillType()) { |
| 86 path.toggleInverseFillType(); | 86 path.toggleInverseFillType(); |
| 87 } | 87 } |
| 88 GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle); |
| 88 | 89 |
| 89 GrPathRendererChain::DrawType type; | 90 GrPathRendererChain::DrawType type; |
| 90 | 91 |
| 91 if (needsStencil) { | 92 if (needsStencil) { |
| 92 type = element->isAA() | 93 type = element->isAA() |
| 93 ? GrPathRendererChain::kStencilAndColorAntiAlias_Dra
wType | 94 ? GrPathRendererChain::kStencilAndColorAntiAlias_Dra
wType |
| 94 : GrPathRendererChain::kStencilAndColor_DrawType; | 95 : GrPathRendererChain::kStencilAndColor_DrawType; |
| 95 } else { | 96 } else { |
| 96 type = element->isAA() | 97 type = element->isAA() |
| 97 ? GrPathRendererChain::kColorAntiAlias_DrawType | 98 ? GrPathRendererChain::kColorAntiAlias_DrawType |
| 98 : GrPathRendererChain::kColor_DrawType; | 99 : GrPathRendererChain::kColor_DrawType; |
| 99 } | 100 } |
| 100 | 101 |
| 101 GrPathRenderer::CanDrawPathArgs canDrawArgs; | 102 GrPathRenderer::CanDrawPathArgs canDrawArgs; |
| 102 canDrawArgs.fShaderCaps = context->caps()->shaderCaps(); | 103 canDrawArgs.fShaderCaps = context->caps()->shaderCaps(); |
| 103 canDrawArgs.fViewMatrix = &viewMatrix; | 104 canDrawArgs.fViewMatrix = &viewMatrix; |
| 104 canDrawArgs.fPath = &path; | 105 canDrawArgs.fPath = &path; |
| 105 canDrawArgs.fStyle = &GrStyle::SimpleFill(); | 106 canDrawArgs.fStroke = &stroke; |
| 106 canDrawArgs.fAntiAlias = element->isAA(); | 107 canDrawArgs.fAntiAlias = element->isAA(); |
| 107 canDrawArgs.fIsStencilDisabled = isStencilDisabled; | 108 canDrawArgs.fIsStencilDisabled = isStencilDisabled; |
| 108 canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampled(); | 109 canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampled(); |
| 109 | 110 |
| 110 // the 'false' parameter disallows use of the SW path renderer | 111 // the 'false' parameter disallows use of the SW path renderer |
| 111 GrPathRenderer* pr = context->drawingManager()->getPathRenderer(canDrawA
rgs, false, type); | 112 GrPathRenderer* pr = context->drawingManager()->getPathRenderer(canDrawA
rgs, false, type); |
| 112 if (prOut) { | 113 if (prOut) { |
| 113 *prOut = pr; | 114 *prOut = pr; |
| 114 } | 115 } |
| 115 return SkToBool(!pr); | 116 return SkToBool(!pr); |
| (...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 583 case Element::kRect_Type: | 584 case Element::kRect_Type: |
| 584 dc->drawRect(clip, paint, viewMatrix, element->getRect()); | 585 dc->drawRect(clip, paint, viewMatrix, element->getRect()); |
| 585 break; | 586 break; |
| 586 default: { | 587 default: { |
| 587 SkPath path; | 588 SkPath path; |
| 588 element->asPath(&path); | 589 element->asPath(&path); |
| 589 if (path.isInverseFillType()) { | 590 if (path.isInverseFillType()) { |
| 590 path.toggleInverseFillType(); | 591 path.toggleInverseFillType(); |
| 591 } | 592 } |
| 592 | 593 |
| 593 dc->drawPath(clip, paint, viewMatrix, path, GrStyle::SimpleFill()); | 594 dc->drawPath(clip, paint, viewMatrix, path, GrStrokeInfo::FillInfo()
); |
| 594 break; | 595 break; |
| 595 } | 596 } |
| 596 } | 597 } |
| 597 } | 598 } |
| 598 | 599 |
| 599 //////////////////////////////////////////////////////////////////////////////// | 600 //////////////////////////////////////////////////////////////////////////////// |
| 600 // Create a 8-bit clip mask in alpha | 601 // Create a 8-bit clip mask in alpha |
| 601 | 602 |
| 602 static void GetClipMaskKey(int32_t clipGenID, const SkIRect& bounds, GrUniqueKey
* key) { | 603 static void GetClipMaskKey(int32_t clipGenID, const SkIRect& bounds, GrUniqueKey
* key) { |
| 603 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); | 604 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 777 } | 778 } |
| 778 | 779 |
| 779 bool fillInverted = false; | 780 bool fillInverted = false; |
| 780 // enabled at bottom of loop | 781 // enabled at bottom of loop |
| 781 fClipMode = kIgnoreClip_StencilClipMode; | 782 fClipMode = kIgnoreClip_StencilClipMode; |
| 782 | 783 |
| 783 // This will be used to determine whether the clip shape can be rend
ered into the | 784 // This will be used to determine whether the clip shape can be rend
ered into the |
| 784 // stencil with arbitrary stencil settings. | 785 // stencil with arbitrary stencil settings. |
| 785 GrPathRenderer::StencilSupport stencilSupport; | 786 GrPathRenderer::StencilSupport stencilSupport; |
| 786 | 787 |
| 788 GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle); |
| 787 SkRegion::Op op = element->getOp(); | 789 SkRegion::Op op = element->getOp(); |
| 788 | 790 |
| 789 GrPathRenderer* pr = nullptr; | 791 GrPathRenderer* pr = nullptr; |
| 790 SkPath clipPath; | 792 SkPath clipPath; |
| 791 if (Element::kRect_Type == element->getType()) { | 793 if (Element::kRect_Type == element->getType()) { |
| 792 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; | 794 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; |
| 793 fillInverted = false; | 795 fillInverted = false; |
| 794 } else { | 796 } else { |
| 795 element->asPath(&clipPath); | 797 element->asPath(&clipPath); |
| 796 fillInverted = clipPath.isInverseFillType(); | 798 fillInverted = clipPath.isInverseFillType(); |
| 797 if (fillInverted) { | 799 if (fillInverted) { |
| 798 clipPath.toggleInverseFillType(); | 800 clipPath.toggleInverseFillType(); |
| 799 } | 801 } |
| 800 | 802 |
| 801 SkASSERT(pipelineBuilder.getStencil().isDisabled()); | 803 SkASSERT(pipelineBuilder.getStencil().isDisabled()); |
| 802 | 804 |
| 803 GrPathRenderer::CanDrawPathArgs canDrawArgs; | 805 GrPathRenderer::CanDrawPathArgs canDrawArgs; |
| 804 canDrawArgs.fShaderCaps = this->getContext()->caps()->shaderCaps
(); | 806 canDrawArgs.fShaderCaps = this->getContext()->caps()->shaderCaps
(); |
| 805 canDrawArgs.fViewMatrix = &viewMatrix; | 807 canDrawArgs.fViewMatrix = &viewMatrix; |
| 806 canDrawArgs.fPath = &clipPath; | 808 canDrawArgs.fPath = &clipPath; |
| 807 canDrawArgs.fStyle = &GrStyle::SimpleFill(); | 809 canDrawArgs.fStroke = &stroke; |
| 808 canDrawArgs.fAntiAlias = false; | 810 canDrawArgs.fAntiAlias = false; |
| 809 canDrawArgs.fIsStencilDisabled = pipelineBuilder.getStencil().is
Disabled(); | 811 canDrawArgs.fIsStencilDisabled = pipelineBuilder.getStencil().is
Disabled(); |
| 810 canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampl
ed(); | 812 canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampl
ed(); |
| 811 | 813 |
| 812 pr = this->getContext()->drawingManager()->getPathRenderer(canDr
awArgs, false, | 814 pr = this->getContext()->drawingManager()->getPathRenderer(canDr
awArgs, false, |
| 813 GrPat
hRendererChain::kStencilOnly_DrawType, | 815 GrPat
hRendererChain::kStencilOnly_DrawType, |
| 814 &sten
cilSupport); | 816 &sten
cilSupport); |
| 815 if (nullptr == pr) { | 817 if (nullptr == pr) { |
| 816 return false; | 818 return false; |
| 817 } | 819 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 852 if (canRenderDirectToStencil) { | 854 if (canRenderDirectToStencil) { |
| 853 *pipelineBuilder.stencil() = kDrawToStencil; | 855 *pipelineBuilder.stencil() = kDrawToStencil; |
| 854 | 856 |
| 855 GrPathRenderer::DrawPathArgs args; | 857 GrPathRenderer::DrawPathArgs args; |
| 856 args.fTarget = fDrawTarget; | 858 args.fTarget = fDrawTarget; |
| 857 args.fResourceProvider = this->getContext()->resourc
eProvider(); | 859 args.fResourceProvider = this->getContext()->resourc
eProvider(); |
| 858 args.fPipelineBuilder = &pipelineBuilder; | 860 args.fPipelineBuilder = &pipelineBuilder; |
| 859 args.fColor = GrColor_WHITE; | 861 args.fColor = GrColor_WHITE; |
| 860 args.fViewMatrix = &viewMatrix; | 862 args.fViewMatrix = &viewMatrix; |
| 861 args.fPath = &clipPath; | 863 args.fPath = &clipPath; |
| 862 args.fStyle = &GrStyle::SimpleFill(); | 864 args.fStroke = &stroke; |
| 863 args.fAntiAlias = false; | 865 args.fAntiAlias = false; |
| 864 args.fGammaCorrect = false; | 866 args.fGammaCorrect = false; |
| 865 pr->drawPath(args); | 867 pr->drawPath(args); |
| 866 } else { | 868 } else { |
| 867 GrPathRenderer::StencilPathArgs args; | 869 GrPathRenderer::StencilPathArgs args; |
| 868 args.fTarget = fDrawTarget; | 870 args.fTarget = fDrawTarget; |
| 869 args.fResourceProvider = this->getContext()->resourc
eProvider(); | 871 args.fResourceProvider = this->getContext()->resourc
eProvider(); |
| 870 args.fPipelineBuilder = &pipelineBuilder; | 872 args.fPipelineBuilder = &pipelineBuilder; |
| 871 args.fViewMatrix = &viewMatrix; | 873 args.fViewMatrix = &viewMatrix; |
| 872 args.fPath = &clipPath; | 874 args.fPath = &clipPath; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 887 draw_non_aa_rect(fDrawTarget, pipelineBuilder, GrColor_W
HITE, viewMatrix, | 889 draw_non_aa_rect(fDrawTarget, pipelineBuilder, GrColor_W
HITE, viewMatrix, |
| 888 element->getRect()); | 890 element->getRect()); |
| 889 } else { | 891 } else { |
| 890 GrPathRenderer::DrawPathArgs args; | 892 GrPathRenderer::DrawPathArgs args; |
| 891 args.fTarget = fDrawTarget; | 893 args.fTarget = fDrawTarget; |
| 892 args.fResourceProvider = this->getContext()->resourcePro
vider(); | 894 args.fResourceProvider = this->getContext()->resourcePro
vider(); |
| 893 args.fPipelineBuilder = &pipelineBuilder; | 895 args.fPipelineBuilder = &pipelineBuilder; |
| 894 args.fColor = GrColor_WHITE; | 896 args.fColor = GrColor_WHITE; |
| 895 args.fViewMatrix = &viewMatrix; | 897 args.fViewMatrix = &viewMatrix; |
| 896 args.fPath = &clipPath; | 898 args.fPath = &clipPath; |
| 897 args.fStyle = &GrStyle::SimpleFill(); | 899 args.fStroke = &stroke; |
| 898 args.fAntiAlias = false; | 900 args.fAntiAlias = false; |
| 899 args.fGammaCorrect = false; | 901 args.fGammaCorrect = false; |
| 900 pr->drawPath(args); | 902 pr->drawPath(args); |
| 901 } | 903 } |
| 902 } else { | 904 } else { |
| 903 // The view matrix is setup to do clip space -> stencil spac
e translation, so | 905 // The view matrix is setup to do clip space -> stencil spac
e translation, so |
| 904 // draw rect in clip space. | 906 // draw rect in clip space. |
| 905 draw_non_aa_rect(fDrawTarget, pipelineBuilder, GrColor_WHITE
, viewMatrix, | 907 draw_non_aa_rect(fDrawTarget, pipelineBuilder, GrColor_WHITE
, viewMatrix, |
| 906 SkRect::Make(clipSpaceIBounds)); | 908 SkRect::Make(clipSpaceIBounds)); |
| 907 } | 909 } |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1091 | 1093 |
| 1092 GrSWMaskHelper helper(context); | 1094 GrSWMaskHelper helper(context); |
| 1093 | 1095 |
| 1094 // Set the matrix so that rendered clip elements are transformed to mask spa
ce from clip | 1096 // Set the matrix so that rendered clip elements are transformed to mask spa
ce from clip |
| 1095 // space. | 1097 // space. |
| 1096 SkMatrix translate; | 1098 SkMatrix translate; |
| 1097 translate.setTranslate(clipToMaskOffset); | 1099 translate.setTranslate(clipToMaskOffset); |
| 1098 | 1100 |
| 1099 helper.init(maskSpaceIBounds, &translate, false); | 1101 helper.init(maskSpaceIBounds, &translate, false); |
| 1100 helper.clear(GrReducedClip::kAllIn_InitialState == initialState ? 0xFF : 0x0
0); | 1102 helper.clear(GrReducedClip::kAllIn_InitialState == initialState ? 0xFF : 0x0
0); |
| 1103 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); |
| 1101 | 1104 |
| 1102 for (GrReducedClip::ElementList::Iter iter(elements.headIter()) ; iter.get()
; iter.next()) { | 1105 for (GrReducedClip::ElementList::Iter iter(elements.headIter()) ; iter.get()
; iter.next()) { |
| 1103 const Element* element = iter.get(); | 1106 const Element* element = iter.get(); |
| 1104 SkRegion::Op op = element->getOp(); | 1107 SkRegion::Op op = element->getOp(); |
| 1105 | 1108 |
| 1106 if (SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op ==
op) { | 1109 if (SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op ==
op) { |
| 1107 // Intersect and reverse difference require modifying pixels outside
of the geometry | 1110 // Intersect and reverse difference require modifying pixels outside
of the geometry |
| 1108 // that is being "drawn". In both cases we erase all the pixels outs
ide of the geometry | 1111 // that is being "drawn". In both cases we erase all the pixels outs
ide of the geometry |
| 1109 // but leave the pixels inside the geometry alone. For reverse diffe
rence we invert all | 1112 // but leave the pixels inside the geometry alone. For reverse diffe
rence we invert all |
| 1110 // the pixels before clearing the ones outside the geometry. | 1113 // the pixels before clearing the ones outside the geometry. |
| 1111 if (SkRegion::kReverseDifference_Op == op) { | 1114 if (SkRegion::kReverseDifference_Op == op) { |
| 1112 SkRect temp = SkRect::Make(clipSpaceIBounds); | 1115 SkRect temp = SkRect::Make(clipSpaceIBounds); |
| 1113 // invert the entire scene | 1116 // invert the entire scene |
| 1114 helper.draw(temp, SkRegion::kXOR_Op, false, 0xFF); | 1117 helper.draw(temp, SkRegion::kXOR_Op, false, 0xFF); |
| 1115 } | 1118 } |
| 1116 SkPath clipPath; | 1119 SkPath clipPath; |
| 1117 element->asPath(&clipPath); | 1120 element->asPath(&clipPath); |
| 1118 clipPath.toggleInverseFillType(); | 1121 clipPath.toggleInverseFillType(); |
| 1119 helper.draw(clipPath, GrStyle::SimpleFill(), SkRegion::kReplace_Op,
element->isAA(), | 1122 helper.draw(clipPath, stroke, SkRegion::kReplace_Op, element->isAA()
, 0x00); |
| 1120 0x00); | |
| 1121 continue; | 1123 continue; |
| 1122 } | 1124 } |
| 1123 | 1125 |
| 1124 // The other ops (union, xor, diff) only affect pixels inside | 1126 // The other ops (union, xor, diff) only affect pixels inside |
| 1125 // the geometry so they can just be drawn normally | 1127 // the geometry so they can just be drawn normally |
| 1126 if (Element::kRect_Type == element->getType()) { | 1128 if (Element::kRect_Type == element->getType()) { |
| 1127 helper.draw(element->getRect(), op, element->isAA(), 0xFF); | 1129 helper.draw(element->getRect(), op, element->isAA(), 0xFF); |
| 1128 } else { | 1130 } else { |
| 1129 SkPath path; | 1131 SkPath path; |
| 1130 element->asPath(&path); | 1132 element->asPath(&path); |
| 1131 helper.draw(path, GrStyle::SimpleFill(), op, element->isAA(), 0xFF); | 1133 helper.draw(path, stroke, op, element->isAA(), 0xFF); |
| 1132 } | 1134 } |
| 1133 } | 1135 } |
| 1134 | 1136 |
| 1135 // Allocate clip mask texture | 1137 // Allocate clip mask texture |
| 1136 GrSurfaceDesc desc; | 1138 GrSurfaceDesc desc; |
| 1137 desc.fWidth = clipSpaceIBounds.width(); | 1139 desc.fWidth = clipSpaceIBounds.width(); |
| 1138 desc.fHeight = clipSpaceIBounds.height(); | 1140 desc.fHeight = clipSpaceIBounds.height(); |
| 1139 desc.fConfig = kAlpha_8_GrPixelConfig; | 1141 desc.fConfig = kAlpha_8_GrPixelConfig; |
| 1140 | 1142 |
| 1141 GrTexture* result = context->resourceProvider()->createApproxTexture(desc, 0
); | 1143 GrTexture* result = context->resourceProvider()->createApproxTexture(desc, 0
); |
| 1142 if (!result) { | 1144 if (!result) { |
| 1143 return nullptr; | 1145 return nullptr; |
| 1144 } | 1146 } |
| 1145 result->resourcePriv().setUniqueKey(key); | 1147 result->resourcePriv().setUniqueKey(key); |
| 1146 | 1148 |
| 1147 helper.toTexture(result); | 1149 helper.toTexture(result); |
| 1148 | 1150 |
| 1149 return result; | 1151 return result; |
| 1150 } | 1152 } |
| 1151 | 1153 |
| 1152 //////////////////////////////////////////////////////////////////////////////// | 1154 //////////////////////////////////////////////////////////////////////////////// |
| 1153 | 1155 |
| 1154 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc
ilAttachment, | 1156 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc
ilAttachment, |
| 1155 GrStencilSettings* settings) { | 1157 GrStencilSettings* settings) { |
| 1156 if (stencilAttachment) { | 1158 if (stencilAttachment) { |
| 1157 int stencilBits = stencilAttachment->bits(); | 1159 int stencilBits = stencilAttachment->bits(); |
| 1158 this->adjustStencilParams(settings, fClipMode, stencilBits); | 1160 this->adjustStencilParams(settings, fClipMode, stencilBits); |
| 1159 } | 1161 } |
| 1160 } | 1162 } |
| OLD | NEW |