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 "GrAAConvexPathRenderer.h" | 9 #include "GrAAConvexPathRenderer.h" |
10 #include "GrAAHairLinePathRenderer.h" | 10 #include "GrAAHairLinePathRenderer.h" |
(...skipping 12 matching lines...) Expand all Loading... |
23 #include "effects/GrPorterDuffXferProcessor.h" | 23 #include "effects/GrPorterDuffXferProcessor.h" |
24 #include "effects/GrRRectEffect.h" | 24 #include "effects/GrRRectEffect.h" |
25 #include "effects/GrTextureDomain.h" | 25 #include "effects/GrTextureDomain.h" |
26 | 26 |
27 typedef SkClipStack::Element Element; | 27 typedef SkClipStack::Element Element; |
28 | 28 |
29 //////////////////////////////////////////////////////////////////////////////// | 29 //////////////////////////////////////////////////////////////////////////////// |
30 namespace { | 30 namespace { |
31 // set up the draw state to enable the aa clipping mask. Besides setting up the | 31 // set up the draw state to enable the aa clipping mask. Besides setting up the |
32 // stage matrix this also alters the vertex layout | 32 // stage matrix this also alters the vertex layout |
33 void setup_drawstate_aaclip(GrPipelineBuilder* pipelineBuilder, | 33 void setup_drawstate_aaclip(const GrPipelineBuilder& pipelineBuilder, |
34 GrTexture* result, | 34 GrTexture* result, |
35 GrPipelineBuilder::AutoRestoreFragmentProcessors* ar
fp, | 35 GrPipelineBuilder::AutoRestoreFragmentProcessors* ar
fp, |
| 36 GrPipelineBuilder::AutoRestoreProcessorDataManager*
arpdm, |
36 const SkIRect &devBound) { | 37 const SkIRect &devBound) { |
37 SkASSERT(pipelineBuilder && arfp); | 38 SkASSERT(arfp && arpdm); |
38 arfp->set(pipelineBuilder); | 39 arfp->set(&pipelineBuilder); |
| 40 arpdm->set(&pipelineBuilder); |
39 | 41 |
40 SkMatrix mat; | 42 SkMatrix mat; |
41 // We use device coords to compute the texture coordinates. We set our matri
x to be a | 43 // We use device coords to compute the texture coordinates. We set our matri
x to be a |
42 // translation to the devBound, and then a scaling matrix to normalized coor
ds. | 44 // translation to the devBound, and then a scaling matrix to normalized coor
ds. |
43 mat.setIDiv(result->width(), result->height()); | 45 mat.setIDiv(result->width(), result->height()); |
44 mat.preTranslate(SkIntToScalar(-devBound.fLeft), | 46 mat.preTranslate(SkIntToScalar(-devBound.fLeft), |
45 SkIntToScalar(-devBound.fTop)); | 47 SkIntToScalar(-devBound.fTop)); |
46 | 48 |
47 SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height()); | 49 SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height()); |
48 // This could be a long-lived effect that is cached with the alpha-mask. | 50 // This could be a long-lived effect that is cached with the alpha-mask. |
49 pipelineBuilder->addCoverageProcessor( | 51 arfp->addCoverageProcessor( |
50 GrTextureDomainEffect::Create(pipelineBuilder->getProcessorDataManager()
, | 52 GrTextureDomainEffect::Create(arpdm->getProcessorDataManager(), |
51 result, | 53 result, |
52 mat, | 54 mat, |
53 GrTextureDomain::MakeTexelDomain(result, d
omainTexels), | 55 GrTextureDomain::MakeTexelDomain(result, d
omainTexels), |
54 GrTextureDomain::kDecal_Mode, | 56 GrTextureDomain::kDecal_Mode, |
55 GrTextureParams::kNone_FilterMode, | 57 GrTextureParams::kNone_FilterMode, |
56 kDevice_GrCoordSet))->unref(); | 58 kDevice_GrCoordSet))->unref(); |
57 } | 59 } |
58 | 60 |
59 bool path_needs_SW_renderer(GrContext* context, | 61 bool path_needs_SW_renderer(GrContext* context, |
60 const GrDrawTarget* gpu, | 62 const GrDrawTarget* gpu, |
61 const GrPipelineBuilder* pipelineBuilder, | 63 const GrPipelineBuilder& pipelineBuilder, |
62 const SkMatrix& viewMatrix, | 64 const SkMatrix& viewMatrix, |
63 const SkPath& origPath, | 65 const SkPath& origPath, |
64 const GrStrokeInfo& stroke, | 66 const GrStrokeInfo& stroke, |
65 bool doAA) { | 67 bool doAA) { |
66 // the gpu alpha mask will draw the inverse paths as non-inverse to a temp b
uffer | 68 // the gpu alpha mask will draw the inverse paths as non-inverse to a temp b
uffer |
67 SkTCopyOnFirstWrite<SkPath> path(origPath); | 69 SkTCopyOnFirstWrite<SkPath> path(origPath); |
68 if (path->isInverseFillType()) { | 70 if (path->isInverseFillType()) { |
69 path.writable()->toggleInverseFillType(); | 71 path.writable()->toggleInverseFillType(); |
70 } | 72 } |
71 // last (false) parameter disallows use of the SW path renderer | 73 // last (false) parameter disallows use of the SW path renderer |
72 GrPathRendererChain::DrawType type = doAA ? | 74 GrPathRendererChain::DrawType type = doAA ? |
73 GrPathRendererChain::kColorAntiAlias_Dr
awType : | 75 GrPathRendererChain::kColorAntiAlias_Dr
awType : |
74 GrPathRendererChain::kColor_DrawType; | 76 GrPathRendererChain::kColor_DrawType; |
75 | 77 |
76 return NULL == context->getPathRenderer(gpu, pipelineBuilder, viewMatrix, *p
ath, stroke, | 78 return NULL == context->getPathRenderer(gpu, &pipelineBuilder, viewMatrix, *
path, stroke, |
77 false, type); | 79 false, type); |
78 } | 80 } |
79 } | 81 } |
80 | 82 |
81 GrClipMaskManager::GrClipMaskManager(GrClipTarget* clipTarget) | 83 GrClipMaskManager::GrClipMaskManager(GrClipTarget* clipTarget) |
82 : fCurrClipMaskType(kNone_ClipMaskType) | 84 : fCurrClipMaskType(kNone_ClipMaskType) |
83 , fAACache(clipTarget->getContext()->resourceProvider()) | 85 , fAACache(clipTarget->getContext()->resourceProvider()) |
84 , fClipTarget(clipTarget) | 86 , fClipTarget(clipTarget) |
85 , fClipMode(kIgnoreClip_StencilClipMode) { | 87 , fClipMode(kIgnoreClip_StencilClipMode) { |
86 } | 88 } |
87 | 89 |
88 GrContext* GrClipMaskManager::getContext() { return fClipTarget->getContext(); } | 90 GrContext* GrClipMaskManager::getContext() { return fClipTarget->getContext(); } |
89 | 91 |
90 /* | 92 /* |
91 * This method traverses the clip stack to see if the GrSoftwarePathRenderer | 93 * This method traverses the clip stack to see if the GrSoftwarePathRenderer |
92 * will be used on any element. If so, it returns true to indicate that the | 94 * will be used on any element. If so, it returns true to indicate that the |
93 * entire clip should be rendered in SW and then uploaded en masse to the gpu. | 95 * entire clip should be rendered in SW and then uploaded en masse to the gpu. |
94 */ | 96 */ |
95 bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder* pipelineBuilder, | 97 bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder& pipelineBuilder, |
96 const SkVector& clipToMaskOffset, | 98 const SkVector& clipToMaskOffset, |
97 const GrReducedClip::ElementList& elements
) { | 99 const GrReducedClip::ElementList& elements
) { |
98 // TODO: generalize this function so that when | 100 // TODO: generalize this function so that when |
99 // a clip gets complex enough it can just be done in SW regardless | 101 // a clip gets complex enough it can just be done in SW regardless |
100 // of whether it would invoke the GrSoftwarePathRenderer. | 102 // of whether it would invoke the GrSoftwarePathRenderer. |
101 GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle); | 103 GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle); |
102 | 104 |
103 // Set the matrix so that rendered clip elements are transformed to mask spa
ce from clip | 105 // Set the matrix so that rendered clip elements are transformed to mask spa
ce from clip |
104 // space. | 106 // space. |
105 SkMatrix translate; | 107 SkMatrix translate; |
106 translate.setTranslate(clipToMaskOffset); | 108 translate.setTranslate(clipToMaskOffset); |
107 | 109 |
108 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get();
iter.next()) { | 110 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get();
iter.next()) { |
109 const Element* element = iter.get(); | 111 const Element* element = iter.get(); |
110 // rects can always be drawn directly w/o using the software path | 112 // rects can always be drawn directly w/o using the software path |
111 // Skip rrects once we're drawing them directly. | 113 // Skip rrects once we're drawing them directly. |
112 if (Element::kRect_Type != element->getType()) { | 114 if (Element::kRect_Type != element->getType()) { |
113 SkPath path; | 115 SkPath path; |
114 element->asPath(&path); | 116 element->asPath(&path); |
115 if (path_needs_SW_renderer(this->getContext(), fClipTarget, pipeline
Builder, translate, | 117 if (path_needs_SW_renderer(this->getContext(), fClipTarget, pipeline
Builder, translate, |
116 path, stroke, element->isAA())) { | 118 path, stroke, element->isAA())) { |
117 return true; | 119 return true; |
118 } | 120 } |
119 } | 121 } |
120 } | 122 } |
121 return false; | 123 return false; |
122 } | 124 } |
123 | 125 |
124 bool GrClipMaskManager::installClipEffects(GrPipelineBuilder* pipelineBuilder, | 126 bool GrClipMaskManager::installClipEffects(const GrPipelineBuilder& pipelineBuil
der, |
125 GrPipelineBuilder::AutoRestoreFragmen
tProcessors* arfp, | 127 GrPipelineBuilder::AutoRestoreFragmen
tProcessors* arfp, |
126 const GrReducedClip::ElementList& ele
ments, | 128 const GrReducedClip::ElementList& ele
ments, |
127 const SkVector& clipToRTOffset, | 129 const SkVector& clipToRTOffset, |
128 const SkRect* drawBounds) { | 130 const SkRect* drawBounds) { |
129 SkRect boundsInClipSpace; | 131 SkRect boundsInClipSpace; |
130 if (drawBounds) { | 132 if (drawBounds) { |
131 boundsInClipSpace = *drawBounds; | 133 boundsInClipSpace = *drawBounds; |
132 boundsInClipSpace.offset(-clipToRTOffset.fX, -clipToRTOffset.fY); | 134 boundsInClipSpace.offset(-clipToRTOffset.fX, -clipToRTOffset.fY); |
133 } | 135 } |
134 | 136 |
135 arfp->set(pipelineBuilder); | 137 arfp->set(&pipelineBuilder); |
136 GrRenderTarget* rt = pipelineBuilder->getRenderTarget(); | 138 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); |
137 GrReducedClip::ElementList::Iter iter(elements); | 139 GrReducedClip::ElementList::Iter iter(elements); |
138 bool failed = false; | 140 bool failed = false; |
139 while (iter.get()) { | 141 while (iter.get()) { |
140 SkRegion::Op op = iter.get()->getOp(); | 142 SkRegion::Op op = iter.get()->getOp(); |
141 bool invert; | 143 bool invert; |
142 bool skip = false; | 144 bool skip = false; |
143 switch (op) { | 145 switch (op) { |
144 case SkRegion::kReplace_Op: | 146 case SkRegion::kReplace_Op: |
145 SkASSERT(iter.get() == elements.head()); | 147 SkASSERT(iter.get() == elements.head()); |
146 // Fallthrough, handled same as intersect. | 148 // Fallthrough, handled same as intersect. |
(...skipping 20 matching lines...) Expand all Loading... |
167 GrPrimitiveEdgeType edgeType; | 169 GrPrimitiveEdgeType edgeType; |
168 if (iter.get()->isAA()) { | 170 if (iter.get()->isAA()) { |
169 if (rt->isUnifiedMultisampled()) { | 171 if (rt->isUnifiedMultisampled()) { |
170 // Coverage based AA clips don't place nicely with MSAA. | 172 // Coverage based AA clips don't place nicely with MSAA. |
171 failed = true; | 173 failed = true; |
172 break; | 174 break; |
173 } | 175 } |
174 edgeType = | 176 edgeType = |
175 invert ? kInverseFillAA_GrProcessorEdgeType : kFillAA_Gr
ProcessorEdgeType; | 177 invert ? kInverseFillAA_GrProcessorEdgeType : kFillAA_Gr
ProcessorEdgeType; |
176 } else { | 178 } else { |
177 edgeType = | 179 edgeType = invert ? kInverseFillBW_GrProcessorEdgeType : |
178 invert ? kInverseFillBW_GrProcessorEdgeType : kFillBW_GrProcessorEdgeType; | 180 kFillBW_GrProcessorEdgeType; |
179 } | 181 } |
180 SkAutoTUnref<GrFragmentProcessor> fp; | 182 SkAutoTUnref<GrFragmentProcessor> fp; |
181 switch (iter.get()->getType()) { | 183 switch (iter.get()->getType()) { |
182 case SkClipStack::Element::kPath_Type: | 184 case SkClipStack::Element::kPath_Type: |
183 fp.reset(GrConvexPolyEffect::Create(edgeType, iter.get()->ge
tPath(), | 185 fp.reset(GrConvexPolyEffect::Create(edgeType, iter.get()->ge
tPath(), |
184 &clipToRTOffset)); | 186 &clipToRTOffset)); |
185 break; | 187 break; |
186 case SkClipStack::Element::kRRect_Type: { | 188 case SkClipStack::Element::kRRect_Type: { |
187 SkRRect rrect = iter.get()->getRRect(); | 189 SkRRect rrect = iter.get()->getRRect(); |
188 rrect.offset(clipToRTOffset.fX, clipToRTOffset.fY); | 190 rrect.offset(clipToRTOffset.fX, clipToRTOffset.fY); |
189 fp.reset(GrRRectEffect::Create(edgeType, rrect)); | 191 fp.reset(GrRRectEffect::Create(edgeType, rrect)); |
190 break; | 192 break; |
191 } | 193 } |
192 case SkClipStack::Element::kRect_Type: { | 194 case SkClipStack::Element::kRect_Type: { |
193 SkRect rect = iter.get()->getRect(); | 195 SkRect rect = iter.get()->getRect(); |
194 rect.offset(clipToRTOffset.fX, clipToRTOffset.fY); | 196 rect.offset(clipToRTOffset.fX, clipToRTOffset.fY); |
195 fp.reset(GrConvexPolyEffect::Create(edgeType, rect)); | 197 fp.reset(GrConvexPolyEffect::Create(edgeType, rect)); |
196 break; | 198 break; |
197 } | 199 } |
198 default: | 200 default: |
199 break; | 201 break; |
200 } | 202 } |
201 if (fp) { | 203 if (fp) { |
202 pipelineBuilder->addCoverageProcessor(fp); | 204 arfp->addCoverageProcessor(fp); |
203 } else { | 205 } else { |
204 failed = true; | 206 failed = true; |
205 break; | 207 break; |
206 } | 208 } |
207 } | 209 } |
208 iter.next(); | 210 iter.next(); |
209 } | 211 } |
210 | 212 |
211 if (failed) { | 213 if (failed) { |
212 arfp->set(NULL); | 214 arfp->set(NULL); |
213 } | 215 } |
214 return !failed; | 216 return !failed; |
215 } | 217 } |
216 | 218 |
217 //////////////////////////////////////////////////////////////////////////////// | 219 //////////////////////////////////////////////////////////////////////////////// |
218 // sort out what kind of clip mask needs to be created: alpha, stencil, | 220 // sort out what kind of clip mask needs to be created: alpha, stencil, |
219 // scissor, or entirely software | 221 // scissor, or entirely software |
220 bool GrClipMaskManager::setupClipping(GrPipelineBuilder* pipelineBuilder, | 222 bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder, |
221 GrPipelineBuilder::AutoRestoreFragmentProc
essors* arfp, | 223 GrPipelineBuilder::AutoRestoreFragmentProc
essors* arfp, |
222 GrPipelineBuilder::AutoRestoreStencil* ars
, | 224 GrPipelineBuilder::AutoRestoreStencil* ars
, |
| 225 GrPipelineBuilder::AutoRestoreProcessorDat
aManager* arpdm, |
223 GrScissorState* scissorState, | 226 GrScissorState* scissorState, |
224 const SkRect* devBounds) { | 227 const SkRect* devBounds) { |
225 fCurrClipMaskType = kNone_ClipMaskType; | 228 fCurrClipMaskType = kNone_ClipMaskType; |
226 if (kRespectClip_StencilClipMode == fClipMode) { | 229 if (kRespectClip_StencilClipMode == fClipMode) { |
227 fClipMode = kIgnoreClip_StencilClipMode; | 230 fClipMode = kIgnoreClip_StencilClipMode; |
228 } | 231 } |
229 | 232 |
230 GrReducedClip::ElementList elements(16); | 233 GrReducedClip::ElementList elements(16); |
231 int32_t genID = 0; | 234 int32_t genID = 0; |
232 GrReducedClip::InitialState initialState = GrReducedClip::kAllIn_InitialStat
e; | 235 GrReducedClip::InitialState initialState = GrReducedClip::kAllIn_InitialStat
e; |
233 SkIRect clipSpaceIBounds; | 236 SkIRect clipSpaceIBounds; |
234 bool requiresAA = false; | 237 bool requiresAA = false; |
235 GrRenderTarget* rt = pipelineBuilder->getRenderTarget(); | 238 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); |
236 | 239 |
237 // GrDrawTarget should have filtered this for us | 240 // GrDrawTarget should have filtered this for us |
238 SkASSERT(rt); | 241 SkASSERT(rt); |
239 | 242 |
240 SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height()); | 243 SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height()); |
241 const GrClip& clip = pipelineBuilder->clip(); | 244 const GrClip& clip = pipelineBuilder.clip(); |
242 if (clip.isWideOpen(clipSpaceRTIBounds)) { | 245 if (clip.isWideOpen(clipSpaceRTIBounds)) { |
243 this->setPipelineBuilderStencil(pipelineBuilder, ars); | 246 this->setPipelineBuilderStencil(pipelineBuilder, ars); |
244 return true; | 247 return true; |
245 } | 248 } |
246 | 249 |
247 // The clip mask manager always draws with a single IRect so we special case
that logic here | 250 // The clip mask manager always draws with a single IRect so we special case
that logic here |
248 // Image filters just use a rect, so we also special case that logic | 251 // Image filters just use a rect, so we also special case that logic |
249 switch (clip.clipType()) { | 252 switch (clip.clipType()) { |
250 case GrClip::kWideOpen_ClipType: | 253 case GrClip::kWideOpen_ClipType: |
251 SkFAIL("Should have caught this with clip.isWideOpen()"); | 254 SkFAIL("Should have caught this with clip.isWideOpen()"); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 clipSpaceIBounds); | 329 clipSpaceIBounds); |
327 } else { | 330 } else { |
328 result = this->createAlphaClipMask(genID, | 331 result = this->createAlphaClipMask(genID, |
329 initialState, | 332 initialState, |
330 elements, | 333 elements, |
331 clipToMaskOffset, | 334 clipToMaskOffset, |
332 clipSpaceIBounds); | 335 clipSpaceIBounds); |
333 } | 336 } |
334 | 337 |
335 if (result) { | 338 if (result) { |
336 arfp->set(pipelineBuilder); | 339 arfp->set(&pipelineBuilder); |
337 // The mask's top left coord should be pinned to the rounded-out top
left corner of | 340 // The mask's top left coord should be pinned to the rounded-out top
left corner of |
338 // clipSpace bounds. We determine the mask's position WRT to the ren
der target here. | 341 // clipSpace bounds. We determine the mask's position WRT to the ren
der target here. |
339 SkIRect rtSpaceMaskBounds = clipSpaceIBounds; | 342 SkIRect rtSpaceMaskBounds = clipSpaceIBounds; |
340 rtSpaceMaskBounds.offset(-clip.origin()); | 343 rtSpaceMaskBounds.offset(-clip.origin()); |
341 setup_drawstate_aaclip(pipelineBuilder, result, arfp, rtSpaceMaskBou
nds); | 344 setup_drawstate_aaclip(pipelineBuilder, result, arfp, arpdm, rtSpace
MaskBounds); |
342 this->setPipelineBuilderStencil(pipelineBuilder, ars); | 345 this->setPipelineBuilderStencil(pipelineBuilder, ars); |
343 return true; | 346 return true; |
344 } | 347 } |
345 // if alpha clip mask creation fails fall through to the non-AA code pat
hs | 348 // if alpha clip mask creation fails fall through to the non-AA code pat
hs |
346 } | 349 } |
347 | 350 |
348 // Either a hard (stencil buffer) clip was explicitly requested or an anti-a
liased clip couldn't | 351 // Either a hard (stencil buffer) clip was explicitly requested or an anti-a
liased clip couldn't |
349 // be created. In either case, free up the texture in the anti-aliased mask
cache. | 352 // be created. In either case, free up the texture in the anti-aliased mask
cache. |
350 // TODO: this may require more investigation. Ganesh performs a lot of utili
ty draws (e.g., | 353 // TODO: this may require more investigation. Ganesh performs a lot of utili
ty draws (e.g., |
351 // clears, InOrderDrawBuffer playbacks) that hit the stencil buffer path. Th
ese may be | 354 // clears, InOrderDrawBuffer playbacks) that hit the stencil buffer path. Th
ese may be |
(...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
918 kKeep_StencilOp, | 921 kKeep_StencilOp, |
919 kKeep_StencilOp, | 922 kKeep_StencilOp, |
920 kAlwaysIfInClip_StencilFunc, | 923 kAlwaysIfInClip_StencilFunc, |
921 0x0000, | 924 0x0000, |
922 0x0000, | 925 0x0000, |
923 0x0000); | 926 0x0000); |
924 return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings); | 927 return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings); |
925 } | 928 } |
926 } | 929 } |
927 | 930 |
928 void GrClipMaskManager::setPipelineBuilderStencil(GrPipelineBuilder* pipelineBui
lder, | 931 void GrClipMaskManager::setPipelineBuilderStencil(const GrPipelineBuilder& pipel
ineBuilder, |
929 GrPipelineBuilder::AutoRestore
Stencil* ars) { | 932 GrPipelineBuilder::AutoRestore
Stencil* ars) { |
930 // We make two copies of the StencilSettings here (except in the early | 933 // We make two copies of the StencilSettings here (except in the early |
931 // exit scenario. One copy from draw state to the stack var. Then another | 934 // exit scenario. One copy from draw state to the stack var. Then another |
932 // from the stack var to the gpu. We could make this class hold a ptr to | 935 // from the stack var to the gpu. We could make this class hold a ptr to |
933 // GrGpu's fStencilSettings and eliminate the stack copy here. | 936 // GrGpu's fStencilSettings and eliminate the stack copy here. |
934 | 937 |
935 // use stencil for clipping if clipping is enabled and the clip | 938 // use stencil for clipping if clipping is enabled and the clip |
936 // has been written into the stencil. | 939 // has been written into the stencil. |
937 GrStencilSettings settings; | 940 GrStencilSettings settings; |
938 | 941 |
939 // The GrGpu client may not be using the stencil buffer but we may need to | 942 // The GrGpu client may not be using the stencil buffer but we may need to |
940 // enable it in order to respect a stencil clip. | 943 // enable it in order to respect a stencil clip. |
941 if (pipelineBuilder->getStencil().isDisabled()) { | 944 if (pipelineBuilder.getStencil().isDisabled()) { |
942 if (GrClipMaskManager::kRespectClip_StencilClipMode == fClipMode) { | 945 if (GrClipMaskManager::kRespectClip_StencilClipMode == fClipMode) { |
943 settings = basic_apply_stencil_clip_settings(); | 946 settings = basic_apply_stencil_clip_settings(); |
944 } else { | 947 } else { |
945 return; | 948 return; |
946 } | 949 } |
947 } else { | 950 } else { |
948 settings = pipelineBuilder->getStencil(); | 951 settings = pipelineBuilder.getStencil(); |
949 } | 952 } |
950 | 953 |
951 int stencilBits = 0; | 954 int stencilBits = 0; |
952 GrRenderTarget* rt = pipelineBuilder->getRenderTarget(); | 955 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); |
953 GrStencilAttachment* stencilAttachment = rt->renderTargetPriv().attachStenci
lAttachment(); | 956 GrStencilAttachment* stencilAttachment = rt->renderTargetPriv().attachStenci
lAttachment(); |
954 if (stencilAttachment) { | 957 if (stencilAttachment) { |
955 stencilBits = stencilAttachment->bits(); | 958 stencilBits = stencilAttachment->bits(); |
956 } | 959 } |
957 | 960 |
958 SkASSERT(fClipTarget->caps()->stencilWrapOpsSupport() || !settings.usesWrapO
p()); | 961 SkASSERT(fClipTarget->caps()->stencilWrapOpsSupport() || !settings.usesWrapO
p()); |
959 SkASSERT(fClipTarget->caps()->twoSidedStencilSupport() || !settings.isTwoSid
ed()); | 962 SkASSERT(fClipTarget->caps()->twoSidedStencilSupport() || !settings.isTwoSid
ed()); |
960 this->adjustStencilParams(&settings, fClipMode, stencilBits); | 963 this->adjustStencilParams(&settings, fClipMode, stencilBits); |
961 ars->set(pipelineBuilder); | 964 ars->set(&pipelineBuilder); |
962 pipelineBuilder->setStencil(settings); | 965 ars->setStencil(settings); |
963 } | 966 } |
964 | 967 |
965 void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings, | 968 void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings, |
966 StencilClipMode mode, | 969 StencilClipMode mode, |
967 int stencilBitCnt) { | 970 int stencilBitCnt) { |
968 SkASSERT(stencilBitCnt > 0); | 971 SkASSERT(stencilBitCnt > 0); |
969 | 972 |
970 if (kModifyClip_StencilClipMode == mode) { | 973 if (kModifyClip_StencilClipMode == mode) { |
971 // We assume that this clip manager itself is drawing to the GrGpu and | 974 // We assume that this clip manager itself is drawing to the GrGpu and |
972 // has already setup the correct values. | 975 // has already setup the correct values. |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1120 fAACache.purgeResources(); | 1123 fAACache.purgeResources(); |
1121 } | 1124 } |
1122 | 1125 |
1123 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc
ilAttachment, | 1126 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc
ilAttachment, |
1124 GrStencilSettings* settings) { | 1127 GrStencilSettings* settings) { |
1125 if (stencilAttachment) { | 1128 if (stencilAttachment) { |
1126 int stencilBits = stencilAttachment->bits(); | 1129 int stencilBits = stencilAttachment->bits(); |
1127 this->adjustStencilParams(settings, fClipMode, stencilBits); | 1130 this->adjustStencilParams(settings, fClipMode, stencilBits); |
1128 } | 1131 } |
1129 } | 1132 } |
OLD | NEW |