Improve usage of window rectangles
* Skips non-AA diff rect elements and replaces them with window
rectangles.
* Places window rectangles in the interiors of antialiased diff rects.
* Arranges two overlapping window rectangles in a plus shape inside of
diff rounded rects.
* Enables window rectangles when clearing and generating clip masks.
GTX 960 perf result (with vs. without window rectangles):
glinst4 msaa16 gpu
keymobi_pinterest.skp 0.48 -> 0.17 [ 35%] 2.77 -> 1.49 [ 54%] 0.22 -> 0.16 [ 70%]
keymobi_digg_com.skp 0.42 -> 0.23 [ 55%] 2.34 -> 1.08 [ 46%] 0.25 -> 0.21 [ 83%]
desk_jsfiddlebigcar.skp 0.28 -> 0.16 [ 59%] 1.70 -> 0.96 [ 57%] 0.19 -> 0.14 [ 70%]
top25desk_wordpress.skp 0.45 -> 0.18 [ 40%] 2.78 -> 1.53 [ 55%] 0.21 -> 0.19 [ 94%]
top25desk_weather_com.skp 2.01 -> 1.93 [ 96%] 23.5 -> 2.54 [ 11%] 1.90 -> 1.68 [ 88%]
keymobi_blogger.skp 0.57 -> 0.37 [ 65%] 2.87 -> 1.54 [ 54%] 0.43 -> 0.33 [ 77%]
keymobi_linkedin.skp 0.32 -> 0.17 [ 51%] 1.93 -> 1.04 [ 54%] 0.17 -> 0.15 [ 91%]
keymobi_bing_com_search_... 0.29 -> 0.25 [ 83%] 1.85 -> 1.23 [ 66%] 0.50 -> 0.24 [ 48%]
keymobi_theverge_com_201... 1.00 -> 0.67 [ 68%] 9.46 -> 3.84 [ 41%] 0.72 -> 0.65 [ 90%]
keymobi_sfgate_com_.skp 1.56 -> 1.13 [ 72%] 4.49 -> 2.86 [ 64%] 1.54 -> 1.11 [ 72%]
...
GEOMEAN (All 79 blink skps) 1.04 -> 0.90 [ 86%] 4.22 -> 2.81 [ 67%] 0.95 -> 0.89 [ 94%]
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2289363005
Committed: https://skia.googlesource.com/skia/+/db42be9a326c747ff92ed1da8c3536c5b3e8e22b
Review-Url: https://codereview.chromium.org/2289363005
diff --git a/src/gpu/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp
index 4572db5..d6ad1d9 100644
--- a/src/gpu/GrClipStackClip.cpp
+++ b/src/gpu/GrClipStackClip.cpp
@@ -287,11 +287,14 @@
return false;
}
+ GrRenderTarget* rt = drawContext->accessRenderTarget();
+
const SkScalar clipX = SkIntToScalar(fOrigin.x()),
clipY = SkIntToScalar(fOrigin.y());
SkRect clipSpaceDevBounds = devBounds.makeOffset(clipX, clipY);
- const GrReducedClip reducedClip(*fStack, clipSpaceDevBounds);
+ const GrReducedClip reducedClip(*fStack, clipSpaceDevBounds,
+ rt->renderTargetPriv().maxWindowRectangles());
if (reducedClip.hasIBounds() &&
!GrClip::IsInsideClip(reducedClip.ibounds(), clipSpaceDevBounds)) {
@@ -300,29 +303,17 @@
out->addScissor(scissorSpaceIBounds);
}
+ if (!reducedClip.windowRectangles().empty()) {
+ out->addWindowRectangles(reducedClip.windowRectangles(), fOrigin,
+ GrWindowRectsState::Mode::kExclusive);
+ }
+
if (reducedClip.elements().isEmpty()) {
return InitialState::kAllIn == reducedClip.initialState();
}
SkASSERT(reducedClip.hasIBounds());
- // Attempt to implement difference clip rects with window rectangles. This will eventually
- // become more comprehensive.
- if (drawContext->accessRenderTarget()->renderTargetPriv().supportsWindowRectangles() &&
- 1 == reducedClip.elements().count() && !reducedClip.requiresAA() &&
- InitialState::kAllIn == reducedClip.initialState()) {
- const Element* element = reducedClip.elements().head();
- SkRegion::Op op = element->getOp();
- if (Element::kRect_Type == element->getType() &&
- (SkRegion::kDifference_Op == op || SkRegion::kXOR_Op == op)) {
- SkIRect window;
- element->getRect().round(&window);
- window.offset(-fOrigin);
- out->addWindowRectangle(window);
- return true;
- }
- }
-
// An element count of 4 was chosen because of the common pattern in Blink of:
// isect RR
// diff RR
@@ -377,12 +368,15 @@
// use the stencil clip if we can't represent the clip as a rectangle.
// TODO: these need to be swapped over to using a StencilAttachmentProxy
GrStencilAttachment* stencilAttachment =
- context->resourceProvider()->attachStencilAttachment(drawContext->accessRenderTarget());
+ context->resourceProvider()->attachStencilAttachment(rt);
if (nullptr == stencilAttachment) {
SkDebugf("WARNING: failed to attach stencil buffer for clip mask. Clip will be ignored.\n");
return true;
}
+ // This relies on the property that a reduced sub-rect of the last clip will contain all the
+ // relevant window rectangles that were in the last clip. This subtle requirement will go away
+ // after clipping is overhauled.
if (stencilAttachment->mustRenderClip(reducedClip.elementsGenID(), reducedClip.ibounds(),
fOrigin)) {
reducedClip.drawStencilClipMask(context, drawContext, fOrigin);