| 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" |
| 11 #include "GrDrawContextPriv.h" | 11 #include "GrDrawContextPriv.h" |
| 12 #include "GrDrawTarget.h" | 12 #include "GrDrawTarget.h" |
| 13 #include "GrGpuResourcePriv.h" | 13 #include "GrGpuResourcePriv.h" |
| 14 #include "GrPaint.h" | 14 #include "GrPaint.h" |
| 15 #include "GrPathRenderer.h" | 15 #include "GrPathRenderer.h" |
| 16 #include "GrRenderTarget.h" | 16 #include "GrRenderTarget.h" |
| 17 #include "GrRenderTargetPriv.h" | 17 #include "GrRenderTargetPriv.h" |
| 18 #include "GrResourceProvider.h" | 18 #include "GrResourceProvider.h" |
| 19 #include "GrInstancedRendering.h" |
| 19 #include "GrStencilAttachment.h" | 20 #include "GrStencilAttachment.h" |
| 20 #include "GrSWMaskHelper.h" | 21 #include "GrSWMaskHelper.h" |
| 21 #include "SkRasterClip.h" | 22 #include "SkRasterClip.h" |
| 22 #include "SkTLazy.h" | 23 #include "SkTLazy.h" |
| 23 #include "batches/GrRectBatchFactory.h" | 24 #include "batches/GrRectBatchFactory.h" |
| 24 #include "effects/GrConvexPolyEffect.h" | 25 #include "effects/GrConvexPolyEffect.h" |
| 25 #include "effects/GrPorterDuffXferProcessor.h" | 26 #include "effects/GrPorterDuffXferProcessor.h" |
| 26 #include "effects/GrRRectEffect.h" | 27 #include "effects/GrRRectEffect.h" |
| 27 #include "effects/GrTextureDomain.h" | 28 #include "effects/GrTextureDomain.h" |
| 28 | 29 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 41 | 42 |
| 42 SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height()); | 43 SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height()); |
| 43 return GrTextureDomainEffect::Create(result, | 44 return GrTextureDomainEffect::Create(result, |
| 44 mat, | 45 mat, |
| 45 GrTextureDomain::MakeTexelDomain(result
, domainTexels), | 46 GrTextureDomain::MakeTexelDomain(result
, domainTexels), |
| 46 GrTextureDomain::kDecal_Mode, | 47 GrTextureDomain::kDecal_Mode, |
| 47 GrTextureParams::kNone_FilterMode, | 48 GrTextureParams::kNone_FilterMode, |
| 48 kDevice_GrCoordSet); | 49 kDevice_GrCoordSet); |
| 49 } | 50 } |
| 50 | 51 |
| 51 static void draw_non_aa_rect(GrDrawTarget* drawTarget, | |
| 52 const GrPipelineBuilder& pipelineBuilder, | |
| 53 GrColor color, | |
| 54 const SkMatrix& viewMatrix, | |
| 55 const SkRect& rect) { | |
| 56 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(color, v
iewMatrix, rect, | |
| 57 nullptr,
nullptr)); | |
| 58 drawTarget->drawBatch(pipelineBuilder, batch); | |
| 59 } | |
| 60 | |
| 61 // Does the path in 'element' require SW rendering? If so, return true (and, | 52 // Does the path in 'element' require SW rendering? If so, return true (and, |
| 62 // optionally, set 'prOut' to NULL. If not, return false (and, optionally, set | 53 // optionally, set 'prOut' to NULL. If not, return false (and, optionally, set |
| 63 // 'prOut' to the non-SW path renderer that will do the job). | 54 // 'prOut' to the non-SW path renderer that will do the job). |
| 64 bool GrClipMaskManager::PathNeedsSWRenderer(GrContext* context, | 55 bool GrClipMaskManager::PathNeedsSWRenderer(GrContext* context, |
| 65 bool isStencilDisabled, | 56 bool isStencilDisabled, |
| 66 const GrRenderTarget* rt, | 57 const GrRenderTarget* rt, |
| 67 const SkMatrix& viewMatrix, | 58 const SkMatrix& viewMatrix, |
| 68 const Element* element, | 59 const Element* element, |
| 69 GrPathRenderer** prOut, | 60 GrPathRenderer** prOut, |
| 70 bool needsStencil) { | 61 bool needsStencil) { |
| (...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 747 stencilSpaceIBounds.offset(clipSpaceToStencilOffset); | 738 stencilSpaceIBounds.offset(clipSpaceToStencilOffset); |
| 748 GrClip clip(stencilSpaceIBounds); | 739 GrClip clip(stencilSpaceIBounds); |
| 749 | 740 |
| 750 int clipBit = stencilAttachment->bits(); | 741 int clipBit = stencilAttachment->bits(); |
| 751 SkASSERT((clipBit <= 16) && "Ganesh only handles 16b or smaller stencil
buffers"); | 742 SkASSERT((clipBit <= 16) && "Ganesh only handles 16b or smaller stencil
buffers"); |
| 752 clipBit = (1 << (clipBit-1)); | 743 clipBit = (1 << (clipBit-1)); |
| 753 | 744 |
| 754 fDrawTarget->cmmAccess().clearStencilClip(stencilSpaceIBounds, | 745 fDrawTarget->cmmAccess().clearStencilClip(stencilSpaceIBounds, |
| 755 GrReducedClip::kAllIn_InitialState == initialState, rt); | 746 GrReducedClip::kAllIn_InitialState == initialState, rt); |
| 756 | 747 |
| 748 GrInstancedRendering* instRendering = fDrawTarget->instancedRendering(); |
| 749 uint32_t instRenderingFlags; |
| 750 if (instRendering) { |
| 751 instRenderingFlags = GrInstancedRendering::kStencilWrite_Flag | |
| 752 GrInstancedRendering::kUseDiscard_Flag; |
| 753 if (rt->isStencilBufferMultisampled()) { |
| 754 instRenderingFlags |= GrInstancedRendering::kStencilBufferMSAA_F
lag; |
| 755 } |
| 756 } |
| 757 |
| 757 // walk through each clip element and perform its set op | 758 // walk through each clip element and perform its set op |
| 758 // with the existing clip. | 759 // with the existing clip. |
| 759 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.ge
t(); iter.next()) { | 760 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.ge
t(); iter.next()) { |
| 760 const Element* element = iter.get(); | 761 const Element* element = iter.get(); |
| 761 | 762 |
| 762 GrPipelineBuilder pipelineBuilder; | 763 GrPipelineBuilder pipelineBuilder; |
| 763 pipelineBuilder.setClip(clip); | 764 pipelineBuilder.setClip(clip); |
| 764 pipelineBuilder.setRenderTarget(rt); | 765 pipelineBuilder.setRenderTarget(rt); |
| 765 | 766 |
| 766 pipelineBuilder.setDisableColorXPFactory(); | 767 pipelineBuilder.setDisableColorXPFactory(); |
| 767 | 768 |
| 768 // if the target is MSAA then we want MSAA enabled when the clip is
soft | 769 // if the target is MSAA then we want MSAA enabled when the clip is
soft |
| 769 if (rt->isStencilBufferMultisampled()) { | 770 if (rt->isStencilBufferMultisampled()) { |
| 770 pipelineBuilder.setState(GrPipelineBuilder::kHWAntialias_Flag, e
lement->isAA()); | 771 pipelineBuilder.setState(GrPipelineBuilder::kHWAntialias_Flag, e
lement->isAA()); |
| 771 } | 772 } |
| 772 | 773 |
| 773 bool fillInverted = false; | 774 bool fillInverted = false; |
| 774 // enabled at bottom of loop | 775 // enabled at bottom of loop |
| 775 fClipMode = kIgnoreClip_StencilClipMode; | 776 fClipMode = kIgnoreClip_StencilClipMode; |
| 776 | 777 |
| 777 // This will be used to determine whether the clip shape can be rend
ered into the | 778 // This will be used to determine whether the clip shape can be rend
ered into the |
| 778 // stencil with arbitrary stencil settings. | 779 // stencil with arbitrary stencil settings. |
| 779 GrPathRenderer::StencilSupport stencilSupport; | 780 GrPathRenderer::StencilSupport stencilSupport; |
| 780 | 781 |
| 781 GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle); | 782 GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle); |
| 782 SkRegion::Op op = element->getOp(); | 783 SkRegion::Op op = element->getOp(); |
| 783 | 784 |
| 785 SkAutoTUnref<GrDrawBatch> fastBatch; |
| 786 if (Element::kPath_Type != element->getType()) { |
| 787 if (instRendering) { |
| 788 bool useHWAA; |
| 789 fastBatch.reset(instRendering->recordRRect(element->asRRect(
), viewMatrix, |
| 790 GrColor_WHITE, |
| 791 pipelineBuilder.i
sHWAntialias(), |
| 792 instRenderingFlag
s, &useHWAA)); |
| 793 SkASSERT(!fastBatch || pipelineBuilder.isHWAntialias() == us
eHWAA); |
| 794 } |
| 795 |
| 796 if (!fastBatch && Element::kRect_Type == element->getType()) { |
| 797 fastBatch.reset(GrRectBatchFactory::CreateNonAAFill(GrColor_
WHITE, viewMatrix, |
| 798 element-
>getRect(), nullptr, |
| 799 nullptr)
); |
| 800 } |
| 801 } |
| 802 |
| 784 GrPathRenderer* pr = nullptr; | 803 GrPathRenderer* pr = nullptr; |
| 785 SkPath clipPath; | 804 SkPath clipPath; |
| 786 if (Element::kRect_Type == element->getType()) { | 805 if (fastBatch) { |
| 787 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; | 806 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; |
| 788 fillInverted = false; | 807 fillInverted = false; |
| 789 } else { | 808 } else { |
| 790 element->asPath(&clipPath); | 809 element->asPath(&clipPath); |
| 791 fillInverted = clipPath.isInverseFillType(); | 810 fillInverted = clipPath.isInverseFillType(); |
| 792 if (fillInverted) { | 811 if (fillInverted) { |
| 793 clipPath.toggleInverseFillType(); | 812 clipPath.toggleInverseFillType(); |
| 794 } | 813 } |
| 795 | 814 |
| 796 SkASSERT(pipelineBuilder.getStencil().isDisabled()); | 815 SkASSERT(pipelineBuilder.getStencil().isDisabled()); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 830 | 849 |
| 831 // draw the element to the client stencil bits if necessary | 850 // draw the element to the client stencil bits if necessary |
| 832 if (!canDrawDirectToClip) { | 851 if (!canDrawDirectToClip) { |
| 833 GR_STATIC_CONST_SAME_STENCIL(gDrawToStencil, | 852 GR_STATIC_CONST_SAME_STENCIL(gDrawToStencil, |
| 834 kIncClamp_StencilOp, | 853 kIncClamp_StencilOp, |
| 835 kIncClamp_StencilOp, | 854 kIncClamp_StencilOp, |
| 836 kAlways_StencilFunc, | 855 kAlways_StencilFunc, |
| 837 0xffff, | 856 0xffff, |
| 838 0x0000, | 857 0x0000, |
| 839 0xffff); | 858 0xffff); |
| 840 if (Element::kRect_Type == element->getType()) { | 859 if (fastBatch) { |
| 841 *pipelineBuilder.stencil() = gDrawToStencil; | 860 *pipelineBuilder.stencil() = gDrawToStencil; |
| 842 | 861 fDrawTarget->drawBatch(pipelineBuilder, fastBatch); |
| 843 draw_non_aa_rect(fDrawTarget, pipelineBuilder, GrColor_WHITE
, viewMatrix, | |
| 844 element->getRect()); | |
| 845 } else { | 862 } else { |
| 846 if (!clipPath.isEmpty()) { | 863 if (!clipPath.isEmpty()) { |
| 847 if (canRenderDirectToStencil) { | 864 if (canRenderDirectToStencil) { |
| 848 *pipelineBuilder.stencil() = gDrawToStencil; | 865 *pipelineBuilder.stencil() = gDrawToStencil; |
| 849 | 866 |
| 850 GrPathRenderer::DrawPathArgs args; | 867 GrPathRenderer::DrawPathArgs args; |
| 851 args.fTarget = fDrawTarget; | 868 args.fTarget = fDrawTarget; |
| 852 args.fResourceProvider = this->getContext()->resourc
eProvider(); | 869 args.fResourceProvider = this->getContext()->resourc
eProvider(); |
| 853 args.fPipelineBuilder = &pipelineBuilder; | 870 args.fPipelineBuilder = &pipelineBuilder; |
| 854 args.fColor = GrColor_WHITE; | 871 args.fColor = GrColor_WHITE; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 872 } | 889 } |
| 873 } | 890 } |
| 874 | 891 |
| 875 // now we modify the clip bit by rendering either the clip | 892 // now we modify the clip bit by rendering either the clip |
| 876 // element directly or a bounding rect of the entire clip. | 893 // element directly or a bounding rect of the entire clip. |
| 877 fClipMode = kModifyClip_StencilClipMode; | 894 fClipMode = kModifyClip_StencilClipMode; |
| 878 for (int p = 0; p < passes; ++p) { | 895 for (int p = 0; p < passes; ++p) { |
| 879 *pipelineBuilder.stencil() = stencilSettings[p]; | 896 *pipelineBuilder.stencil() = stencilSettings[p]; |
| 880 | 897 |
| 881 if (canDrawDirectToClip) { | 898 if (canDrawDirectToClip) { |
| 882 if (Element::kRect_Type == element->getType()) { | 899 if (fastBatch) { |
| 883 draw_non_aa_rect(fDrawTarget, pipelineBuilder, GrColor_W
HITE, viewMatrix, | 900 fDrawTarget->drawBatch(pipelineBuilder, fastBatch); |
| 884 element->getRect()); | |
| 885 } else { | 901 } else { |
| 886 GrPathRenderer::DrawPathArgs args; | 902 GrPathRenderer::DrawPathArgs args; |
| 887 args.fTarget = fDrawTarget; | 903 args.fTarget = fDrawTarget; |
| 888 args.fResourceProvider = this->getContext()->resourcePro
vider(); | 904 args.fResourceProvider = this->getContext()->resourcePro
vider(); |
| 889 args.fPipelineBuilder = &pipelineBuilder; | 905 args.fPipelineBuilder = &pipelineBuilder; |
| 890 args.fColor = GrColor_WHITE; | 906 args.fColor = GrColor_WHITE; |
| 891 args.fViewMatrix = &viewMatrix; | 907 args.fViewMatrix = &viewMatrix; |
| 892 args.fPath = &clipPath; | 908 args.fPath = &clipPath; |
| 893 args.fStroke = &stroke; | 909 args.fStroke = &stroke; |
| 894 args.fAntiAlias = false; | 910 args.fAntiAlias = false; |
| 895 args.fGammaCorrect = false; | 911 args.fGammaCorrect = false; |
| 896 pr->drawPath(args); | 912 pr->drawPath(args); |
| 897 } | 913 } |
| 898 } else { | 914 } else { |
| 899 // The view matrix is setup to do clip space -> stencil spac
e translation, so | 915 // The view matrix is setup to do clip space -> stencil spac
e translation, so |
| 900 // draw rect in clip space. | 916 // draw rect in clip space. |
| 901 draw_non_aa_rect(fDrawTarget, pipelineBuilder, GrColor_WHITE
, viewMatrix, | 917 const SkRect& clipSpaceRect = SkRect::Make(clipSpaceIBounds)
; |
| 902 SkRect::Make(clipSpaceIBounds)); | 918 SkAutoTUnref<GrDrawBatch> coverBatch; |
| 919 if (instRendering) { |
| 920 bool useHWAA; |
| 921 coverBatch.reset(instRendering->recordRect(clipSpaceRect
, viewMatrix, |
| 922 GrColor_WHITE
, |
| 923 pipelineBuild
er.isHWAntialias(), |
| 924 instRendering
Flags, &useHWAA)); |
| 925 SkASSERT(!fastBatch || pipelineBuilder.isHWAntialias() =
= useHWAA); |
| 926 } |
| 927 if (!coverBatch) { |
| 928 coverBatch.reset(GrRectBatchFactory::CreateNonAAFill(GrC
olor_WHITE, |
| 929 vie
wMatrix, |
| 930 cli
pSpaceRect, |
| 931 nul
lptr, nullptr)); |
| 932 } |
| 933 fDrawTarget->drawBatch(pipelineBuilder, coverBatch); |
| 903 } | 934 } |
| 904 } | 935 } |
| 905 } | 936 } |
| 906 } | 937 } |
| 907 fClipMode = kRespectClip_StencilClipMode; | 938 fClipMode = kRespectClip_StencilClipMode; |
| 908 return true; | 939 return true; |
| 909 } | 940 } |
| 910 | 941 |
| 911 // mapping of clip-respecting stencil funcs to normal stencil funcs | 942 // mapping of clip-respecting stencil funcs to normal stencil funcs |
| 912 // mapping depends on whether stencil-clipping is in effect. | 943 // mapping depends on whether stencil-clipping is in effect. |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1156 | 1187 |
| 1157 //////////////////////////////////////////////////////////////////////////////// | 1188 //////////////////////////////////////////////////////////////////////////////// |
| 1158 | 1189 |
| 1159 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc
ilAttachment, | 1190 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc
ilAttachment, |
| 1160 GrStencilSettings* settings) { | 1191 GrStencilSettings* settings) { |
| 1161 if (stencilAttachment) { | 1192 if (stencilAttachment) { |
| 1162 int stencilBits = stencilAttachment->bits(); | 1193 int stencilBits = stencilAttachment->bits(); |
| 1163 this->adjustStencilParams(settings, fClipMode, stencilBits); | 1194 this->adjustStencilParams(settings, fClipMode, stencilBits); |
| 1164 } | 1195 } |
| 1165 } | 1196 } |
| OLD | NEW |