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 "GrGpuResourcePriv.h" | 12 #include "GrGpuResourcePriv.h" |
13 #include "GrPaint.h" | 13 #include "GrPaint.h" |
14 #include "GrPathRenderer.h" | 14 #include "GrPathRenderer.h" |
15 #include "GrRenderTarget.h" | 15 #include "GrRenderTarget.h" |
16 #include "GrRenderTargetPriv.h" | 16 #include "GrRenderTargetPriv.h" |
17 #include "GrResourceProvider.h" | 17 #include "GrResourceProvider.h" |
18 #include "GrStencilAttachment.h" | 18 #include "GrStencilAttachment.h" |
19 #include "GrSWMaskHelper.h" | 19 #include "GrSWMaskHelper.h" |
20 #include "SkRasterClip.h" | 20 #include "SkRasterClip.h" |
21 #include "SkTLazy.h" | 21 #include "SkTLazy.h" |
22 #include "batches/GrRectBatchFactory.h" | 22 #include "batches/GrRectBatchFactory.h" |
23 #include "effects/GrConvexPolyEffect.h" | 23 #include "effects/GrConvexPolyEffect.h" |
24 #include "effects/GrPorterDuffXferProcessor.h" | 24 #include "effects/GrPorterDuffXferProcessor.h" |
25 #include "effects/GrRRectEffect.h" | 25 #include "effects/GrRRectEffect.h" |
26 #include "effects/GrTextureDomain.h" | 26 #include "effects/GrTextureDomain.h" |
27 | 27 |
28 typedef SkClipStack::Element Element; | 28 typedef SkClipStack::Element Element; |
| 29 typedef GrReducedClip::InitialState InitialState; |
29 | 30 |
30 static const int kMaxAnalyticElements = 4; | 31 static const int kMaxAnalyticElements = 4; |
31 | 32 |
32 //////////////////////////////////////////////////////////////////////////////// | 33 //////////////////////////////////////////////////////////////////////////////// |
33 // set up the draw state to enable the aa clipping mask. Besides setting up the | 34 // set up the draw state to enable the aa clipping mask. Besides setting up the |
34 // stage matrix this also alters the vertex layout | 35 // stage matrix this also alters the vertex layout |
35 static sk_sp<GrFragmentProcessor> create_fp_for_mask(GrTexture* result, | 36 static sk_sp<GrFragmentProcessor> create_fp_for_mask(GrTexture* result, |
36 const SkIRect &devBound) { | 37 const SkIRect &devBound) { |
37 SkMatrix mat; | 38 SkMatrix mat; |
38 // We use device coords to compute the texture coordinates. We set our matri
x to be a | 39 // We use device coords to compute the texture coordinates. We set our matri
x to be a |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 GrDrawContext* drawContext, | 231 GrDrawContext* drawContext, |
231 const GrClipStackClip& clip, | 232 const GrClipStackClip& clip, |
232 const SkRect* origDevBounds, | 233 const SkRect* origDevBounds, |
233 bool useHWAA, | 234 bool useHWAA, |
234 bool hasUserStencilSettings, | 235 bool hasUserStencilSettings, |
235 GrAppliedClip* out) { | 236 GrAppliedClip* out) { |
236 if (!clip.clipStack() || clip.clipStack()->isWideOpen()) { | 237 if (!clip.clipStack() || clip.clipStack()->isWideOpen()) { |
237 return true; | 238 return true; |
238 } | 239 } |
239 | 240 |
| 241 const SkScalar clipX = clip.origin().x(), |
| 242 clipY = clip.origin().y(); |
| 243 SkRect devBounds = SkRect::MakeIWH(drawContext->width(), drawContext->height
()); |
| 244 if (!devBounds.intersect(devBounds.makeOffset(-clipX, -clipY))) { |
| 245 return false; |
| 246 } |
| 247 if (origDevBounds && !devBounds.intersect(*origDevBounds)) { |
| 248 return false; |
| 249 } |
| 250 |
240 GrReducedClip::ElementList elements; | 251 GrReducedClip::ElementList elements; |
241 int32_t genID = 0; | 252 int32_t genID = 0; |
242 GrReducedClip::InitialState initialState = GrReducedClip::kAllIn_InitialStat
e; | |
243 SkIRect clipSpaceIBounds; | 253 SkIRect clipSpaceIBounds; |
244 bool requiresAA = false; | 254 bool requiresAA = false; |
245 | 255 |
246 SkIRect clipSpaceReduceQueryBounds; | 256 InitialState initialState = GrReducedClip::ReduceClipStack(*clip.clipStack()
, |
247 SkRect devBounds; | 257 devBounds.makeOff
set(clipX, clipY), |
248 if (origDevBounds) { | 258 &elements, |
249 if (!devBounds.intersect(SkRect::MakeIWH(drawContext->width(), drawConte
xt->height()), | 259 &genID, |
250 *origDevBounds)) { | 260 &clipSpaceIBounds
, |
251 return false; | 261 &requiresAA); |
252 } | |
253 devBounds.roundOut(&clipSpaceReduceQueryBounds); | |
254 clipSpaceReduceQueryBounds.offset(clip.origin()); | |
255 } else { | |
256 devBounds = SkRect::MakeIWH(drawContext->width(), drawContext->height())
; | |
257 clipSpaceReduceQueryBounds.setXYWH(0, 0, drawContext->width(), drawConte
xt->height()); | |
258 clipSpaceReduceQueryBounds.offset(clip.origin()); | |
259 } | |
260 GrReducedClip::ReduceClipStack(*clip.clipStack(), | |
261 clipSpaceReduceQueryBounds, | |
262 &elements, | |
263 &genID, | |
264 &initialState, | |
265 &clipSpaceIBounds, | |
266 &requiresAA); | |
267 if (elements.isEmpty()) { | 262 if (elements.isEmpty()) { |
268 if (GrReducedClip::kAllOut_InitialState == initialState) { | 263 if (GrReducedClip::kAllOut_InitialState == initialState) { |
269 return false; | 264 return false; |
270 } else { | 265 } else { |
271 SkIRect scissorSpaceIBounds(clipSpaceIBounds); | 266 SkIRect scissorSpaceIBounds(clipSpaceIBounds); |
272 scissorSpaceIBounds.offset(-clip.origin()); | 267 scissorSpaceIBounds.offset(-clip.origin()); |
273 if (!GrClip::CanIgnoreScissor(scissorSpaceIBounds, devBounds)) { | 268 if (!GrClip::IsInsideClip(scissorSpaceIBounds, devBounds)) { |
274 out->makeScissored(scissorSpaceIBounds); | 269 out->makeScissored(scissorSpaceIBounds); |
275 } | 270 } |
276 return true; | 271 return true; |
277 } | 272 } |
278 } | 273 } |
279 | 274 |
280 // An element count of 4 was chosen because of the common pattern in Blink o
f: | 275 // An element count of 4 was chosen because of the common pattern in Blink o
f: |
281 // isect RR | 276 // isect RR |
282 // diff RR | 277 // diff RR |
283 // isect convex_poly | 278 // isect convex_poly |
284 // isect convex_poly | 279 // isect convex_poly |
285 // when drawing rounded div borders. This could probably be tuned based on a | 280 // when drawing rounded div borders. This could probably be tuned based on a |
286 // configuration's relative costs of switching RTs to generate a mask vs | 281 // configuration's relative costs of switching RTs to generate a mask vs |
287 // longer shaders. | 282 // longer shaders. |
288 if (elements.count() <= kMaxAnalyticElements) { | 283 if (elements.count() <= kMaxAnalyticElements) { |
289 SkVector clipToRTOffset = { SkIntToScalar(-clip.origin().fX), | 284 SkVector clipToRTOffset = { SkIntToScalar(-clipX), SkIntToScalar(-clipY)
}; |
290 SkIntToScalar(-clip.origin().fY) }; | |
291 // When there are multiple samples we want to do per-sample clipping, no
t compute a | 285 // When there are multiple samples we want to do per-sample clipping, no
t compute a |
292 // fractional pixel coverage. | 286 // fractional pixel coverage. |
293 bool disallowAnalyticAA = drawContext->isStencilBufferMultisampled(); | 287 bool disallowAnalyticAA = drawContext->isStencilBufferMultisampled(); |
294 if (disallowAnalyticAA && !drawContext->numColorSamples()) { | 288 if (disallowAnalyticAA && !drawContext->numColorSamples()) { |
295 // With a single color sample, any coverage info is lost from color
once it hits the | 289 // With a single color sample, any coverage info is lost from color
once it hits the |
296 // color buffer anyway, so we may as well use coverage AA if nothing
else in the pipe | 290 // color buffer anyway, so we may as well use coverage AA if nothing
else in the pipe |
297 // is multisampled. | 291 // is multisampled. |
298 disallowAnalyticAA = useHWAA || hasUserStencilSettings; | 292 disallowAnalyticAA = useHWAA || hasUserStencilSettings; |
299 } | 293 } |
300 sk_sp<GrFragmentProcessor> clipFP; | 294 sk_sp<GrFragmentProcessor> clipFP; |
301 if (requiresAA && | 295 if (requiresAA && |
302 get_analytic_clip_processor(elements, disallowAnalyticAA, clipToRTOf
fset, devBounds, | 296 get_analytic_clip_processor(elements, disallowAnalyticAA, clipToRTOf
fset, devBounds, |
303 &clipFP)) { | 297 &clipFP)) { |
304 SkIRect scissorSpaceIBounds(clipSpaceIBounds); | 298 SkIRect scissorSpaceIBounds(clipSpaceIBounds); |
305 scissorSpaceIBounds.offset(-clip.origin()); | 299 scissorSpaceIBounds.offset(-clip.origin()); |
306 if (GrClip::CanIgnoreScissor(scissorSpaceIBounds, devBounds)) { | 300 if (GrClip::IsInsideClip(scissorSpaceIBounds, devBounds)) { |
307 out->makeFPBased(std::move(clipFP), SkRect::Make(scissorSpaceIBo
unds)); | 301 out->makeFPBased(std::move(clipFP), SkRect::Make(scissorSpaceIBo
unds)); |
308 } else { | 302 } else { |
309 out->makeScissoredFPBased(std::move(clipFP), scissorSpaceIBounds
); | 303 out->makeScissoredFPBased(std::move(clipFP), scissorSpaceIBounds
); |
310 } | 304 } |
311 return true; | 305 return true; |
312 } | 306 } |
313 } | 307 } |
314 | 308 |
315 // If the stencil buffer is multisampled we can use it to do everything. | 309 // If the stencil buffer is multisampled we can use it to do everything. |
316 if (!drawContext->isStencilBufferMultisampled() && requiresAA) { | 310 if (!drawContext->isStencilBufferMultisampled() && requiresAA) { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 initialState, | 357 initialState, |
364 elements, | 358 elements, |
365 clipSpaceIBounds, | 359 clipSpaceIBounds, |
366 clipSpaceToStencilSpaceOffset); | 360 clipSpaceToStencilSpaceOffset); |
367 | 361 |
368 // This must occur after createStencilClipMask. That function may change the
scissor. Also, it | 362 // This must occur after createStencilClipMask. That function may change the
scissor. Also, it |
369 // only guarantees that the stencil mask is correct within the bounds it was
passed, so we must | 363 // only guarantees that the stencil mask is correct within the bounds it was
passed, so we must |
370 // use both stencil and scissor test to the bounds for the final draw. | 364 // use both stencil and scissor test to the bounds for the final draw. |
371 SkIRect scissorSpaceIBounds(clipSpaceIBounds); | 365 SkIRect scissorSpaceIBounds(clipSpaceIBounds); |
372 scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset); | 366 scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset); |
373 if (GrClip::CanIgnoreScissor(scissorSpaceIBounds, devBounds)) { | 367 if (GrClip::IsInsideClip(scissorSpaceIBounds, devBounds)) { |
374 out->makeStencil(true, devBounds); | 368 out->makeStencil(true, devBounds); |
375 } else { | 369 } else { |
376 out->makeScissoredStencil(scissorSpaceIBounds); | 370 out->makeScissoredStencil(scissorSpaceIBounds); |
377 } | 371 } |
378 return true; | 372 return true; |
379 } | 373 } |
380 | 374 |
381 static bool stencil_element(GrDrawContext* dc, | 375 static bool stencil_element(GrDrawContext* dc, |
382 const GrFixedClip& clip, | 376 const GrFixedClip& clip, |
383 const GrUserStencilSettings* ss, | 377 const GrUserStencilSettings* ss, |
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
810 sk_sp<GrTexture> result(texProvider->createApproxTexture(desc)); | 804 sk_sp<GrTexture> result(texProvider->createApproxTexture(desc)); |
811 if (!result) { | 805 if (!result) { |
812 return nullptr; | 806 return nullptr; |
813 } | 807 } |
814 result->resourcePriv().setUniqueKey(key); | 808 result->resourcePriv().setUniqueKey(key); |
815 | 809 |
816 helper.toTexture(result.get()); | 810 helper.toTexture(result.get()); |
817 | 811 |
818 return result; | 812 return result; |
819 } | 813 } |
OLD | NEW |