diff options
author | Chris Dalton <csmartdalton@google.com> | 2017-11-01 19:21:24 +0000 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-11-01 19:21:31 +0000 |
commit | d8d1593b22d59114480cc5b7cb9eba7c4ac029fc (patch) | |
tree | 34c04f120dc4e1e6c5ab0413584662d9a5dfa7e7 | |
parent | 721718059f39b0a5cff29028e30bc089e21a1244 (diff) |
Revert "Fold analytic clip FPs into GrReducedClip"
This reverts commit d29e0da3523e390eeb77b5a823d7ff86569ac1d3.
Reason for revert: More asserts
Original change's description:
> Fold analytic clip FPs into GrReducedClip
>
> Perf result on Pixel phone (sorted by impact):
>
> GEOMEAN 6.73 -> 6.49 ms [96% ]
>
> top25desk_pinterest.skp 0.45 -> 0.49 ms [107%]
> desk_pokemonwiki.skp 14.6 -> 15.9 ms [106%]
> keymobi_pinterest.skp 0.47 -> 0.49 ms [104%]
> ...
> keymobi_androidpolice_com_2012_.skp 3.69 -> 3.09 ms [83% ]
> keymobi_shop_mobileweb_ebay_com.skp 2.90 -> 2.29 ms [78% ]
> keymobi_boingboing_net.skp 2.95 -> 2.29 ms [76% ]
> desk_jsfiddlebigcar.skp 1.79 -> 1.29 ms [71% ]
> keymobi_m_youtube_com_watch_v_9.skp 12.9 -> 9.09 ms [70% ]
> keymobi_blogger.skp 3.80 -> 2.69 ms [70% ]
> keymobi_sfgate_com_.skp 8.16 -> 5.69 ms [69% ]
>
> Cleaner code, improved skps, slightly better geometric mean time.
>
> Pixel C is mostly unaffected, presumably because it uses window
> rectangles.
>
> Bug: skia:7190
> Change-Id: I9c7f3512ca57e1d1afcd42865357b63ffcc192ce
> Reviewed-on: https://skia-review.googlesource.com/66280
> Reviewed-by: Brian Salomon <bsalomon@google.com>
> Commit-Queue: Chris Dalton <csmartdalton@google.com>
TBR=bsalomon@google.com,csmartdalton@google.com
Change-Id: Ia91076d7b7a240798f1543f892d41a2968b421ae
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:7190
Reviewed-on: https://skia-review.googlesource.com/66184
Reviewed-by: Chris Dalton <csmartdalton@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
-rw-r--r-- | src/gpu/GrClipStackClip.cpp | 159 | ||||
-rw-r--r-- | src/gpu/GrReducedClip.cpp | 111 | ||||
-rw-r--r-- | src/gpu/GrReducedClip.h | 26 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetContextPriv.h | 10 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetOpList.h | 1 |
5 files changed, 153 insertions, 154 deletions
diff --git a/src/gpu/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp index b18cb16c44..aa2b9fdd29 100644 --- a/src/gpu/GrClipStackClip.cpp +++ b/src/gpu/GrClipStackClip.cpp @@ -30,15 +30,7 @@ typedef SkClipStack::Element Element; typedef GrReducedClip::InitialState InitialState; typedef GrReducedClip::ElementList ElementList; -// An element count of 4 was chosen because of the common pattern in Blink of: -// isect RR -// diff RR -// isect convex_poly -// isect convex_poly -// when drawing rounded div borders. This could probably be tuned based on a configuration's -// relative costs of switching RTs to generate a mask vs longer shaders. static const int kMaxAnalyticElements = 4; - const char GrClipStackClip::kMaskTestTag[] = "clip_mask"; bool GrClipStackClip::quickContains(const SkRect& rect) const { @@ -184,6 +176,80 @@ bool GrClipStackClip::UseSWOnlyPath(GrContext* context, return false; } +static bool get_analytic_clip_processor(const ElementList& elements, + bool abortIfAA, + const SkRect& drawDevBounds, + std::unique_ptr<GrFragmentProcessor>* resultFP) { + SkASSERT(elements.count() <= kMaxAnalyticElements); + SkSTArray<kMaxAnalyticElements, std::unique_ptr<GrFragmentProcessor>> fps; + ElementList::Iter iter(elements); + while (iter.get()) { + SkClipOp op = iter.get()->getOp(); + bool invert; + bool skip = false; + switch (op) { + case kReplace_SkClipOp: + SkASSERT(iter.get() == elements.head()); + // Fallthrough, handled same as intersect. + case kIntersect_SkClipOp: + invert = false; + if (iter.get()->contains(drawDevBounds)) { + skip = true; + } + break; + case kDifference_SkClipOp: + invert = true; + // We don't currently have a cheap test for whether a rect is fully outside an + // element's primitive, so don't attempt to set skip. + break; + default: + return false; + } + if (!skip) { + GrPrimitiveEdgeType edgeType; + if (iter.get()->isAA()) { + if (abortIfAA) { + return false; + } + edgeType = + invert ? kInverseFillAA_GrProcessorEdgeType : kFillAA_GrProcessorEdgeType; + } else { + edgeType = + invert ? kInverseFillBW_GrProcessorEdgeType : kFillBW_GrProcessorEdgeType; + } + + switch (iter.get()->getDeviceSpaceType()) { + case SkClipStack::Element::DeviceSpaceType::kPath: + fps.emplace_back( + GrConvexPolyEffect::Make(edgeType, iter.get()->getDeviceSpacePath())); + break; + case SkClipStack::Element::DeviceSpaceType::kRRect: { + fps.emplace_back( + GrRRectEffect::Make(edgeType, iter.get()->getDeviceSpaceRRect())); + break; + } + case SkClipStack::Element::DeviceSpaceType::kRect: { + fps.emplace_back( + GrConvexPolyEffect::Make(edgeType, iter.get()->getDeviceSpaceRect())); + break; + } + default: + break; + } + if (!fps.back()) { + return false; + } + } + iter.next(); + } + + *resultFP = nullptr; + if (fps.count()) { + *resultFP = GrFragmentProcessor::RunInSeries(fps.begin(), fps.count()); + } + return true; +} + //////////////////////////////////////////////////////////////////////////////// // sort out what kind of clip mask needs to be created: alpha, stencil, // scissor, or entirely software @@ -199,19 +265,8 @@ bool GrClipStackClip::apply(GrContext* context, GrRenderTargetContext* renderTar return true; } - int maxAnalyticFPs = kMaxAnalyticElements; - if (GrFSAAType::kNone != renderTargetContext->fsaaType()) { - // With mixed samples (non-msaa color buffer), any coverage info is lost from color once it - // hits the color buffer anyway, so we may as well use coverage AA if nothing else in the - // pipe is multisampled. - if (renderTargetContext->numColorSamples() > 0 || useHWAA || hasUserStencilSettings) { - maxAnalyticFPs = 0; - } - SkASSERT(!context->caps()->avoidStencilBuffers()); // We disable MSAA when avoiding stencil. - } - - GrReducedClip reducedClip(*fStack, devBounds, renderTargetContext->priv().maxWindowRectangles(), - maxAnalyticFPs); + const GrReducedClip reducedClip(*fStack, devBounds, + renderTargetContext->priv().maxWindowRectangles()); if (reducedClip.hasScissor() && !GrClip::IsInsideClip(reducedClip.scissor(), devBounds)) { out->addScissor(reducedClip.scissor(), bounds); @@ -222,10 +277,6 @@ bool GrClipStackClip::apply(GrContext* context, GrRenderTargetContext* renderTar GrWindowRectsState::Mode::kExclusive); } - if (std::unique_ptr<GrFragmentProcessor> clipFPs = reducedClip.detachAnalyticFPs()) { - out->addCoverageFP(std::move(clipFPs)); - } - if (reducedClip.maskElements().isEmpty()) { return InitialState::kAllIn == reducedClip.initialState(); } @@ -238,9 +289,41 @@ bool GrClipStackClip::apply(GrContext* context, GrRenderTargetContext* renderTar SkASSERT(rtIBounds.contains(scissor)); // Mask shouldn't be larger than the RT. #endif + bool avoidStencilBuffers = context->caps()->avoidStencilBuffers(); + + // An element count of 4 was chosen because of the common pattern in Blink of: + // isect RR + // diff RR + // isect convex_poly + // isect convex_poly + // when drawing rounded div borders. This could probably be tuned based on a + // configuration's relative costs of switching RTs to generate a mask vs + // longer shaders. + if (reducedClip.maskElements().count() <= kMaxAnalyticElements) { + // When there are multiple samples we want to do per-sample clipping, not compute a + // fractional pixel coverage. + bool disallowAnalyticAA = + GrFSAAType::kNone != renderTargetContext->fsaaType() && !avoidStencilBuffers; + if (disallowAnalyticAA && !renderTargetContext->numColorSamples()) { + // With a single color sample, any coverage info is lost from color once it hits the + // color buffer anyway, so we may as well use coverage AA if nothing else in the pipe + // is multisampled. + disallowAnalyticAA = useHWAA || hasUserStencilSettings; + } + std::unique_ptr<GrFragmentProcessor> clipFP; + if ((reducedClip.maskRequiresAA() || avoidStencilBuffers) && + get_analytic_clip_processor(reducedClip.maskElements(), disallowAnalyticAA, devBounds, + &clipFP)) { + if (clipFP) { + out->addCoverageFP(std::move(clipFP)); + } + return true; + } + } + // If the stencil buffer is multisampled we can use it to do everything. if ((GrFSAAType::kNone == renderTargetContext->fsaaType() && reducedClip.maskRequiresAA()) || - context->caps()->avoidStencilBuffers()) { + avoidStencilBuffers) { sk_sp<GrTextureProxy> result; if (UseSWOnlyPath(context, hasUserStencilSettings, renderTargetContext, reducedClip)) { // The clip geometry is complex enough that it will be more efficient to create it @@ -260,8 +343,7 @@ bool GrClipStackClip::apply(GrContext* context, GrRenderTargetContext* renderTar // If alpha or software clip mask creation fails, fall through to the stencil code paths, // unless stencils are disallowed. if (context->caps()->avoidStencilBuffers()) { - SkDebugf("WARNING: Clip mask requires stencil, but stencil unavailable. " - "Clip will be ignored.\n"); + SkDebugf("WARNING: Clip mask requires stencil, but stencil unavailable. Clip will be ignored.\n"); return false; } } @@ -271,14 +353,11 @@ bool GrClipStackClip::apply(GrContext* context, GrRenderTargetContext* renderTar // 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().mustRenderClip(reducedClip.maskGenID(), + reducedClip.scissor())) { reducedClip.drawStencilClipMask(context, renderTargetContext); - renderTargetContext->priv().setLastClip(reducedClip.maskGenID(), reducedClip.scissor(), - reducedClip.numAnalyticFPs()); + renderTargetContext->priv().setLastClip(reducedClip.maskGenID(), reducedClip.scissor()); } - // GrAppliedClip doesn't need to figure numAnalyticFPs into its key (used by operator==) because - // it verifies the FPs are also equal. out->addStencilClip(reducedClip.maskGenID()); return true; } @@ -286,16 +365,14 @@ bool GrClipStackClip::apply(GrContext* context, GrRenderTargetContext* renderTar //////////////////////////////////////////////////////////////////////////////// // 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 void create_clip_mask_key(uint32_t clipGenID, const SkIRect& bounds, GrUniqueKey* key) { static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); - GrUniqueKey::Builder builder(key, kDomain, 4, GrClipStackClip::kMaskTestTag); + GrUniqueKey::Builder builder(key, kDomain, 3, 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, @@ -316,8 +393,7 @@ sk_sp<GrTextureProxy> GrClipStackClip::createAlphaClipMask(GrContext* context, const GrReducedClip& reducedClip) const { GrResourceProvider* resourceProvider = context->resourceProvider(); GrUniqueKey key; - create_clip_mask_key(reducedClip.maskGenID(), reducedClip.scissor(), - reducedClip.numAnalyticFPs(), &key); + create_clip_mask_key(reducedClip.maskGenID(), reducedClip.scissor(), &key); sk_sp<GrTextureProxy> proxy(resourceProvider->findOrCreateProxyByUniqueKey( key, kBottomLeft_GrSurfaceOrigin)); @@ -429,8 +505,7 @@ 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); + create_clip_mask_key(reducedClip.maskGenID(), reducedClip.scissor(), &key); sk_sp<GrTextureProxy> proxy(context->resourceProvider()->findOrCreateProxyByUniqueKey( key, kTopLeft_GrSurfaceOrigin)); diff --git a/src/gpu/GrReducedClip.cpp b/src/gpu/GrReducedClip.cpp index 8d49af078b..bc3286bdf0 100644 --- a/src/gpu/GrReducedClip.cpp +++ b/src/gpu/GrReducedClip.cpp @@ -20,8 +20,6 @@ #include "GrStyle.h" #include "GrUserStencilSettings.h" #include "SkClipOpPriv.h" -#include "effects/GrConvexPolyEffect.h" -#include "effects/GrRRectEffect.h" /** * There are plenty of optimizations that could be added here. Maybe flips could be folded into @@ -31,11 +29,8 @@ * take a rect in case the caller knows a bound on what is to be drawn through this clip. */ GrReducedClip::GrReducedClip(const SkClipStack& stack, const SkRect& queryBounds, - int maxWindowRectangles, int maxAnalyticFPs) - : fMaxWindowRectangles(maxWindowRectangles) - , fMaxAnalyticFPs(maxAnalyticFPs) { + int maxWindowRectangles) { SkASSERT(!queryBounds.isEmpty()); - SkASSERT(fMaxWindowRectangles <= GrWindowRectangles::kMaxWindows); fHasScissor = false; fAAClipRectGenID = SK_InvalidGenID; @@ -101,13 +96,12 @@ GrReducedClip::GrReducedClip(const SkClipStack& stack, const SkRect& queryBounds } fHasScissor = true; - // Now that we have determined the bounds to use and filtered out the trivial cases, call - // the helper that actually walks the stack. - this->walkStack(stack, tighterQuery); + // Now that we have determined the bounds to use and filtered out the trivial cases, call the + // helper that actually walks the stack. + this->walkStack(stack, tighterQuery, maxWindowRectangles); } - if (SK_InvalidGenID != fAAClipRectGenID && // Is there an AA clip rect? - ClipResult::kNotClipped == this->addAnalyticFP(fAAClipRect, Invert::kNo, true)) { + if (SK_InvalidGenID != fAAClipRectGenID) { // Is there an AA clip rect? if (fMaskElements.isEmpty()) { // Use a replace since it is faster than intersect. fMaskElements.addToHead(fAAClipRect, SkMatrix::I(), kReplace_SkClipOp, true /*doAA*/); @@ -117,10 +111,12 @@ GrReducedClip::GrReducedClip(const SkClipStack& stack, const SkRect& queryBounds } fMaskRequiresAA = true; fMaskGenID = fAAClipRectGenID; + fAAClipRectGenID = SK_InvalidGenID; } } -void GrReducedClip::walkStack(const SkClipStack& stack, const SkRect& queryBounds) { +void GrReducedClip::walkStack(const SkClipStack& stack, const SkRect& queryBounds, + int maxWindowRectangles) { // walk backwards until we get to: // a) the beginning // b) an operation that is known to make the bounds all inside/outside @@ -183,7 +179,7 @@ void GrReducedClip::walkStack(const SkClipStack& stack, const SkRect& queryBound } else if (GrClip::IsOutsideClip(element->getBounds(), queryBounds)) { skippable = true; } else if (!embiggens) { - ClipResult result = this->clipOutsideElement(element); + ClipResult result = this->clipOutsideElement(element, maxWindowRectangles); if (ClipResult::kMadeEmpty == result) { return; } @@ -483,43 +479,34 @@ GrReducedClip::ClipResult GrReducedClip::clipInsideElement(const Element* elemen return ClipResult::kClipped; case Element::DeviceSpaceType::kRRect: - return this->addAnalyticFP(element->getDeviceSpaceRRect(), Invert::kNo, - element->isAA()); - case Element::DeviceSpaceType::kPath: - return this->addAnalyticFP(element->getDeviceSpacePath(), Invert::kNo, element->isAA()); + return ClipResult::kNotClipped; } SK_ABORT("Unexpected DeviceSpaceType"); return ClipResult::kNotClipped; } -GrReducedClip::ClipResult GrReducedClip::clipOutsideElement(const Element* element) { +GrReducedClip::ClipResult GrReducedClip::clipOutsideElement(const Element* element, + int maxWindowRectangles) { + if (fWindowRects.count() >= maxWindowRectangles) { + return ClipResult::kNotClipped; + } + switch (element->getDeviceSpaceType()) { case Element::DeviceSpaceType::kEmpty: return ClipResult::kMadeEmpty; case Element::DeviceSpaceType::kRect: - if (fWindowRects.count() < fMaxWindowRectangles) { - // Clip out the inside of every rect. We won't be able to entirely skip the AA ones, - // but it saves processing time. - this->addWindowRectangle(element->getDeviceSpaceRect(), element->isAA()); - if (!element->isAA()) { - return ClipResult::kClipped; - } - } - return this->addAnalyticFP(element->getDeviceSpaceRect(), Invert::kYes, - element->isAA()); + // Clip out the inside of every rect. We won't be able to entirely skip the AA ones, but + // it saves processing time. + this->addWindowRectangle(element->getDeviceSpaceRect(), element->isAA()); + return !element->isAA() ? ClipResult::kClipped : ClipResult::kNotClipped; case Element::DeviceSpaceType::kRRect: { - const SkRRect& clipRRect = element->getDeviceSpaceRRect(); - ClipResult clipResult = this->addAnalyticFP(clipRRect, Invert::kYes, element->isAA()); - if (fWindowRects.count() >= fMaxWindowRectangles) { - return clipResult; - } - // Clip out the interiors of round rects with two window rectangles in the shape of a - // "plus". This doesn't let us skip the clip element, but still saves processing time. + // plus. It doesn't allow us to skip the clip element, but still saves processing time. + const SkRRect& clipRRect = element->getDeviceSpaceRRect(); SkVector insetTL = clipRRect.radii(SkRRect::kUpperLeft_Corner); SkVector insetBR = clipRRect.radii(SkRRect::kLowerRight_Corner); if (SkRRect::kComplex_Type == clipRRect.getType()) { @@ -533,25 +520,24 @@ GrReducedClip::ClipResult GrReducedClip::clipOutsideElement(const Element* eleme const SkRect& bounds = clipRRect.getBounds(); if (insetTL.x() + insetBR.x() >= bounds.width() || insetTL.y() + insetBR.y() >= bounds.height()) { - return clipResult; // The interior "plus" is empty. + return ClipResult::kNotClipped; // The interior "plus" is empty. } SkRect horzRect = SkRect::MakeLTRB(bounds.left(), bounds.top() + insetTL.y(), bounds.right(), bounds.bottom() - insetBR.y()); this->addWindowRectangle(horzRect, element->isAA()); - - if (fWindowRects.count() < fMaxWindowRectangles) { - SkRect vertRect = SkRect::MakeLTRB(bounds.left() + insetTL.x(), bounds.top(), - bounds.right() - insetBR.x(), bounds.bottom()); - this->addWindowRectangle(vertRect, element->isAA()); + if (fWindowRects.count() >= maxWindowRectangles) { + return ClipResult::kNotClipped; } - return clipResult; + SkRect vertRect = SkRect::MakeLTRB(bounds.left() + insetTL.x(), bounds.top(), + bounds.right() - insetBR.x(), bounds.bottom()); + this->addWindowRectangle(vertRect, element->isAA()); + return ClipResult::kNotClipped; } case Element::DeviceSpaceType::kPath: - return this->addAnalyticFP(element->getDeviceSpacePath(), Invert::kYes, - element->isAA()); + return ClipResult::kNotClipped; } SK_ABORT("Unexpected DeviceSpaceType"); @@ -570,43 +556,6 @@ inline void GrReducedClip::addWindowRectangle(const SkRect& elementInteriorRect, } } -std::unique_ptr<GrFragmentProcessor> make_analytic_clip_fp(GrPrimitiveEdgeType edgeType, - const SkRect& deviceSpaceRect) { - return GrConvexPolyEffect::Make(edgeType, deviceSpaceRect); -} - -std::unique_ptr<GrFragmentProcessor> make_analytic_clip_fp(GrPrimitiveEdgeType edgeType, - const SkRRect& deviceSpaceRRect) { - return GrRRectEffect::Make(edgeType, deviceSpaceRRect); -} - -std::unique_ptr<GrFragmentProcessor> make_analytic_clip_fp(GrPrimitiveEdgeType edgeType, - const SkPath& deviceSpacePath) { - return GrConvexPolyEffect::Make(edgeType, deviceSpacePath); -} - -template<typename T> -inline GrReducedClip::ClipResult GrReducedClip::addAnalyticFP(const T& deviceSpaceShape, - Invert invert, bool aa) { - if (fAnalyticFPs.count() >= fMaxAnalyticFPs) { - return ClipResult::kNotClipped; - } - - GrPrimitiveEdgeType edgeType; - if (Invert::kNo == invert) { - edgeType = aa ? kFillAA_GrProcessorEdgeType : kFillBW_GrProcessorEdgeType; - } else { - edgeType = aa ? kInverseFillAA_GrProcessorEdgeType : kInverseFillBW_GrProcessorEdgeType; - } - - if (auto fp = make_analytic_clip_fp(edgeType, deviceSpaceShape)) { - fAnalyticFPs.push_back(std::move(fp)); - return ClipResult::kClipped; - } - - return ClipResult::kNotClipped; -} - void GrReducedClip::makeEmpty() { fHasScissor = false; fAAClipRectGenID = SK_InvalidGenID; diff --git a/src/gpu/GrReducedClip.h b/src/gpu/GrReducedClip.h index ca133550dd..0746439ba3 100644 --- a/src/gpu/GrReducedClip.h +++ b/src/gpu/GrReducedClip.h @@ -8,7 +8,6 @@ #ifndef GrReducedClip_DEFINED #define GrReducedClip_DEFINED -#include "GrFragmentProcessor.h" #include "GrWindowRectangles.h" #include "SkClipStack.h" #include "SkTLList.h" @@ -25,8 +24,7 @@ public: using Element = SkClipStack::Element; using ElementList = SkTLList<SkClipStack::Element, 16>; - GrReducedClip(const SkClipStack&, const SkRect& queryBounds, - int maxWindowRectangles = 0, int maxAnalyticFPs = 0); + GrReducedClip(const SkClipStack&, const SkRect& queryBounds, int maxWindowRectangles = 0); /** * If hasScissor() is true, the clip mask is not valid outside this rect and the caller must @@ -50,13 +48,6 @@ public: */ const GrWindowRectangles& windowRectangles() const { return fWindowRects; } - int numAnalyticFPs() const { return fAnalyticFPs.count(); } - - std::unique_ptr<GrFragmentProcessor> detachAnalyticFPs() { - SkDEBUGCODE(for (const auto& fp : fAnalyticFPs) { SkASSERT(fp); }) - return GrFragmentProcessor::RunInSeries(fAnalyticFPs.begin(), fAnalyticFPs.count()); - } - /** * An ordered list of clip elements that could not be skipped or implemented by other means. If * nonempty, the caller must create an alpha and/or stencil mask for these elements and apply it @@ -90,7 +81,7 @@ public: bool drawStencilClipMask(GrContext*, GrRenderTargetContext*) const; private: - void walkStack(const SkClipStack&, const SkRect& queryBounds); + void walkStack(const SkClipStack&, const SkRect& queryBounds, int maxWindowRectangles); enum class ClipResult { kNotClipped, @@ -104,27 +95,16 @@ private: // Clips the the given element's exterior out of the final clip. // NOTE: do not call for elements followed by ops that can grow the clip. - ClipResult clipOutsideElement(const Element* element); + ClipResult clipOutsideElement(const Element* element, int maxWindowRectangles); void addWindowRectangle(const SkRect& elementInteriorRect, bool elementIsAA); - - enum class Invert : bool { - kNo, - kYes - }; - - template<typename T> ClipResult addAnalyticFP(const T& deviceSpaceShape, Invert, bool aa); - void makeEmpty(); - const int fMaxWindowRectangles; - const int fMaxAnalyticFPs; SkIRect fScissor; bool fHasScissor; SkRect fAAClipRect; uint32_t fAAClipRectGenID; // GenID the mask will have if includes the AA clip rect. GrWindowRectangles fWindowRects; - SkSTArray<4, std::unique_ptr<GrFragmentProcessor>> fAnalyticFPs; ElementList fMaskElements; uint32_t fMaskGenID; bool fMaskRequiresAA; diff --git a/src/gpu/GrRenderTargetContextPriv.h b/src/gpu/GrRenderTargetContextPriv.h index 4b3ceefac5..2cfd5c8679 100644 --- a/src/gpu/GrRenderTargetContextPriv.h +++ b/src/gpu/GrRenderTargetContextPriv.h @@ -28,22 +28,18 @@ public: // called to note the last clip drawn to the stencil buffer. // TODO: remove after clipping overhaul. - void setLastClip(uint32_t clipStackGenID, const SkIRect& devClipBounds, - int numClipAnalyticFPs) { + void setLastClip(uint32_t clipStackGenID, const SkIRect& devClipBounds) { GrRenderTargetOpList* opList = fRenderTargetContext->getRTOpList(); opList->fLastClipStackGenID = clipStackGenID; opList->fLastDevClipBounds = devClipBounds; - opList->fLastClipNumAnalyticFPs = numClipAnalyticFPs; } // called to determine if we have to render the clip into SB. // TODO: remove after clipping overhaul. - bool mustRenderClip(uint32_t clipStackGenID, const SkIRect& devClipBounds, - int numClipAnalyticFPs) const { + bool mustRenderClip(uint32_t clipStackGenID, const SkIRect& devClipBounds) const { GrRenderTargetOpList* opList = fRenderTargetContext->getRTOpList(); return opList->fLastClipStackGenID != clipStackGenID || - !opList->fLastDevClipBounds.contains(devClipBounds) || - opList->fLastClipNumAnalyticFPs != numClipAnalyticFPs; + !opList->fLastDevClipBounds.contains(devClipBounds); } void clear(const GrFixedClip&, const GrColor, bool canIgnoreClip); diff --git a/src/gpu/GrRenderTargetOpList.h b/src/gpu/GrRenderTargetOpList.h index e9797db8f5..24125acba6 100644 --- a/src/gpu/GrRenderTargetOpList.h +++ b/src/gpu/GrRenderTargetOpList.h @@ -156,7 +156,6 @@ private: uint32_t fLastClipStackGenID; SkIRect fLastDevClipBounds; - int fLastClipNumAnalyticFPs; // For ops/opList we have mean: 5 stdDev: 28 SkSTArray<5, RecordedOp, true> fRecordedOps; |