OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 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 "GrClipStackClip.h" | 8 #include "GrClipStackClip.h" |
9 | 9 |
10 #include "GrAppliedClip.h" | 10 #include "GrAppliedClip.h" |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 bool hasUserStencilSettings, GrAppliedClip* out) con
st { | 280 bool hasUserStencilSettings, GrAppliedClip* out) con
st { |
281 if (!fStack || fStack->isWideOpen()) { | 281 if (!fStack || fStack->isWideOpen()) { |
282 return true; | 282 return true; |
283 } | 283 } |
284 | 284 |
285 SkRect devBounds = SkRect::MakeIWH(drawContext->width(), drawContext->height
()); | 285 SkRect devBounds = SkRect::MakeIWH(drawContext->width(), drawContext->height
()); |
286 if (!devBounds.intersect(out->clippedDrawBounds())) { | 286 if (!devBounds.intersect(out->clippedDrawBounds())) { |
287 return false; | 287 return false; |
288 } | 288 } |
289 | 289 |
290 GrRenderTarget* rt = drawContext->accessRenderTarget(); | |
291 | |
292 const SkScalar clipX = SkIntToScalar(fOrigin.x()), | 290 const SkScalar clipX = SkIntToScalar(fOrigin.x()), |
293 clipY = SkIntToScalar(fOrigin.y()); | 291 clipY = SkIntToScalar(fOrigin.y()); |
294 | 292 |
295 SkRect clipSpaceDevBounds = devBounds.makeOffset(clipX, clipY); | 293 SkRect clipSpaceDevBounds = devBounds.makeOffset(clipX, clipY); |
296 const GrReducedClip reducedClip(*fStack, clipSpaceDevBounds, | 294 const GrReducedClip reducedClip(*fStack, clipSpaceDevBounds); |
297 rt->renderTargetPriv().maxWindowRectangles()
); | |
298 | 295 |
299 if (reducedClip.hasIBounds() && | 296 if (reducedClip.hasIBounds() && |
300 !GrClip::IsInsideClip(reducedClip.ibounds(), clipSpaceDevBounds)) { | 297 !GrClip::IsInsideClip(reducedClip.ibounds(), clipSpaceDevBounds)) { |
301 SkIRect scissorSpaceIBounds(reducedClip.ibounds()); | 298 SkIRect scissorSpaceIBounds(reducedClip.ibounds()); |
302 scissorSpaceIBounds.offset(-fOrigin); | 299 scissorSpaceIBounds.offset(-fOrigin); |
303 out->addScissor(scissorSpaceIBounds); | 300 out->addScissor(scissorSpaceIBounds); |
304 } | 301 } |
305 | 302 |
306 if (!reducedClip.windowRectangles().empty()) { | |
307 out->addWindowRectangles(reducedClip.windowRectangles(), fOrigin, | |
308 GrWindowRectsState::Mode::kExclusive); | |
309 } | |
310 | |
311 if (reducedClip.elements().isEmpty()) { | 303 if (reducedClip.elements().isEmpty()) { |
312 return InitialState::kAllIn == reducedClip.initialState(); | 304 return InitialState::kAllIn == reducedClip.initialState(); |
313 } | 305 } |
314 | 306 |
315 SkASSERT(reducedClip.hasIBounds()); | 307 SkASSERT(reducedClip.hasIBounds()); |
316 | 308 |
| 309 // Attempt to implement difference clip rects with window rectangles. This w
ill eventually |
| 310 // become more comprehensive. |
| 311 if (drawContext->accessRenderTarget()->renderTargetPriv().supportsWindowRect
angles() && |
| 312 1 == reducedClip.elements().count() && !reducedClip.requiresAA() && |
| 313 InitialState::kAllIn == reducedClip.initialState()) { |
| 314 const Element* element = reducedClip.elements().head(); |
| 315 SkRegion::Op op = element->getOp(); |
| 316 if (Element::kRect_Type == element->getType() && |
| 317 (SkRegion::kDifference_Op == op || SkRegion::kXOR_Op == op)) { |
| 318 SkIRect window; |
| 319 element->getRect().round(&window); |
| 320 window.offset(-fOrigin); |
| 321 out->addWindowRectangle(window); |
| 322 return true; |
| 323 } |
| 324 } |
| 325 |
317 // An element count of 4 was chosen because of the common pattern in Blink o
f: | 326 // An element count of 4 was chosen because of the common pattern in Blink o
f: |
318 // isect RR | 327 // isect RR |
319 // diff RR | 328 // diff RR |
320 // isect convex_poly | 329 // isect convex_poly |
321 // isect convex_poly | 330 // isect convex_poly |
322 // when drawing rounded div borders. This could probably be tuned based on a | 331 // when drawing rounded div borders. This could probably be tuned based on a |
323 // configuration's relative costs of switching RTs to generate a mask vs | 332 // configuration's relative costs of switching RTs to generate a mask vs |
324 // longer shaders. | 333 // longer shaders. |
325 if (reducedClip.elements().count() <= kMaxAnalyticElements) { | 334 if (reducedClip.elements().count() <= kMaxAnalyticElements) { |
326 // When there are multiple samples we want to do per-sample clipping, no
t compute a | 335 // When there are multiple samples we want to do per-sample clipping, no
t compute a |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 rtSpaceMaskBounds.offset(-fOrigin); | 370 rtSpaceMaskBounds.offset(-fOrigin); |
362 out->addCoverageFP(create_fp_for_mask(result.get(), rtSpaceMaskBound
s)); | 371 out->addCoverageFP(create_fp_for_mask(result.get(), rtSpaceMaskBound
s)); |
363 return true; | 372 return true; |
364 } | 373 } |
365 // if alpha clip mask creation fails fall through to the non-AA code pat
hs | 374 // if alpha clip mask creation fails fall through to the non-AA code pat
hs |
366 } | 375 } |
367 | 376 |
368 // use the stencil clip if we can't represent the clip as a rectangle. | 377 // use the stencil clip if we can't represent the clip as a rectangle. |
369 // TODO: these need to be swapped over to using a StencilAttachmentProxy | 378 // TODO: these need to be swapped over to using a StencilAttachmentProxy |
370 GrStencilAttachment* stencilAttachment = | 379 GrStencilAttachment* stencilAttachment = |
371 context->resourceProvider()->attachStencilAttachment(rt); | 380 context->resourceProvider()->attachStencilAttachment(drawContext->access
RenderTarget()); |
372 if (nullptr == stencilAttachment) { | 381 if (nullptr == stencilAttachment) { |
373 SkDebugf("WARNING: failed to attach stencil buffer for clip mask. Clip w
ill be ignored.\n"); | 382 SkDebugf("WARNING: failed to attach stencil buffer for clip mask. Clip w
ill be ignored.\n"); |
374 return true; | 383 return true; |
375 } | 384 } |
376 | 385 |
377 // This relies on the property that a reduced sub-rect of the last clip will
contain all the | |
378 // relevant window rectangles that were in the last clip. This subtle requir
ement will go away | |
379 // after clipping is overhauled. | |
380 if (stencilAttachment->mustRenderClip(reducedClip.elementsGenID(), reducedCl
ip.ibounds(), | 386 if (stencilAttachment->mustRenderClip(reducedClip.elementsGenID(), reducedCl
ip.ibounds(), |
381 fOrigin)) { | 387 fOrigin)) { |
382 reducedClip.drawStencilClipMask(context, drawContext, fOrigin); | 388 reducedClip.drawStencilClipMask(context, drawContext, fOrigin); |
383 stencilAttachment->setLastClip(reducedClip.elementsGenID(), reducedClip.
ibounds(), | 389 stencilAttachment->setLastClip(reducedClip.elementsGenID(), reducedClip.
ibounds(), |
384 fOrigin); | 390 fOrigin); |
385 } | 391 } |
386 out->addStencilClip(); | 392 out->addStencilClip(); |
387 return true; | 393 return true; |
388 } | 394 } |
389 | 395 |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 sk_sp<GrTexture> result(texProvider->createApproxTexture(desc)); | 502 sk_sp<GrTexture> result(texProvider->createApproxTexture(desc)); |
497 if (!result) { | 503 if (!result) { |
498 return nullptr; | 504 return nullptr; |
499 } | 505 } |
500 result->resourcePriv().setUniqueKey(key); | 506 result->resourcePriv().setUniqueKey(key); |
501 | 507 |
502 helper.toTexture(result.get()); | 508 helper.toTexture(result.get()); |
503 | 509 |
504 return result; | 510 return result; |
505 } | 511 } |
OLD | NEW |