| 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 |