| 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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 return SkToBool(!pr); | 108 return SkToBool(!pr); |
| 109 } | 109 } |
| 110 } | 110 } |
| 111 | 111 |
| 112 /* | 112 /* |
| 113 * This method traverses the clip stack to see if the GrSoftwarePathRenderer | 113 * This method traverses the clip stack to see if the GrSoftwarePathRenderer |
| 114 * will be used on any element. If so, it returns true to indicate that the | 114 * will be used on any element. If so, it returns true to indicate that the |
| 115 * entire clip should be rendered in SW and then uploaded en masse to the gpu. | 115 * entire clip should be rendered in SW and then uploaded en masse to the gpu. |
| 116 */ | 116 */ |
| 117 bool GrClipMaskManager::UseSWOnlyPath(GrContext* context, | 117 bool GrClipMaskManager::UseSWOnlyPath(GrContext* context, |
| 118 const GrPipelineBuilder& pipelineBuilder, | 118 bool hasUserStencilSettings, |
| 119 const GrDrawContext* drawContext, | 119 const GrDrawContext* drawContext, |
| 120 const SkVector& clipToMaskOffset, | 120 const SkVector& clipToMaskOffset, |
| 121 const GrReducedClip::ElementList& elements
) { | 121 const GrReducedClip::ElementList& elements
) { |
| 122 // TODO: generalize this function so that when | 122 // TODO: generalize this function so that when |
| 123 // a clip gets complex enough it can just be done in SW regardless | 123 // a clip gets complex enough it can just be done in SW regardless |
| 124 // of whether it would invoke the GrSoftwarePathRenderer. | 124 // of whether it would invoke the GrSoftwarePathRenderer. |
| 125 | 125 |
| 126 // Set the matrix so that rendered clip elements are transformed to mask spa
ce from clip | 126 // Set the matrix so that rendered clip elements are transformed to mask spa
ce from clip |
| 127 // space. | 127 // space. |
| 128 const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMa
skOffset.fY); | 128 const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMa
skOffset.fY); |
| 129 | 129 |
| 130 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get();
iter.next()) { | 130 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get();
iter.next()) { |
| 131 const Element* element = iter.get(); | 131 const Element* element = iter.get(); |
| 132 | 132 |
| 133 SkRegion::Op op = element->getOp(); | 133 SkRegion::Op op = element->getOp(); |
| 134 bool invert = element->isInverseFilled(); | 134 bool invert = element->isInverseFilled(); |
| 135 bool needsStencil = invert || | 135 bool needsStencil = invert || |
| 136 SkRegion::kIntersect_Op == op || SkRegion::kReverseD
ifference_Op == op; | 136 SkRegion::kIntersect_Op == op || SkRegion::kReverseD
ifference_Op == op; |
| 137 | 137 |
| 138 if (PathNeedsSWRenderer(context, pipelineBuilder.hasUserStencilSettings(
), | 138 if (PathNeedsSWRenderer(context, hasUserStencilSettings, |
| 139 drawContext, translate, element, nullptr, needsS
tencil)) { | 139 drawContext, translate, element, nullptr, needsS
tencil)) { |
| 140 return true; | 140 return true; |
| 141 } | 141 } |
| 142 } | 142 } |
| 143 return false; | 143 return false; |
| 144 } | 144 } |
| 145 | 145 |
| 146 static bool get_analytic_clip_processor(const GrReducedClip::ElementList& elemen
ts, | 146 static bool get_analytic_clip_processor(const GrReducedClip::ElementList& elemen
ts, |
| 147 bool abortIfAA, | 147 bool abortIfAA, |
| 148 SkVector& clipToRTOffset, | 148 SkVector& clipToRTOffset, |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 if (fps.count()) { | 219 if (fps.count()) { |
| 220 *resultFP = GrFragmentProcessor::RunInSeries(fps.begin(), fps.count()); | 220 *resultFP = GrFragmentProcessor::RunInSeries(fps.begin(), fps.count()); |
| 221 } | 221 } |
| 222 return true; | 222 return true; |
| 223 } | 223 } |
| 224 | 224 |
| 225 //////////////////////////////////////////////////////////////////////////////// | 225 //////////////////////////////////////////////////////////////////////////////// |
| 226 // sort out what kind of clip mask needs to be created: alpha, stencil, | 226 // sort out what kind of clip mask needs to be created: alpha, stencil, |
| 227 // scissor, or entirely software | 227 // scissor, or entirely software |
| 228 bool GrClipMaskManager::SetupClipping(GrContext* context, | 228 bool GrClipMaskManager::SetupClipping(GrContext* context, |
| 229 const GrPipelineBuilder& pipelineBuilder, | |
| 230 GrDrawContext* drawContext, | 229 GrDrawContext* drawContext, |
| 231 const GrClipStackClip& clip, | 230 const GrClipStackClip& clip, |
| 232 const SkRect* origDevBounds, | 231 const SkRect* origDevBounds, |
| 232 bool useHWAA, |
| 233 bool hasUserStencilSettings, |
| 233 GrAppliedClip* out) { | 234 GrAppliedClip* out) { |
| 234 if (!clip.clipStack() || clip.clipStack()->isWideOpen()) { | 235 if (!clip.clipStack() || clip.clipStack()->isWideOpen()) { |
| 235 return true; | 236 return true; |
| 236 } | 237 } |
| 237 | 238 |
| 238 GrReducedClip::ElementList elements; | 239 GrReducedClip::ElementList elements; |
| 239 int32_t genID = 0; | 240 int32_t genID = 0; |
| 240 GrReducedClip::InitialState initialState = GrReducedClip::kAllIn_InitialStat
e; | 241 GrReducedClip::InitialState initialState = GrReducedClip::kAllIn_InitialStat
e; |
| 241 SkIRect clipSpaceIBounds; | 242 SkIRect clipSpaceIBounds; |
| 242 bool requiresAA = false; | 243 bool requiresAA = false; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 if (elements.count() <= kMaxAnalyticElements) { | 287 if (elements.count() <= kMaxAnalyticElements) { |
| 287 SkVector clipToRTOffset = { SkIntToScalar(-clip.origin().fX), | 288 SkVector clipToRTOffset = { SkIntToScalar(-clip.origin().fX), |
| 288 SkIntToScalar(-clip.origin().fY) }; | 289 SkIntToScalar(-clip.origin().fY) }; |
| 289 // When there are multiple samples we want to do per-sample clipping, no
t compute a | 290 // When there are multiple samples we want to do per-sample clipping, no
t compute a |
| 290 // fractional pixel coverage. | 291 // fractional pixel coverage. |
| 291 bool disallowAnalyticAA = drawContext->isStencilBufferMultisampled(); | 292 bool disallowAnalyticAA = drawContext->isStencilBufferMultisampled(); |
| 292 if (disallowAnalyticAA && !drawContext->numColorSamples()) { | 293 if (disallowAnalyticAA && !drawContext->numColorSamples()) { |
| 293 // With a single color sample, any coverage info is lost from color
once it hits the | 294 // With a single color sample, any coverage info is lost from color
once it hits the |
| 294 // color buffer anyway, so we may as well use coverage AA if nothing
else in the pipe | 295 // color buffer anyway, so we may as well use coverage AA if nothing
else in the pipe |
| 295 // is multisampled. | 296 // is multisampled. |
| 296 disallowAnalyticAA = pipelineBuilder.isHWAntialias() || | 297 disallowAnalyticAA = useHWAA || hasUserStencilSettings; |
| 297 pipelineBuilder.hasUserStencilSettings(); | |
| 298 } | 298 } |
| 299 sk_sp<GrFragmentProcessor> clipFP; | 299 sk_sp<GrFragmentProcessor> clipFP; |
| 300 if (requiresAA && | 300 if (requiresAA && |
| 301 get_analytic_clip_processor(elements, disallowAnalyticAA, clipToRTOf
fset, devBounds, | 301 get_analytic_clip_processor(elements, disallowAnalyticAA, clipToRTOf
fset, devBounds, |
| 302 &clipFP)) { | 302 &clipFP)) { |
| 303 SkIRect scissorSpaceIBounds(clipSpaceIBounds); | 303 SkIRect scissorSpaceIBounds(clipSpaceIBounds); |
| 304 scissorSpaceIBounds.offset(-clip.origin()); | 304 scissorSpaceIBounds.offset(-clip.origin()); |
| 305 if (!SkRect::Make(scissorSpaceIBounds).contains(devBounds)) { | 305 if (!SkRect::Make(scissorSpaceIBounds).contains(devBounds)) { |
| 306 out->makeScissoredFPBased(std::move(clipFP), scissorSpaceIBounds
); | 306 out->makeScissoredFPBased(std::move(clipFP), scissorSpaceIBounds
); |
| 307 return true; | 307 return true; |
| 308 } | 308 } |
| 309 out->makeFPBased(std::move(clipFP), SkRect::Make(scissorSpaceIBounds
)); | 309 out->makeFPBased(std::move(clipFP), SkRect::Make(scissorSpaceIBounds
)); |
| 310 return true; | 310 return true; |
| 311 } | 311 } |
| 312 } | 312 } |
| 313 | 313 |
| 314 // If the stencil buffer is multisampled we can use it to do everything. | 314 // If the stencil buffer is multisampled we can use it to do everything. |
| 315 if (!drawContext->isStencilBufferMultisampled() && requiresAA) { | 315 if (!drawContext->isStencilBufferMultisampled() && requiresAA) { |
| 316 sk_sp<GrTexture> result; | 316 sk_sp<GrTexture> result; |
| 317 | 317 |
| 318 // The top-left of the mask corresponds to the top-left corner of the bo
unds. | 318 // The top-left of the mask corresponds to the top-left corner of the bo
unds. |
| 319 SkVector clipToMaskOffset = { | 319 SkVector clipToMaskOffset = { |
| 320 SkIntToScalar(-clipSpaceIBounds.fLeft), | 320 SkIntToScalar(-clipSpaceIBounds.fLeft), |
| 321 SkIntToScalar(-clipSpaceIBounds.fTop) | 321 SkIntToScalar(-clipSpaceIBounds.fTop) |
| 322 }; | 322 }; |
| 323 | 323 |
| 324 if (UseSWOnlyPath(context, pipelineBuilder, drawContext, | 324 if (UseSWOnlyPath(context, hasUserStencilSettings, drawContext, |
| 325 clipToMaskOffset, elements)) { | 325 clipToMaskOffset, elements)) { |
| 326 // The clip geometry is complex enough that it will be more efficien
t to create it | 326 // The clip geometry is complex enough that it will be more efficien
t to create it |
| 327 // entirely in software | 327 // entirely in software |
| 328 result = CreateSoftwareClipMask(context->textureProvider(), | 328 result = CreateSoftwareClipMask(context->textureProvider(), |
| 329 genID, | 329 genID, |
| 330 initialState, | 330 initialState, |
| 331 elements, | 331 elements, |
| 332 clipToMaskOffset, | 332 clipToMaskOffset, |
| 333 clipSpaceIBounds); | 333 clipSpaceIBounds); |
| 334 } else { | 334 } else { |
| (...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 805 sk_sp<GrTexture> result(texProvider->createApproxTexture(desc)); | 805 sk_sp<GrTexture> result(texProvider->createApproxTexture(desc)); |
| 806 if (!result) { | 806 if (!result) { |
| 807 return nullptr; | 807 return nullptr; |
| 808 } | 808 } |
| 809 result->resourcePriv().setUniqueKey(key); | 809 result->resourcePriv().setUniqueKey(key); |
| 810 | 810 |
| 811 helper.toTexture(result.get()); | 811 helper.toTexture(result.get()); |
| 812 | 812 |
| 813 return result; | 813 return result; |
| 814 } | 814 } |
| OLD | NEW |