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