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 14 matching lines...) Expand all Loading... |
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(GrPipelineBuilder* pipelineBuilder, |
34 GrTexture* result, | 34 GrTexture* result, |
35 GrPipelineBuilder::AutoRestoreEffects* are, | 35 GrPipelineBuilder::AutoRestoreFragmentProcessors* ar
fp, |
36 const SkIRect &devBound) { | 36 const SkIRect &devBound) { |
37 SkASSERT(pipelineBuilder && are); | 37 SkASSERT(pipelineBuilder && arfp); |
38 are->set(pipelineBuilder); | 38 arfp->set(pipelineBuilder); |
39 | 39 |
40 SkMatrix mat; | 40 SkMatrix mat; |
41 // We use device coords to compute the texture coordinates. We set our matri
x to be a | 41 // 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. | 42 // translation to the devBound, and then a scaling matrix to normalized coor
ds. |
43 mat.setIDiv(result->width(), result->height()); | 43 mat.setIDiv(result->width(), result->height()); |
44 mat.preTranslate(SkIntToScalar(-devBound.fLeft), | 44 mat.preTranslate(SkIntToScalar(-devBound.fLeft), |
45 SkIntToScalar(-devBound.fTop)); | 45 SkIntToScalar(-devBound.fTop)); |
46 | 46 |
47 SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height()); | 47 SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height()); |
48 // This could be a long-lived effect that is cached with the alpha-mask. | 48 // This could be a long-lived effect that is cached with the alpha-mask. |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 if (path_needs_SW_renderer(this->getContext(), fClipTarget, pipeline
Builder, translate, | 105 if (path_needs_SW_renderer(this->getContext(), fClipTarget, pipeline
Builder, translate, |
106 path, stroke, element->isAA())) { | 106 path, stroke, element->isAA())) { |
107 return true; | 107 return true; |
108 } | 108 } |
109 } | 109 } |
110 } | 110 } |
111 return false; | 111 return false; |
112 } | 112 } |
113 | 113 |
114 bool GrClipMaskManager::installClipEffects(GrPipelineBuilder* pipelineBuilder, | 114 bool GrClipMaskManager::installClipEffects(GrPipelineBuilder* pipelineBuilder, |
115 GrPipelineBuilder::AutoRestoreEffects
* are, | 115 GrPipelineBuilder::AutoRestoreFragmen
tProcessors* arfp, |
116 const GrReducedClip::ElementList& ele
ments, | 116 const GrReducedClip::ElementList& ele
ments, |
117 const SkVector& clipToRTOffset, | 117 const SkVector& clipToRTOffset, |
118 const SkRect* drawBounds) { | 118 const SkRect* drawBounds) { |
119 SkRect boundsInClipSpace; | 119 SkRect boundsInClipSpace; |
120 if (drawBounds) { | 120 if (drawBounds) { |
121 boundsInClipSpace = *drawBounds; | 121 boundsInClipSpace = *drawBounds; |
122 boundsInClipSpace.offset(-clipToRTOffset.fX, -clipToRTOffset.fY); | 122 boundsInClipSpace.offset(-clipToRTOffset.fX, -clipToRTOffset.fY); |
123 } | 123 } |
124 | 124 |
125 are->set(pipelineBuilder); | 125 arfp->set(pipelineBuilder); |
126 GrRenderTarget* rt = pipelineBuilder->getRenderTarget(); | 126 GrRenderTarget* rt = pipelineBuilder->getRenderTarget(); |
127 GrReducedClip::ElementList::Iter iter(elements); | 127 GrReducedClip::ElementList::Iter iter(elements); |
128 bool failed = false; | 128 bool failed = false; |
129 while (iter.get()) { | 129 while (iter.get()) { |
130 SkRegion::Op op = iter.get()->getOp(); | 130 SkRegion::Op op = iter.get()->getOp(); |
131 bool invert; | 131 bool invert; |
132 bool skip = false; | 132 bool skip = false; |
133 switch (op) { | 133 switch (op) { |
134 case SkRegion::kReplace_Op: | 134 case SkRegion::kReplace_Op: |
135 SkASSERT(iter.get() == elements.head()); | 135 SkASSERT(iter.get() == elements.head()); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 pipelineBuilder->addCoverageProcessor(fp); | 192 pipelineBuilder->addCoverageProcessor(fp); |
193 } else { | 193 } else { |
194 failed = true; | 194 failed = true; |
195 break; | 195 break; |
196 } | 196 } |
197 } | 197 } |
198 iter.next(); | 198 iter.next(); |
199 } | 199 } |
200 | 200 |
201 if (failed) { | 201 if (failed) { |
202 are->set(NULL); | 202 arfp->set(NULL); |
203 } | 203 } |
204 return !failed; | 204 return !failed; |
205 } | 205 } |
206 | 206 |
207 //////////////////////////////////////////////////////////////////////////////// | 207 //////////////////////////////////////////////////////////////////////////////// |
208 // sort out what kind of clip mask needs to be created: alpha, stencil, | 208 // sort out what kind of clip mask needs to be created: alpha, stencil, |
209 // scissor, or entirely software | 209 // scissor, or entirely software |
210 bool GrClipMaskManager::setupClipping(GrPipelineBuilder* pipelineBuilder, | 210 bool GrClipMaskManager::setupClipping(GrPipelineBuilder* pipelineBuilder, |
211 GrPipelineBuilder::AutoRestoreEffects* are
, | 211 GrPipelineBuilder::AutoRestoreFragmentProc
essors* arfp, |
212 GrPipelineBuilder::AutoRestoreStencil* ars
, | 212 GrPipelineBuilder::AutoRestoreStencil* ars
, |
213 GrScissorState* scissorState, | 213 GrScissorState* scissorState, |
214 const SkRect* devBounds) { | 214 const SkRect* devBounds) { |
215 fCurrClipMaskType = kNone_ClipMaskType; | 215 fCurrClipMaskType = kNone_ClipMaskType; |
216 if (kRespectClip_StencilClipMode == fClipMode) { | 216 if (kRespectClip_StencilClipMode == fClipMode) { |
217 fClipMode = kIgnoreClip_StencilClipMode; | 217 fClipMode = kIgnoreClip_StencilClipMode; |
218 } | 218 } |
219 | 219 |
220 GrReducedClip::ElementList elements(16); | 220 GrReducedClip::ElementList elements(16); |
221 int32_t genID; | 221 int32_t genID; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 // diff RR | 287 // diff RR |
288 // isect convex_poly | 288 // isect convex_poly |
289 // isect convex_poly | 289 // isect convex_poly |
290 // when drawing rounded div borders. This could probably be tuned based on a | 290 // when drawing rounded div borders. This could probably be tuned based on a |
291 // configuration's relative costs of switching RTs to generate a mask vs | 291 // configuration's relative costs of switching RTs to generate a mask vs |
292 // longer shaders. | 292 // longer shaders. |
293 if (elements.count() <= 4) { | 293 if (elements.count() <= 4) { |
294 SkVector clipToRTOffset = { SkIntToScalar(-clip.origin().fX), | 294 SkVector clipToRTOffset = { SkIntToScalar(-clip.origin().fX), |
295 SkIntToScalar(-clip.origin().fY) }; | 295 SkIntToScalar(-clip.origin().fY) }; |
296 if (elements.isEmpty() || | 296 if (elements.isEmpty() || |
297 this->installClipEffects(pipelineBuilder, are, elements, clipToRTOff
set, devBounds)) { | 297 this->installClipEffects(pipelineBuilder, arfp, elements, clipToRTOf
fset, devBounds)) { |
298 SkIRect scissorSpaceIBounds(clipSpaceIBounds); | 298 SkIRect scissorSpaceIBounds(clipSpaceIBounds); |
299 scissorSpaceIBounds.offset(-clip.origin()); | 299 scissorSpaceIBounds.offset(-clip.origin()); |
300 if (NULL == devBounds || | 300 if (NULL == devBounds || |
301 !SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) { | 301 !SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) { |
302 scissorState->set(scissorSpaceIBounds); | 302 scissorState->set(scissorSpaceIBounds); |
303 } | 303 } |
304 this->setPipelineBuilderStencil(pipelineBuilder, ars); | 304 this->setPipelineBuilderStencil(pipelineBuilder, ars); |
305 return true; | 305 return true; |
306 } | 306 } |
307 } | 307 } |
(...skipping 18 matching lines...) Expand all Loading... |
326 clipSpaceIBounds); | 326 clipSpaceIBounds); |
327 } else { | 327 } else { |
328 result = this->createAlphaClipMask(genID, | 328 result = this->createAlphaClipMask(genID, |
329 initialState, | 329 initialState, |
330 elements, | 330 elements, |
331 clipToMaskOffset, | 331 clipToMaskOffset, |
332 clipSpaceIBounds); | 332 clipSpaceIBounds); |
333 } | 333 } |
334 | 334 |
335 if (result) { | 335 if (result) { |
336 are->set(pipelineBuilder); | 336 arfp->set(pipelineBuilder); |
337 // The mask's top left coord should be pinned to the rounded-out top
left corner of | 337 // 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. | 338 // clipSpace bounds. We determine the mask's position WRT to the ren
der target here. |
339 SkIRect rtSpaceMaskBounds = clipSpaceIBounds; | 339 SkIRect rtSpaceMaskBounds = clipSpaceIBounds; |
340 rtSpaceMaskBounds.offset(-clip.origin()); | 340 rtSpaceMaskBounds.offset(-clip.origin()); |
341 setup_drawstate_aaclip(pipelineBuilder, result, are, rtSpaceMaskBoun
ds); | 341 setup_drawstate_aaclip(pipelineBuilder, result, arfp, rtSpaceMaskBou
nds); |
342 this->setPipelineBuilderStencil(pipelineBuilder, ars); | 342 this->setPipelineBuilderStencil(pipelineBuilder, ars); |
343 return true; | 343 return true; |
344 } | 344 } |
345 // if alpha clip mask creation fails fall through to the non-AA code pat
hs | 345 // if alpha clip mask creation fails fall through to the non-AA code pat
hs |
346 } | 346 } |
347 | 347 |
348 // Either a hard (stencil buffer) clip was explicitly requested or an anti-a
liased clip couldn't | 348 // 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. | 349 // 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., | 350 // 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 | 351 // clears, InOrderDrawBuffer playbacks) that hit the stencil buffer path. Th
ese may be |
(...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1123 fAACache.setContext(clipTarget->getContext()); | 1123 fAACache.setContext(clipTarget->getContext()); |
1124 } | 1124 } |
1125 | 1125 |
1126 void GrClipMaskManager::adjustPathStencilParams(const GrStencilBuffer* stencilBu
ffer, | 1126 void GrClipMaskManager::adjustPathStencilParams(const GrStencilBuffer* stencilBu
ffer, |
1127 GrStencilSettings* settings) { | 1127 GrStencilSettings* settings) { |
1128 if (stencilBuffer) { | 1128 if (stencilBuffer) { |
1129 int stencilBits = stencilBuffer->bits(); | 1129 int stencilBits = stencilBuffer->bits(); |
1130 this->adjustStencilParams(settings, fClipMode, stencilBits); | 1130 this->adjustStencilParams(settings, fClipMode, stencilBits); |
1131 } | 1131 } |
1132 } | 1132 } |
OLD | NEW |