diff options
author | Brian Salomon <bsalomon@google.com> | 2018-07-09 10:31:47 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-07-09 14:54:16 +0000 |
commit | 1354048c8fa885b83e414532c011d710590d6b46 (patch) | |
tree | e3fd906497340adbd73e5a1bbebc50c4f4ef4d15 /src/gpu/GrClipStackClip.cpp | |
parent | 373224c9ab3ae3f13c45f61521e01c282016fde0 (diff) |
Add genIDs from all contributing elements to GrReducedClip's mask key.
Change-Id: I3fed124ba3fefd1ef82acdb4ace9531d0c89ad8b
Reviewed-on: https://skia-review.googlesource.com/138586
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'src/gpu/GrClipStackClip.cpp')
-rw-r--r-- | src/gpu/GrClipStackClip.cpp | 84 |
1 files changed, 33 insertions, 51 deletions
diff --git a/src/gpu/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp index 68c18be5e8..dea60ff3b4 100644 --- a/src/gpu/GrClipStackClip.cpp +++ b/src/gpu/GrClipStackClip.cpp @@ -27,11 +27,10 @@ #include "effects/GrRRectEffect.h" #include "effects/GrTextureDomain.h" -typedef SkClipStack::Element Element; -typedef GrReducedClip::InitialState InitialState; -typedef GrReducedClip::ElementList ElementList; - -const char GrClipStackClip::kMaskTestTag[] = "clip_mask"; +using MaskElement = GrReducedClip::MaskElement; +using Element = SkClipStack::Element; +using InitialState = GrReducedClip::InitialState; +using ElementList = GrReducedClip::ElementList; bool GrClipStackClip::quickContains(const SkRect& rect) const { if (!fStack || fStack->isWideOpen()) { @@ -91,10 +90,10 @@ bool GrClipStackClip::PathNeedsSWRenderer(GrContext* context, bool hasUserStencilSettings, const GrRenderTargetContext* renderTargetContext, const SkMatrix& viewMatrix, - const Element* element, + const Element& element, GrPathRenderer** prOut, bool needsStencil) { - if (Element::DeviceSpaceType::kRect == element->getDeviceSpaceType()) { + if (Element::DeviceSpaceType::kRect == element.getDeviceSpaceType()) { // rects can always be drawn directly w/o using the software path // TODO: skip rrects once we're drawing them directly. if (prOut) { @@ -103,11 +102,11 @@ bool GrClipStackClip::PathNeedsSWRenderer(GrContext* context, return false; } else { // We shouldn't get here with an empty clip element. - SkASSERT(Element::DeviceSpaceType::kEmpty != element->getDeviceSpaceType()); + SkASSERT(Element::DeviceSpaceType::kEmpty != element.getDeviceSpaceType()); // the gpu alpha mask will draw the inverse paths as non-inverse to a temp buffer SkPath path; - element->asDeviceSpacePath(&path); + element.asDeviceSpacePath(&path); if (path.isInverseFillType()) { path.toggleInverseFillType(); } @@ -122,7 +121,7 @@ bool GrClipStackClip::PathNeedsSWRenderer(GrContext* context, canDrawArgs.fClipConservativeBounds = &scissorRect; canDrawArgs.fViewMatrix = &viewMatrix; canDrawArgs.fShape = &shape; - canDrawArgs.fAAType = GrChooseAAType(GrAA(element->isAA()), + canDrawArgs.fAAType = GrChooseAAType(GrAA(element.isAA()), renderTargetContext->fsaaType(), GrAllowMixedSamples::kYes, *context->contextPriv().caps()); @@ -162,10 +161,10 @@ bool GrClipStackClip::UseSWOnlyPath(GrContext* context, translate.setTranslate(SkIntToScalar(-reducedClip.left()), SkIntToScalar(-reducedClip.top())); for (ElementList::Iter iter(reducedClip.maskElements()); iter.get(); iter.next()) { - const Element* element = iter.get(); + const Element& element = iter.get()->fElement; - SkClipOp op = element->getOp(); - bool invert = element->isInverseFilled(); + SkClipOp op = element.getOp(); + bool invert = element.isInverseFilled(); bool needsStencil = invert || kIntersect_SkClipOp == op || kReverseDifference_SkClipOp == op; @@ -281,38 +280,25 @@ bool GrClipStackClip::applyClipMask(GrContext* context, GrRenderTargetContext* r renderTargetContext->setNeedsStencil(); - // 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 (renderTargetContext->priv().mustRenderClip(reducedClip.maskGenID(), reducedClip.scissor(), - reducedClip.numAnalyticFPs())) { + if (!renderTargetContext->priv().lastStencilClipKey().isValid() || + !reducedClip.maskUniqueKey().isValid() || + renderTargetContext->priv().lastStencilClipKey() != reducedClip.maskUniqueKey()) { reducedClip.drawStencilClipMask(context, renderTargetContext); - renderTargetContext->priv().setLastClip(reducedClip.maskGenID(), reducedClip.scissor(), - reducedClip.numAnalyticFPs()); + renderTargetContext->priv().setLastStencilClipKey(reducedClip.maskUniqueKey()); } - // GrAppliedClip doesn't need to figure numAnalyticFPs into its key (used by operator==) because - // it verifies the FPs are also equal. - out->hardClip().addStencilClip(reducedClip.maskGenID()); + // The enables the stencil test against the clip bit in the applied clip. + out->hardClip().addStencilClip(); return true; } //////////////////////////////////////////////////////////////////////////////// // Create a 8-bit clip mask in alpha -static void create_clip_mask_key(uint32_t clipGenID, const SkIRect& bounds, int numAnalyticFPs, - GrUniqueKey* key) { - static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); - GrUniqueKey::Builder builder(key, kDomain, 4, GrClipStackClip::kMaskTestTag); - builder[0] = clipGenID; - // SkToS16 because image filters outset layers to a size indicated by the filter, which can - // sometimes result in negative coordinates from device space. - builder[1] = SkToS16(bounds.fLeft) | (SkToS16(bounds.fRight) << 16); - builder[2] = SkToS16(bounds.fTop) | (SkToS16(bounds.fBottom) << 16); - builder[3] = numAnalyticFPs; -} - static void add_invalidate_on_pop_message(const SkClipStack& stack, uint32_t clipGenID, const GrUniqueKey& clipMaskKey) { + if (clipGenID == SK_InvalidGenID || !clipMaskKey.isValid()) { + return; + } SkClipStack::Iter iter(stack, SkClipStack::Iter::kTop_IterStart); while (const Element* element = iter.prev()) { if (element->getGenID() == clipGenID) { @@ -328,10 +314,7 @@ static void add_invalidate_on_pop_message(const SkClipStack& stack, uint32_t cli sk_sp<GrTextureProxy> GrClipStackClip::createAlphaClipMask(GrContext* context, const GrReducedClip& reducedClip) const { GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider(); - GrUniqueKey key; - create_clip_mask_key(reducedClip.maskGenID(), reducedClip.scissor(), - reducedClip.numAnalyticFPs(), &key); - + const GrUniqueKey& key = reducedClip.maskUniqueKey(); sk_sp<GrTextureProxy> proxy(proxyProvider->findOrCreateProxyByUniqueKey( key, kTopLeft_GrSurfaceOrigin)); if (proxy) { @@ -362,7 +345,7 @@ sk_sp<GrTextureProxy> GrClipStackClip::createAlphaClipMask(GrContext* context, SkASSERT(result->origin() == kTopLeft_GrSurfaceOrigin); proxyProvider->assignUniqueKeyToProxy(key, result.get()); - add_invalidate_on_pop_message(*fStack, reducedClip.maskGenID(), key); + add_invalidate_on_pop_message(*fStack, reducedClip.topMaskElementID(), key); return result; } @@ -406,9 +389,9 @@ static void draw_clip_elements_to_mask_helper(GrSWMaskHelper& helper, const Elem helper.clear(InitialState::kAllIn == initialState ? 0xFF : 0x00); for (ElementList::Iter iter(elements); iter.get(); iter.next()) { - const Element* element = iter.get(); - SkClipOp op = element->getOp(); - GrAA aa = GrAA(element->isAA()); + const Element& element = iter.get()->fElement; + SkClipOp op = element.getOp(); + GrAA aa = GrAA(element.isAA()); if (kIntersect_SkClipOp == op || kReverseDifference_SkClipOp == op) { // Intersect and reverse difference require modifying pixels outside of the geometry @@ -421,7 +404,7 @@ static void draw_clip_elements_to_mask_helper(GrSWMaskHelper& helper, const Elem helper.drawRect(temp, translate, SkRegion::kXOR_Op, GrAA::kNo, 0xFF); } SkPath clipPath; - element->asDeviceSpacePath(&clipPath); + element.asDeviceSpacePath(&clipPath); clipPath.toggleInverseFillType(); GrShape shape(clipPath, GrStyle::SimpleFill()); helper.drawShape(shape, translate, SkRegion::kReplace_Op, aa, 0x00); @@ -430,11 +413,11 @@ static void draw_clip_elements_to_mask_helper(GrSWMaskHelper& helper, const Elem // The other ops (union, xor, diff) only affect pixels inside // the geometry so they can just be drawn normally - if (Element::DeviceSpaceType::kRect == element->getDeviceSpaceType()) { - helper.drawRect(element->getDeviceSpaceRect(), translate, (SkRegion::Op)op, aa, 0xFF); + if (Element::DeviceSpaceType::kRect == element.getDeviceSpaceType()) { + helper.drawRect(element.getDeviceSpaceRect(), translate, (SkRegion::Op)op, aa, 0xFF); } else { SkPath path; - element->asDeviceSpacePath(&path); + element.asDeviceSpacePath(&path); GrShape shape(path, GrStyle::SimpleFill()); helper.drawShape(shape, translate, (SkRegion::Op)op, aa, 0xFF); } @@ -444,9 +427,7 @@ static void draw_clip_elements_to_mask_helper(GrSWMaskHelper& helper, const Elem sk_sp<GrTextureProxy> GrClipStackClip::createSoftwareClipMask( GrContext* context, const GrReducedClip& reducedClip, GrRenderTargetContext* renderTargetContext) const { - GrUniqueKey key; - create_clip_mask_key(reducedClip.maskGenID(), reducedClip.scissor(), - reducedClip.numAnalyticFPs(), &key); + const GrUniqueKey& key = reducedClip.maskUniqueKey(); GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider(); @@ -503,6 +484,7 @@ sk_sp<GrTextureProxy> GrClipStackClip::createSoftwareClipMask( SkASSERT(proxy->origin() == kTopLeft_GrSurfaceOrigin); proxyProvider->assignUniqueKeyToProxy(key, proxy.get()); - add_invalidate_on_pop_message(*fStack, reducedClip.maskGenID(), key); + add_invalidate_on_pop_message(*fStack, reducedClip.topMaskElementID(), key); + return proxy; } |