aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Chris Dalton <csmartdalton@google.com>2017-11-01 19:21:24 +0000
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-11-01 19:21:31 +0000
commitd8d1593b22d59114480cc5b7cb9eba7c4ac029fc (patch)
tree34c04f120dc4e1e6c5ab0413584662d9a5dfa7e7
parent721718059f39b0a5cff29028e30bc089e21a1244 (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.cpp159
-rw-r--r--src/gpu/GrReducedClip.cpp111
-rw-r--r--src/gpu/GrReducedClip.h26
-rw-r--r--src/gpu/GrRenderTargetContextPriv.h10
-rw-r--r--src/gpu/GrRenderTargetOpList.h1
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;