Simplify SkRasterClip now that it's only intersect/diff
Bug: skia:10205
Change-Id: Id29a63783bd38e5977e94bf8e8d7fbb4fe16cb51
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/442279
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
diff --git a/experimental/xform/XContext.cpp b/experimental/xform/XContext.cpp
index d2a9077..f16867b 100644
--- a/experimental/xform/XContext.cpp
+++ b/experimental/xform/XContext.cpp
@@ -42,16 +42,16 @@
}
void clipRect(const SkRect& r, SkClipOp op) override {
- fRC.op(r, fCTM, fBounds, (SkRegion::Op)op, false);
+ fRC.op(r, fCTM, op, false);
fCache.reset(nullptr);
}
void clipRRect(const SkRRect& rr, SkClipOp op) override {
- fRC.op(rr, fCTM, fBounds, (SkRegion::Op)op, false);
+ fRC.op(rr, fCTM, op, false);
fCache.reset(nullptr);
}
void clipPath(const SkPath& p, SkClipOp op) override {
- fRC.op(p, fCTM, fBounds, (SkRegion::Op)op, false);
+ fRC.op(p, fCTM, op, false);
fCache.reset(nullptr);
}
diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp
index 475fcb2..9eaf54e 100644
--- a/src/core/SkBitmapDevice.cpp
+++ b/src/core/SkBitmapDevice.cpp
@@ -169,7 +169,7 @@
SkIntToScalar(-fOrigin.y()));
fDevice->fRCStack.rc().translate(-fOrigin.x(), -fOrigin.y(), &fTileRC);
fTileRC.op(SkIRect::MakeWH(fDraw.fDst.width(), fDraw.fDst.height()),
- SkRegion::kIntersect_Op);
+ SkClipOp::kIntersect);
}
};
@@ -708,7 +708,7 @@
const SkRasterClip& rc = fRCStack.rc();
if (rc.isEmpty()) {
return ClipType::kEmpty;
- } else if (rc.isRect()) {
+ } else if (rc.isRect() && !SkToBool(rc.clipShader())) {
return ClipType::kRect;
} else {
return ClipType::kComplex;
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index b436032..8604bd3 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -1058,7 +1058,7 @@
}
static bool clipHandlesSprite(const SkRasterClip& clip, int x, int y, const SkPixmap& pmap) {
- return clip.isBW() || clip.quickContains(x, y, x + pmap.width(), y + pmap.height());
+ return clip.isBW() || clip.quickContains(SkIRect::MakeXYWH(x, y, pmap.width(), pmap.height()));
}
void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix,
diff --git a/src/core/SkRasterClip.cpp b/src/core/SkRasterClip.cpp
index bfb67b0..4193d2c 100644
--- a/src/core/SkRasterClip.cpp
+++ b/src/core/SkRasterClip.cpp
@@ -64,6 +64,20 @@
SkDEBUGCODE(this->validate();)
}
+SkRasterClip::SkRasterClip(const SkPath& path, const SkIRect& bounds, bool doAA) {
+ SkRegion clip(bounds);
+ if (doAA) {
+ fIsBW = false;
+ fAA.setPath(path, &clip, true);
+ } else {
+ fIsBW = true;
+ fBW.setPath(path, clip);
+ }
+ fIsEmpty = this->computeIsEmpty(); // bounds might be empty, so compute
+ fIsRect = this->computeIsRect();
+ SkDEBUGCODE(this->validate();)
+}
+
SkRasterClip::~SkRasterClip() {
SkDEBUGCODE(this->validate();)
}
@@ -82,14 +96,6 @@
return isEqual;
}
-bool SkRasterClip::isComplex() const {
- return fIsBW ? fBW.isComplex() : !fAA.isEmpty();
-}
-
-const SkIRect& SkRasterClip::getBounds() const {
- return fIsBW ? fBW.getBounds() : fAA.getBounds();
-}
-
bool SkRasterClip::setEmpty() {
AUTO_RASTERCLIP_VALIDATE(*this);
@@ -113,51 +119,82 @@
/////////////////////////////////////////////////////////////////////////////////////
-bool SkRasterClip::setConservativeRect(const SkRect& r, const SkIRect& clipR, bool isInverse) {
- SkRegion::Op op;
- if (isInverse) {
- op = SkRegion::kDifference_Op;
+bool SkRasterClip::op(const SkIRect& rect, SkClipOp op) {
+ AUTO_RASTERCLIP_VALIDATE(*this);
+
+ if (fIsBW) {
+ fBW.op(rect, (SkRegion::Op) op);
} else {
- op = SkRegion::kIntersect_Op;
+ fAA.op(rect, (SkRegion::Op) op);
}
- fBW.setRect(clipR);
- fBW.op(r.roundOut(), op);
return this->updateCacheAndReturnNonEmpty();
}
-/////////////////////////////////////////////////////////////////////////////////////
-
-bool SkRasterClip::setPath(const SkPath& path, const SkRegion& clip, bool doAA) {
+bool SkRasterClip::op(const SkRegion& rgn, SkClipOp op) {
AUTO_RASTERCLIP_VALIDATE(*this);
- if (this->isBW() && !doAA) {
- (void)fBW.setPath(path, clip);
+ if (fIsBW) {
+ (void)fBW.op(rgn, (SkRegion::Op) op);
} else {
- // TODO: since we are going to over-write fAA completely (aren't we?)
- // we should just clear our BW data (if any) and set fIsAA=true
- if (this->isBW()) {
+ SkAAClip tmp;
+ tmp.setRegion(rgn);
+ (void)fAA.op(tmp, (SkRegion::Op) op);
+ }
+ return this->updateCacheAndReturnNonEmpty();
+}
+
+/**
+ * Our antialiasing currently has a granularity of 1/4 of a pixel along each
+ * axis. Thus we can treat an axis coordinate as an integer if it differs
+ * from its nearest int by < half of that value (1/8 in this case).
+ */
+static bool nearly_integral(SkScalar x) {
+ static const SkScalar domain = SK_Scalar1 / 4;
+ static const SkScalar halfDomain = domain / 2;
+
+ x += halfDomain;
+ return x - SkScalarFloorToScalar(x) < domain;
+}
+
+bool SkRasterClip::op(const SkRect& localRect, const SkMatrix& matrix, SkClipOp op, bool doAA) {
+ AUTO_RASTERCLIP_VALIDATE(*this);
+
+ const bool isScaleTrans = matrix.isScaleTranslate();
+ if (!isScaleTrans) {
+ SkPath path = SkPath::Rect(localRect);
+ path.setIsVolatile(true);
+ return this->op(path, matrix, op, doAA);
+ }
+
+ SkRect devRect = matrix.mapRect(localRect);
+ if (fIsBW && doAA) {
+ // check that the rect really needs aa, or is it close enought to
+ // integer boundaries that we can just treat it as a BW rect?
+ if (nearly_integral(devRect.fLeft) && nearly_integral(devRect.fTop) &&
+ nearly_integral(devRect.fRight) && nearly_integral(devRect.fBottom)) {
+ doAA = false;
+ }
+ }
+
+ if (fIsBW && !doAA) {
+ (void)fBW.op(devRect.round(), (SkRegion::Op) op);
+ } else {
+ if (fIsBW) {
this->convertToAA();
}
- (void)fAA.setPath(path, &clip, doAA);
+ (void)fAA.op(devRect, (SkRegion::Op) op, doAA);
}
return this->updateCacheAndReturnNonEmpty();
}
-bool SkRasterClip::op(const SkRRect& rrect, const SkMatrix& matrix, const SkIRect& devBounds,
- SkRegion::Op op, bool doAA) {
- SkIRect bounds(devBounds);
- return this->op(SkPath::RRect(rrect), matrix, bounds, op, doAA);
+bool SkRasterClip::op(const SkRRect& rrect, const SkMatrix& matrix, SkClipOp op, bool doAA) {
+ return this->op(SkPath::RRect(rrect), matrix, op, doAA);
}
-bool SkRasterClip::op(const SkPath& path, const SkMatrix& matrix, const SkIRect& devBounds,
- SkRegion::Op op, bool doAA) {
+bool SkRasterClip::op(const SkPath& path, const SkMatrix& matrix, SkClipOp op, bool doAA) {
AUTO_RASTERCLIP_VALIDATE(*this);
- SkIRect bounds(devBounds);
- // base is used to limit the size (and therefore memory allocation) of the
- // region that results from scan converting devPath.
- SkRegion base;
-
+ // Transform into device space
SkPath devPath;
if (matrix.isIdentity()) {
devPath = path;
@@ -165,82 +202,11 @@
path.transform(matrix, &devPath);
devPath.setIsVolatile(true);
}
- if (SkRegion::kIntersect_Op == op) {
- // since we are intersect, we can do better (tighter) with currRgn's
- // bounds, than just using the device. However, if currRgn is complex,
- // our region blitter may hork, so we do that case in two steps.
- if (this->isRect()) {
- // FIXME: we should also be able to do this when this->isBW(),
- // but relaxing the test above triggers GM asserts in
- // SkRgnBuilder::blitH(). We need to investigate what's going on.
- return this->setPath(devPath, this->bwRgn(), doAA);
- } else {
- base.setRect(this->getBounds());
- SkRasterClip clip;
- clip.setPath(devPath, base, doAA);
- return this->op(clip, op);
- }
- } else {
- base.setRect(bounds);
- if (SkRegion::kReplace_Op == op) {
- return this->setPath(devPath, base, doAA);
- } else {
- SkRasterClip clip;
- clip.setPath(devPath, base, doAA);
- return this->op(clip, op);
- }
- }
-}
-
-bool SkRasterClip::setPath(const SkPath& path, const SkIRect& clip, bool doAA) {
- SkRegion tmp;
- tmp.setRect(clip);
- return this->setPath(path, tmp, doAA);
-}
-
-bool SkRasterClip::op(const SkIRect& rect, SkRegion::Op op) {
- AUTO_RASTERCLIP_VALIDATE(*this);
-
- fIsBW ? fBW.op(rect, op) : fAA.op(rect, op);
- return this->updateCacheAndReturnNonEmpty();
-}
-
-bool SkRasterClip::op(const SkRegion& rgn, SkRegion::Op op) {
- AUTO_RASTERCLIP_VALIDATE(*this);
-
- if (fIsBW) {
- (void)fBW.op(rgn, op);
- } else {
- SkAAClip tmp;
- tmp.setRegion(rgn);
- (void)fAA.op(tmp, op);
- }
- return this->updateCacheAndReturnNonEmpty();
-}
-
-bool SkRasterClip::op(const SkRasterClip& clip, SkRegion::Op op) {
- AUTO_RASTERCLIP_VALIDATE(*this);
- clip.validate();
-
- if (this->isBW() && clip.isBW()) {
- (void)fBW.op(clip.fBW, op);
- } else {
- SkAAClip tmp;
- const SkAAClip* other;
-
- if (this->isBW()) {
- this->convertToAA();
- }
- if (clip.isBW()) {
- tmp.setRegion(clip.bwRgn());
- other = &tmp;
- } else {
- other = &clip.aaRgn();
- }
- (void)fAA.op(*other, op);
- }
- return this->updateCacheAndReturnNonEmpty();
+ // Since op is either intersect or difference, the clip is always shrinking; that means we can
+ // always use our current bounds as the limiting factor for region/aaclip operations
+ SkRasterClip clip(devPath, this->getBounds(), doAA);
+ return this->op(clip, op);
}
bool SkRasterClip::op(sk_sp<SkShader> sh) {
@@ -254,52 +220,26 @@
return !this->isEmpty();
}
-/**
- * Our antialiasing currently has a granularity of 1/4 of a pixel along each
- * axis. Thus we can treat an axis coordinate as an integer if it differs
- * from its nearest int by < half of that value (1.8 in this case).
- */
-static bool nearly_integral(SkScalar x) {
- static const SkScalar domain = SK_Scalar1 / 4;
- static const SkScalar halfDomain = domain / 2;
-
- x += halfDomain;
- return x - SkScalarFloorToScalar(x) < domain;
-}
-
-bool SkRasterClip::op(const SkRect& localRect, const SkMatrix& matrix, const SkIRect& devBounds,
- SkRegion::Op op, bool doAA) {
+bool SkRasterClip::op(const SkRasterClip& clip, SkClipOp op) {
AUTO_RASTERCLIP_VALIDATE(*this);
- SkRect devRect;
+ clip.validate();
- const bool isScaleTrans = matrix.isScaleTranslate();
- if (!isScaleTrans) {
- SkPath path;
- path.addRect(localRect);
- path.setIsVolatile(true);
- return this->op(path, matrix, devBounds, op, doAA);
- }
-
- matrix.mapRect(&devRect, localRect);
-
- if (fIsBW && doAA) {
- // check that the rect really needs aa, or is it close enought to
- // integer boundaries that we can just treat it as a BW rect?
- if (nearly_integral(devRect.fLeft) && nearly_integral(devRect.fTop) &&
- nearly_integral(devRect.fRight) && nearly_integral(devRect.fBottom)) {
- doAA = false;
- }
- }
-
- if (fIsBW && !doAA) {
- SkIRect ir;
- devRect.round(&ir);
- (void)fBW.op(ir, op);
+ if (this->isBW() && clip.isBW()) {
+ (void)fBW.op(clip.fBW, (SkRegion::Op) op);
} else {
- if (fIsBW) {
+ SkAAClip tmp;
+ const SkAAClip* other;
+
+ if (this->isBW()) {
this->convertToAA();
}
- (void)fAA.op(devRect, op, doAA);
+ if (clip.isBW()) {
+ tmp.setRegion(clip.bwRgn());
+ other = &tmp;
+ } else {
+ other = &clip.aaRgn();
+ }
+ (void)fAA.op(*other, (SkRegion::Op) op);
}
return this->updateCacheAndReturnNonEmpty();
}
@@ -331,21 +271,6 @@
dst->updateCacheAndReturnNonEmpty();
}
-bool SkRasterClip::quickContains(const SkIRect& ir) const {
- return fIsBW ? fBW.quickContains(ir) : fAA.quickContains(ir);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-const SkRegion& SkRasterClip::forceGetBW() {
- AUTO_RASTERCLIP_VALIDATE(*this);
-
- if (!fIsBW) {
- fBW.setRect(fAA.getBounds());
- }
- return fBW;
-}
-
void SkRasterClip::convertToAA() {
AUTO_RASTERCLIP_VALIDATE(*this);
diff --git a/src/core/SkRasterClip.h b/src/core/SkRasterClip.h
index ccc2f9d..1dd1397 100644
--- a/src/core/SkRasterClip.h
+++ b/src/core/SkRasterClip.h
@@ -8,6 +8,7 @@
#ifndef SkRasterClip_DEFINED
#define SkRasterClip_DEFINED
+#include "include/core/SkClipOp.h"
#include "include/core/SkRegion.h"
#include "include/core/SkShader.h"
#include "include/private/SkMacros.h"
@@ -18,23 +19,19 @@
/**
* Wraps a SkRegion and SkAAClip, so we have a single object that can represent either our
* BW or antialiased clips.
- *
- * This class is optimized for the raster backend of canvas, but can be expense to keep up2date,
- * so it supports a runtime option (force-conservative-rects) to turn it into a super-fast
- * rect-only tracker. The gpu backend uses this since it does not need the result (it uses
- * SkClipStack instead).
*/
class SkRasterClip {
public:
SkRasterClip();
- SkRasterClip(const SkIRect&);
- SkRasterClip(const SkRegion&);
- SkRasterClip(const SkRasterClip&);
- SkRasterClip& operator=(const SkRasterClip&);
+ explicit SkRasterClip(const SkIRect&);
+ explicit SkRasterClip(const SkRegion&);
+ explicit SkRasterClip(const SkRasterClip&);
+ SkRasterClip(const SkPath& path, const SkIRect& bounds, bool doAA);
+
~SkRasterClip();
- // Only compares the current state. Does not compare isForceConservativeRects(), so that field
- // could be different but this could still return true.
+ SkRasterClip& operator=(const SkRasterClip&);
+
bool operator==(const SkRasterClip&) const;
bool operator!=(const SkRasterClip& other) const {
return !(*this == other);
@@ -55,27 +52,27 @@
return fIsRect;
}
- bool isComplex() const;
- const SkIRect& getBounds() const;
+ bool isComplex() const {
+ return fIsBW ? fBW.isComplex() : !fAA.isEmpty();
+ }
+ const SkIRect& getBounds() const {
+ return fIsBW ? fBW.getBounds() : fAA.getBounds();
+ }
bool setEmpty();
bool setRect(const SkIRect&);
- bool op(const SkIRect&, SkRegion::Op);
- bool op(const SkRegion&, SkRegion::Op);
- bool op(const SkRect&, const SkMatrix& matrix, const SkIRect&, SkRegion::Op, bool doAA);
- bool op(const SkRRect&, const SkMatrix& matrix, const SkIRect&, SkRegion::Op, bool doAA);
- bool op(const SkPath&, const SkMatrix& matrix, const SkIRect&, SkRegion::Op, bool doAA);
+ bool op(const SkIRect&, SkClipOp);
+ bool op(const SkRegion&, SkClipOp);
+ bool op(const SkRect&, const SkMatrix& matrix, SkClipOp, bool doAA);
+ bool op(const SkRRect&, const SkMatrix& matrix, SkClipOp, bool doAA);
+ bool op(const SkPath&, const SkMatrix& matrix, SkClipOp, bool doAA);
bool op(sk_sp<SkShader>);
void translate(int dx, int dy, SkRasterClip* dst) const;
- void translate(int dx, int dy) {
- this->translate(dx, dy, this);
- }
- bool quickContains(const SkIRect& rect) const;
- bool quickContains(int left, int top, int right, int bottom) const {
- return quickContains(SkIRect::MakeLTRB(left, top, right, bottom));
+ bool quickContains(const SkIRect& rect) const {
+ return fIsBW ? fBW.quickContains(rect) : fAA.quickContains(rect);
}
/**
@@ -87,9 +84,6 @@
return !SkIRect::Intersects(this->getBounds(), rect);
}
- // hack for SkCanvas::getTotalClip
- const SkRegion& forceGetBW();
-
#ifdef SK_DEBUG
void validate() const;
#else
@@ -132,10 +126,7 @@
void convertToAA();
- bool setPath(const SkPath& path, const SkRegion& clip, bool doAA);
- bool setPath(const SkPath& path, const SkIRect& clip, bool doAA);
- bool op(const SkRasterClip&, SkRegion::Op);
- bool setConservativeRect(const SkRect& r, const SkIRect& clipR, bool isInverse);
+ bool op(const SkRasterClip&, SkClipOp);
};
class SkAutoRasterClipValidate : SkNoncopyable {
diff --git a/src/core/SkRasterClipStack.h b/src/core/SkRasterClipStack.h
index a642c5f..3f991d5 100644
--- a/src/core/SkRasterClipStack.h
+++ b/src/core/SkRasterClipStack.h
@@ -9,68 +9,16 @@
#define SkRasterClipStack_DEFINED
#include "include/core/SkClipOp.h"
-#include "include/private/SkDeque.h"
#include "src/core/SkRasterClip.h"
#include "src/core/SkScan.h"
-#include <new>
-
-template <typename T> class SkTStack {
-public:
- SkTStack(void* storage, size_t size) : fDeque(sizeof(T), storage, size), fTop(nullptr) {}
- ~SkTStack() {
- while (!fDeque.empty()) {
- ((T*)fDeque.back())->~T();
- fDeque.pop_back();
- }
- }
-
- bool empty() const { return fDeque.empty(); }
-
- int count() const { return fDeque.count(); }
-
- const T& top() const {
- SkASSERT(fTop);
- return *fTop;
- }
-
- T& top() {
- SkASSERT(fTop);
- return *fTop;
- }
-
- T* push_raw() { return (T*)fDeque.push_back(); }
- T& push() {
- fTop = this->push_raw();
- new (fTop) T();
- return *fTop;
- }
- T& push(const T& src) {
- fTop = this->push_raw();
- new (fTop) T(src);
- return *fTop;
- }
-
- void pop() {
- fTop->~T();
- fDeque.pop_back();
- fTop = fDeque.empty() ? nullptr : (T*)fDeque.back();
- }
-
-private:
- SkDeque fDeque;
- T* fTop;
-};
+#include "src/core/SkTBlockList.h"
class SkRasterClipStack : SkNoncopyable {
- int fCounter = 0;
public:
SkRasterClipStack(int width, int height)
- : fStack(fStorage, sizeof(fStorage))
- , fRootBounds(SkIRect::MakeWH(width, height))
- , fDisableAA(SkScan::DowngradeClipAA(fRootBounds)) {
- Rec& rec = fStack.push();
- rec.fRC.setRect(fRootBounds);
- rec.fDeferredCount = 0;
+ : fRootBounds(SkIRect::MakeWH(width, height))
+ , fDisableAA(SkScan::DowngradeClipAA(fRootBounds)) {
+ fStack.emplace_back(SkRasterClip(fRootBounds));
SkASSERT(fStack.count() == 1);
}
@@ -78,43 +26,42 @@
fRootBounds.setXYWH(0, 0, w, h);
SkASSERT(fStack.count() == 1);
- Rec& rec = fStack.top();
+ Rec& rec = fStack.back();
SkASSERT(rec.fDeferredCount == 0);
rec.fRC.setRect(fRootBounds);
}
- const SkRasterClip& rc() const { return fStack.top().fRC; }
+ const SkRasterClip& rc() const { return fStack.back().fRC; }
void save() {
- fCounter += 1;
- SkASSERT(fStack.top().fDeferredCount >= 0);
- fStack.top().fDeferredCount += 1;
+ SkDEBUGCODE(fCounter += 1);
+ SkASSERT(fStack.back().fDeferredCount >= 0);
+ fStack.back().fDeferredCount += 1;
}
void restore() {
- fCounter -= 1; SkASSERT(fCounter >= 0);
- if (--fStack.top().fDeferredCount < 0) {
- SkASSERT(fStack.top().fDeferredCount == -1);
+ SkDEBUGCODE(fCounter -= 1);
+ SkASSERT(fCounter >= 0);
+
+ if (--fStack.back().fDeferredCount < 0) {
+ SkASSERT(fStack.back().fDeferredCount == -1);
SkASSERT(fStack.count() > 1);
- fStack.pop();
+ fStack.pop_back();
}
}
void clipRect(const SkMatrix& ctm, const SkRect& rect, SkClipOp op, bool aa) {
- this->writable_rc().op(rect, ctm, fRootBounds, (SkRegion::Op)op, this->finalAA(aa));
- this->trimIfExpanding(op);
+ this->writable_rc().op(rect, ctm, op, this->finalAA(aa));
this->validate();
}
void clipRRect(const SkMatrix& ctm, const SkRRect& rrect, SkClipOp op, bool aa) {
- this->writable_rc().op(rrect, ctm, fRootBounds, (SkRegion::Op)op, this->finalAA(aa));
- this->trimIfExpanding(op);
+ this->writable_rc().op(rrect, ctm, op, this->finalAA(aa));
this->validate();
}
void clipPath(const SkMatrix& ctm, const SkPath& path, SkClipOp op, bool aa) {
- this->writable_rc().op(path, ctm, fRootBounds, (SkRegion::Op)op, this->finalAA(aa));
- this->trimIfExpanding(op);
+ this->writable_rc().op(path, ctm, op, this->finalAA(aa));
this->validate();
}
@@ -124,8 +71,7 @@
}
void clipRegion(const SkRegion& rgn, SkClipOp op) {
- this->writable_rc().op(rgn, (SkRegion::Op)op);
- this->trimIfExpanding(op);
+ this->writable_rc().op(rgn, op);
this->validate();
}
@@ -151,38 +97,27 @@
private:
struct Rec {
- SkRasterClip fRC;
- int fDeferredCount; // 0 for a "normal" entry
+ SkRasterClip fRC;
+ int fDeferredCount; // 0 for a "normal" entry
+
+ Rec(const SkRasterClip& rc) : fRC(rc), fDeferredCount(0) {}
};
- enum {
- ELEM_COUNT = 16,
- PTR_COUNT = ELEM_COUNT * sizeof(Rec) / sizeof(void*)
- };
- void* fStorage[PTR_COUNT];
- SkTStack<Rec> fStack;
- SkIRect fRootBounds;
- bool fDisableAA;
+ SkTBlockList<Rec, 16> fStack;
+ SkIRect fRootBounds;
+ bool fDisableAA;
+ SkDEBUGCODE(int fCounter = 0);
SkRasterClip& writable_rc() {
- SkASSERT(fStack.top().fDeferredCount >= 0);
- if (fStack.top().fDeferredCount > 0) {
- fStack.top().fDeferredCount -= 1;
- fStack.push(fStack.top());
- fStack.top().fDeferredCount = 0;
+ SkASSERT(fStack.back().fDeferredCount >= 0);
+ if (fStack.back().fDeferredCount > 0) {
+ fStack.back().fDeferredCount -= 1;
+ fStack.emplace_back(fStack.back().fRC);
}
- return fStack.top().fRC;
+ return fStack.back().fRC;
}
bool finalAA(bool aa) const { return aa && !fDisableAA; }
-
- void trimIfExpanding(SkClipOp op) {
- if ((int)op > (int)SkClipOp::kIntersect) {
- Rec& rec = fStack.top();
- SkASSERT(rec.fDeferredCount == 0);
- rec.fRC.op(fRootBounds, SkRegion::kIntersect_Op);
- }
- }
};
#endif
diff --git a/tests/AAClipTest.cpp b/tests/AAClipTest.cpp
index 88fbf03..cdd710e 100644
--- a/tests/AAClipTest.cpp
+++ b/tests/AAClipTest.cpp
@@ -356,7 +356,6 @@
static void did_dx_affect(skiatest::Reporter* reporter, const SkScalar dx[],
size_t count, bool changed) {
- const SkIRect baseBounds = SkIRect::MakeXYWH(0, 0, 10, 10);
SkIRect ir = { 0, 0, 10, 10 };
for (size_t i = 0; i < count; ++i) {
@@ -367,11 +366,11 @@
SkRasterClip rc1(ir);
SkRasterClip rc2(ir);
- rc0.op(r, SkMatrix::I(), baseBounds, SkRegion::kIntersect_Op, false);
+ rc0.op(r, SkMatrix::I(), SkClipOp::kIntersect, false);
r.offset(dx[i], 0);
- rc1.op(r, SkMatrix::I(), baseBounds, SkRegion::kIntersect_Op, true);
+ rc1.op(r, SkMatrix::I(), SkClipOp::kIntersect, true);
r.offset(-2*dx[i], 0);
- rc2.op(r, SkMatrix::I(), baseBounds, SkRegion::kIntersect_Op, true);
+ rc2.op(r, SkMatrix::I(), SkClipOp::kIntersect, true);
REPORTER_ASSERT(reporter, changed != (rc0 == rc1));
REPORTER_ASSERT(reporter, changed != (rc0 == rc2));
@@ -417,7 +416,7 @@
SkRasterClip rc(SkIRect::MakeLTRB(-25000, -25000, 25000, 25000));
SkPath path;
path.addCircle(50, 50, 50);
- rc.op(path, SkMatrix::I(), rc.getBounds(), SkRegion::kIntersect_Op, true);
+ rc.op(path, SkMatrix::I(), SkClipOp::kIntersect, true);
}
static void test_huge(skiatest::Reporter* reporter) {