aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Mike Reed <reed@google.com>2017-03-02 11:23:46 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-03-02 18:57:45 +0000
commitc77e33f73d3e86cfabf925d6f2e1166f81022575 (patch)
tree8830c10ea1e9f3295ae9116b90120b3d811290ff /src/core
parent8e8e817cbf6c6e3df744dbaa070564c453b70a62 (diff)
Remove SkDraw from device-draw methods, and enable device-centric clipping.
BUG=skia:6214 Change-Id: I593900724310d09133ae4791ef68d38c43762fc2 Reviewed-on: https://skia-review.googlesource.com/8806 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Mike Reed <reed@google.com>
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkBitmapDevice.cpp108
-rw-r--r--src/core/SkBitmapDevice.h34
-rw-r--r--src/core/SkCanvas.cpp395
-rw-r--r--src/core/SkClipStackDevice.cpp44
-rw-r--r--src/core/SkClipStackDevice.h4
-rw-r--r--src/core/SkDevice.cpp85
-rw-r--r--src/core/SkDevice.h63
-rw-r--r--src/core/SkDeviceLooper.cpp1
-rw-r--r--src/core/SkDraw.cpp28
-rw-r--r--src/core/SkDraw.h1
-rw-r--r--src/core/SkRasterClip.cpp226
-rw-r--r--src/core/SkRasterClip.h40
12 files changed, 451 insertions, 578 deletions
diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp
index 77ff706f4f..20704278bf 100644
--- a/src/core/SkBitmapDevice.cpp
+++ b/src/core/SkBitmapDevice.cpp
@@ -190,63 +190,63 @@ bool SkBitmapDevice::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, s
///////////////////////////////////////////////////////////////////////////////
-#ifdef SK_USE_DEVICE_CLIPPING
-class ModifiedDraw : public SkDraw {
+class SkBitmapDevice::BDDraw : public SkDraw {
public:
- ModifiedDraw(const SkMatrix& cmt, const SkRasterClip& rc, const SkDraw& draw) : SkDraw(draw) {
- SkASSERT(cmt == *draw.fMatrix);
- fRC = &rc;
+ BDDraw(SkBitmapDevice* dev) {
+ // we need fDst to be set, and if we're actually drawing, to dirty the genID
+ if (!dev->accessPixels(&fDst)) {
+ // NoDrawDevice uses us (why?) so we have to catch this case w/ no pixels
+ fDst.reset(dev->imageInfo(), nullptr, 0);
+ }
+ fMatrix = &dev->ctm();
+ fRC = &dev->fRCStack.rc();
}
};
-#define PREPARE_DRAW(draw) ModifiedDraw(this->ctm(), fRCStack.rc(), draw)
-#else
-#define PREPARE_DRAW(draw) draw
-#endif
-void SkBitmapDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
- PREPARE_DRAW(draw).drawPaint(paint);
+void SkBitmapDevice::drawPaint(const SkPaint& paint) {
+ BDDraw(this).drawPaint(paint);
}
-void SkBitmapDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_t count,
+void SkBitmapDevice::drawPoints(SkCanvas::PointMode mode, size_t count,
const SkPoint pts[], const SkPaint& paint) {
- PREPARE_DRAW(draw).drawPoints(mode, count, pts, paint, nullptr);
+ BDDraw(this).drawPoints(mode, count, pts, paint, nullptr);
}
-void SkBitmapDevice::drawRect(const SkDraw& draw, const SkRect& r, const SkPaint& paint) {
- PREPARE_DRAW(draw).drawRect(r, paint);
+void SkBitmapDevice::drawRect(const SkRect& r, const SkPaint& paint) {
+ BDDraw(this).drawRect(r, paint);
}
-void SkBitmapDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPaint& paint) {
+void SkBitmapDevice::drawOval(const SkRect& oval, const SkPaint& paint) {
SkPath path;
path.addOval(oval);
// call the VIRTUAL version, so any subclasses who do handle drawPath aren't
// required to override drawOval.
- this->drawPath(draw, path, paint, nullptr, true);
+ this->drawPath(path, paint, nullptr, true);
}
-void SkBitmapDevice::drawRRect(const SkDraw& draw, const SkRRect& rrect, const SkPaint& paint) {
+void SkBitmapDevice::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
#ifdef SK_IGNORE_BLURRED_RRECT_OPT
SkPath path;
path.addRRect(rrect);
// call the VIRTUAL version, so any subclasses who do handle drawPath aren't
// required to override drawRRect.
- this->drawPath(draw, path, paint, nullptr, true);
+ this->drawPath(path, paint, nullptr, true);
#else
- PREPARE_DRAW(draw).drawRRect(rrect, paint);
+ BDDraw(this).drawRRect(rrect, paint);
#endif
}
-void SkBitmapDevice::drawPath(const SkDraw& draw, const SkPath& path,
+void SkBitmapDevice::drawPath(const SkPath& path,
const SkPaint& paint, const SkMatrix* prePathMatrix,
bool pathIsMutable) {
- PREPARE_DRAW(draw).drawPath(path, paint, prePathMatrix, pathIsMutable);
+ BDDraw(this).drawPath(path, paint, prePathMatrix, pathIsMutable);
}
-void SkBitmapDevice::drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
+void SkBitmapDevice::drawBitmap(const SkBitmap& bitmap,
const SkMatrix& matrix, const SkPaint& paint) {
- LogDrawScaleFactor(SkMatrix::Concat(*draw.fMatrix, matrix), paint.getFilterQuality());
- PREPARE_DRAW(draw).drawBitmap(bitmap, matrix, nullptr, paint);
+ LogDrawScaleFactor(SkMatrix::Concat(this->ctm(), matrix), paint.getFilterQuality());
+ BDDraw(this).drawBitmap(bitmap, matrix, nullptr, paint);
}
static inline bool CanApplyDstMatrixAsCTM(const SkMatrix& m, const SkPaint& paint) {
@@ -258,7 +258,7 @@ static inline bool CanApplyDstMatrixAsCTM(const SkMatrix& m, const SkPaint& pain
return m.getType() <= SkMatrix::kTranslate_Mask;
}
-void SkBitmapDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
+void SkBitmapDevice::drawBitmapRect(const SkBitmap& bitmap,
const SkRect* src, const SkRect& dst,
const SkPaint& paint, SkCanvas::SrcRectConstraint constraint) {
SkMatrix matrix;
@@ -275,7 +275,7 @@ void SkBitmapDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
}
matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit);
- LogDrawScaleFactor(SkMatrix::Concat(*draw.fMatrix, matrix), paint.getFilterQuality());
+ LogDrawScaleFactor(SkMatrix::Concat(this->ctm(), matrix), paint.getFilterQuality());
const SkRect* dstPtr = &dst;
const SkBitmap* bitmapPtr = &bitmap;
@@ -335,7 +335,7 @@ void SkBitmapDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
// matrix with the CTM, and try to call drawSprite if it can. If not,
// it will make a shader and call drawRect, as we do below.
if (CanApplyDstMatrixAsCTM(matrix, paint)) {
- PREPARE_DRAW(draw).drawBitmap(*bitmapPtr, matrix, dstPtr, paint);
+ BDDraw(this).drawBitmap(*bitmapPtr, matrix, dstPtr, paint);
return;
}
}
@@ -360,45 +360,43 @@ void SkBitmapDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
// Call ourself, in case the subclass wanted to share this setup code
// but handle the drawRect code themselves.
- this->drawRect(draw, *dstPtr, paintWithShader);
+ this->drawRect(*dstPtr, paintWithShader);
}
-void SkBitmapDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
+void SkBitmapDevice::drawSprite(const SkBitmap& bitmap,
int x, int y, const SkPaint& paint) {
- PREPARE_DRAW(draw).drawSprite(bitmap, x, y, paint);
+ BDDraw(this).drawSprite(bitmap, x, y, paint);
}
-void SkBitmapDevice::drawText(const SkDraw& draw, const void* text, size_t len,
+void SkBitmapDevice::drawText(const void* text, size_t len,
SkScalar x, SkScalar y, const SkPaint& paint) {
- PREPARE_DRAW(draw).drawText((const char*)text, len, x, y, paint, &fSurfaceProps);
+ BDDraw(this).drawText((const char*)text, len, x, y, paint, &fSurfaceProps);
}
-void SkBitmapDevice::drawPosText(const SkDraw& draw, const void* text, size_t len,
- const SkScalar xpos[], int scalarsPerPos,
- const SkPoint& offset, const SkPaint& paint) {
- PREPARE_DRAW(draw).drawPosText((const char*)text, len, xpos, scalarsPerPos, offset,
- paint, &fSurfaceProps);
+void SkBitmapDevice::drawPosText(const void* text, size_t len, const SkScalar xpos[],
+ int scalarsPerPos, const SkPoint& offset, const SkPaint& paint) {
+ BDDraw(this).drawPosText((const char*)text, len, xpos, scalarsPerPos, offset, paint, &fSurfaceProps);
}
-void SkBitmapDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
+void SkBitmapDevice::drawVertices(SkCanvas::VertexMode vmode,
int vertexCount,
const SkPoint verts[], const SkPoint textures[],
const SkColor colors[], SkBlendMode bmode,
const uint16_t indices[], int indexCount,
const SkPaint& paint) {
- PREPARE_DRAW(draw).drawVertices(vmode, vertexCount, verts, textures, colors, bmode,
- indices, indexCount, paint);
+ BDDraw(this).drawVertices(vmode, vertexCount, verts, textures, colors, bmode, indices,
+ indexCount, paint);
}
-void SkBitmapDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
+void SkBitmapDevice::drawDevice(SkBaseDevice* device,
int x, int y, const SkPaint& paint) {
SkASSERT(!paint.getImageFilter());
- PREPARE_DRAW(draw).drawSprite(static_cast<SkBitmapDevice*>(device)->fBitmap, x, y, paint);
+ BDDraw(this).drawSprite(static_cast<SkBitmapDevice*>(device)->fBitmap, x, y, paint);
}
///////////////////////////////////////////////////////////////////////////////
-void SkBitmapDevice::drawSpecial(const SkDraw& draw, SkSpecialImage* srcImg, int x, int y,
+void SkBitmapDevice::drawSpecial(SkSpecialImage* srcImg, int x, int y,
const SkPaint& paint) {
SkASSERT(!srcImg->isTextureBacked());
@@ -407,9 +405,9 @@ void SkBitmapDevice::drawSpecial(const SkDraw& draw, SkSpecialImage* srcImg, int
SkImageFilter* filter = paint.getImageFilter();
if (filter) {
SkIPoint offset = SkIPoint::Make(0, 0);
- SkMatrix matrix = *draw.fMatrix;
+ SkMatrix matrix = this->ctm();
matrix.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y));
- const SkIRect clipBounds = draw.fRC->getBounds().makeOffset(-x, -y);
+ const SkIRect clipBounds = fRCStack.rc().getBounds().makeOffset(-x, -y);
sk_sp<SkImageFilterCache> cache(this->getImageFilterCache());
SkImageFilter::OutputProperties outputProperties(fBitmap.colorSpace());
SkImageFilter::Context ctx(matrix, clipBounds, cache.get(), outputProperties);
@@ -419,12 +417,12 @@ void SkBitmapDevice::drawSpecial(const SkDraw& draw, SkSpecialImage* srcImg, int
SkPaint tmpUnfiltered(paint);
tmpUnfiltered.setImageFilter(nullptr);
if (resultImg->getROPixels(&resultBM)) {
- this->drawSprite(draw, resultBM, x + offset.x(), y + offset.y(), tmpUnfiltered);
+ this->drawSprite(resultBM, x + offset.x(), y + offset.y(), tmpUnfiltered);
}
}
} else {
if (srcImg->getROPixels(&resultBM)) {
- this->drawSprite(draw, resultBM, x, y, paint);
+ this->drawSprite(resultBM, x, y, paint);
}
}
}
@@ -511,6 +509,20 @@ void SkBitmapDevice::onSetDeviceClipRestriction(SkIRect* mutableClipRestriction)
}
}
+bool SkBitmapDevice::onClipIsAA() const {
+ const SkRasterClip& rc = fRCStack.rc();
+ return !rc.isEmpty() && rc.isAA();
+}
+
+void SkBitmapDevice::onAsRgnClip(SkRegion* rgn) const {
+ const SkRasterClip& rc = fRCStack.rc();
+ if (rc.isAA()) {
+ rgn->setRect(rc.getBounds());
+ } else {
+ *rgn = rc.bwRgn();
+ }
+}
+
void SkBitmapDevice::validateDevBounds(const SkIRect& drawClipBounds) {
#ifdef SK_DEBUG
const SkIRect& stackBounds = fRCStack.rc().getBounds();
diff --git a/src/core/SkBitmapDevice.h b/src/core/SkBitmapDevice.h
index 266b2d9513..7f5a8463b3 100644
--- a/src/core/SkBitmapDevice.h
+++ b/src/core/SkBitmapDevice.h
@@ -21,7 +21,6 @@
#include "SkSize.h"
#include "SkSurfaceProps.h"
-class SkDraw;
class SkImageFilterCache;
class SkMatrix;
class SkPaint;
@@ -70,12 +69,12 @@ protected:
and are handling any looping from the paint, and any effects from the
DrawFilter.
*/
- void drawPaint(const SkDraw&, const SkPaint& paint) override;
- void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
+ void drawPaint(const SkPaint& paint) override;
+ void drawPoints(SkCanvas::PointMode mode, size_t count,
const SkPoint[], const SkPaint& paint) override;
- void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint) override;
- void drawOval(const SkDraw&, const SkRect& oval, const SkPaint& paint) override;
- void drawRRect(const SkDraw&, const SkRRect& rr, const SkPaint& paint) override;
+ void drawRect(const SkRect& r, const SkPaint& paint) override;
+ void drawOval(const SkRect& oval, const SkPaint& paint) override;
+ void drawRRect(const SkRRect& rr, const SkPaint& paint) override;
/**
* If pathIsMutable, then the implementation is allowed to cast path to a
@@ -88,34 +87,34 @@ protected:
* affect the geometry/rasterization, then the pre matrix can just be
* pre-concated with the current matrix.
*/
- void drawPath(const SkDraw&, const SkPath&, const SkPaint&, const SkMatrix* prePathMatrix,
+ void drawPath(const SkPath&, const SkPaint&, const SkMatrix* prePathMatrix,
bool pathIsMutable) override;
- void drawBitmap(const SkDraw&, const SkBitmap&, const SkMatrix&, const SkPaint&) override;
- void drawSprite(const SkDraw&, const SkBitmap&, int x, int y, const SkPaint&) override;
+ void drawBitmap(const SkBitmap&, const SkMatrix&, const SkPaint&) override;
+ void drawSprite(const SkBitmap&, int x, int y, const SkPaint&) override;
/**
* The default impl. will create a bitmap-shader from the bitmap,
* and call drawRect with it.
*/
- void drawBitmapRect(const SkDraw&, const SkBitmap&, const SkRect*, const SkRect&,
+ void drawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&,
const SkPaint&, SkCanvas::SrcRectConstraint) override;
/**
* Does not handle text decoration.
* Decorations (underline and stike-thru) will be handled by SkCanvas.
*/
- void drawText(const SkDraw&, const void* text, size_t len, SkScalar x, SkScalar y,
+ void drawText(const void* text, size_t len, SkScalar x, SkScalar y,
const SkPaint&) override;
- void drawPosText(const SkDraw&, const void* text, size_t len, const SkScalar pos[],
+ void drawPosText(const void* text, size_t len, const SkScalar pos[],
int scalarsPerPos, const SkPoint& offset, const SkPaint& paint) override;
- void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount, const SkPoint verts[],
+ void drawVertices(SkCanvas::VertexMode, int vertexCount, const SkPoint verts[],
const SkPoint texs[], const SkColor colors[], SkBlendMode,
const uint16_t indices[], int indexCount, const SkPaint&) override;
- void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, const SkPaint&) override;
+ void drawDevice(SkBaseDevice*, int x, int y, const SkPaint&) override;
///////////////////////////////////////////////////////////////////////////
- void drawSpecial(const SkDraw&, SkSpecialImage*, int x, int y, const SkPaint&) override;
+ void drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&) override;
sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&) override;
sk_sp<SkSpecialImage> makeSpecial(const SkImage*) override;
sk_sp<SkSpecialImage> snapSpecial() override;
@@ -134,6 +133,8 @@ protected:
void onClipPath(const SkPath& path, SkClipOp, bool aa) override;
void onClipRegion(const SkRegion& deviceRgn, SkClipOp) override;
void onSetDeviceClipRestriction(SkIRect* mutableClipRestriction) override;
+ bool onClipIsAA() const override;
+ void onAsRgnClip(SkRegion*) const override;
void validateDevBounds(const SkIRect& r) override;
private:
@@ -142,9 +143,10 @@ private:
friend class SkDraw;
friend class SkDrawIter;
friend class SkDeviceFilteredPaint;
-
friend class SkSurface_Raster;
+ class BDDraw;
+
// used to change the backend's pixels (and possibly config/rowbytes)
// but cannot change the width/height, so there should be no change to
// any clip information.
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 5c7039fc50..f7173badb9 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -75,9 +75,13 @@ bool SkCanvas::wouldOverwriteEntireSurface(const SkRect* rect, const SkPaint* pa
const SkISize size = this->getBaseLayerSize();
const SkRect bounds = SkRect::MakeIWH(size.width(), size.height());
+
+#if 0
+ // Replace with device method?
if (!this->getClipStack()->quickContains(bounds)) {
return false;
}
+#endif
if (rect) {
if (!this->getTotalMatrix().isScaleTranslate()) {
@@ -192,10 +196,8 @@ struct DeviceCM {
SkMatrix fMatrixStorage;
SkMatrix fStashedMatrix; // original CTM; used by imagefilter in saveLayer
- DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas,
- bool conservativeRasterClip, const SkMatrix& stashed)
+ DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas, const SkMatrix& stashed)
: fNext(nullptr)
- , fClip(conservativeRasterClip)
, fStashedMatrix(stashed)
{
SkSafeRef(device);
@@ -214,48 +216,6 @@ struct DeviceCM {
SkASSERT(fDevice);
fClip.setRect(bounds);
}
-
- void updateMC(const SkMatrix& totalMatrix, const SkRasterClip& totalClip,
- SkRasterClip* updateClip) {
- int x = fDevice->getOrigin().x();
- int y = fDevice->getOrigin().y();
- int width = fDevice->width();
- int height = fDevice->height();
-
- if ((x | y) == 0) {
- fMatrix = &totalMatrix;
- fClip = totalClip;
- } else {
- fMatrixStorage = totalMatrix;
- fMatrixStorage.postTranslate(SkIntToScalar(-x),
- SkIntToScalar(-y));
- fMatrix = &fMatrixStorage;
- totalClip.translate(-x, -y, &fClip);
- }
-
- fClip.op(SkIRect::MakeWH(width, height), SkRegion::kIntersect_Op);
-
-#ifdef SK_USE_DEVICE_CLIPPING
- SkASSERT(*fMatrix == fDevice->ctm());
- // TODO: debug tiles-rt-8888 so we can enable this all the time
-// fDevice->validateDevBounds(fClip.getBounds());
-#endif
-
- // intersect clip, but don't translate it (yet)
-
- if (updateClip) {
- updateClip->op(SkIRect::MakeXYWH(x, y, width, height),
- SkRegion::kDifference_Op);
- }
-
-#ifdef SK_DEBUG
- if (!fClip.isEmpty()) {
- SkIRect deviceR;
- deviceR.set(0, 0, width, height);
- SkASSERT(deviceR.contains(fClip.getBounds()));
- }
-#endif
- }
};
/* This is the record we keep for each save/restore level in the stack.
@@ -275,15 +235,15 @@ public:
reference counted, since the real owner is either our fLayer field,
or a previous one in a lower level.)
*/
- DeviceCM* fTopLayer;
- SkRasterClip fRasterClip;
- SkMatrix fMatrix;
- int fDeferredSaveCount;
+ DeviceCM* fTopLayer;
+ SkConservativeClip fRasterClip;
+ SkMatrix fMatrix;
+ int fDeferredSaveCount;
// This is the current cumulative depth (aggregate of all done translateZ calls)
SkScalar fCurDrawDepth;
- MCRec(bool conservativeRasterClip) : fRasterClip(conservativeRasterClip) {
+ MCRec() {
fFilter = nullptr;
fLayer = nullptr;
fTopLayer = nullptr;
@@ -320,70 +280,26 @@ public:
}
};
-static SkIRect compute_device_bounds(SkBaseDevice* device) {
- return SkIRect::MakeXYWH(device->getOrigin().x(), device->getOrigin().y(),
- device->width(), device->height());
-}
-
-class SkDrawIter : public SkDraw {
+class SkDrawIter {
public:
- SkDrawIter(SkCanvas* canvas) : fDevice(nullptr) {
- canvas->updateDeviceCMCache();
-
- fClipStack = canvas->getClipStack();
- fCurrLayer = canvas->fMCRec->fTopLayer;
-
- fMultiDeviceCS = nullptr;
- if (fCurrLayer->fNext) {
- fMultiDeviceCS = canvas->fClipStack.get();
- fMultiDeviceCS->save();
- }
-#ifdef SK_USE_DEVICE_CLIPPING
- fClipStack = nullptr; // for testing
-#endif
- }
-
- ~SkDrawIter() {
- if (fMultiDeviceCS) {
- fMultiDeviceCS->restore();
- }
- }
+ SkDrawIter(SkCanvas* canvas)
+ : fDevice(nullptr), fCurrLayer(canvas->fMCRec->fTopLayer), fPaint(nullptr)
+ {}
bool next() {
- if (fMultiDeviceCS && fDevice) {
- // remove the previous device's bounds
- fMultiDeviceCS->clipDevRect(compute_device_bounds(fDevice), kDifference_SkClipOp);
- }
-
- // skip over recs with empty clips
- while (fCurrLayer && fCurrLayer->fClip.isEmpty()) {
- fCurrLayer = fCurrLayer->fNext;
- }
-
const DeviceCM* rec = fCurrLayer;
if (rec && rec->fDevice) {
-
- fMatrix = rec->fMatrix;
- fRC = &rec->fClip;
fDevice = rec->fDevice;
- if (!fDevice->accessPixels(&fDst)) {
- fDst.reset(fDevice->imageInfo(), nullptr, 0);
- }
fPaint = rec->fPaint;
- SkDEBUGCODE(this->validate();)
-
fCurrLayer = rec->fNext;
// fCurrLayer may be nullptr now
-
return true;
}
return false;
}
- const SkRasterClip& getClip() const { return *fRC; }
int getX() const { return fDevice->getOrigin().x(); }
int getY() const { return fDevice->getOrigin().y(); }
- const SkMatrix& getMatrix() const { return *fMatrix; }
const SkPaint* getPaint() const { return fPaint; }
SkBaseDevice* fDevice;
@@ -391,9 +307,6 @@ public:
private:
const DeviceCM* fCurrLayer;
const SkPaint* fPaint; // May be null.
- SkClipStack* fMultiDeviceCS;
-
- typedef SkDraw INHERITED;
};
#define FOR_EACH_TOP_DEVICE( code ) \
@@ -657,7 +570,6 @@ static inline SkRect qr_clip_bounds(const SkIRect& bounds) {
void SkCanvas::resetForNextPicture(const SkIRect& bounds) {
this->restoreToCount(1);
- fClipStack->reset();
fMCRec->reset(bounds);
// We're peering through a lot of structs here. Only at this scope do we
@@ -671,29 +583,22 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) {
if (device && device->forceConservativeRasterClip()) {
flags = InitFlags(flags | kConservativeRasterClip_InitFlag);
}
- // Since init() is only called once by our constructors, it is safe to perform this
- // const-cast.
- *const_cast<bool*>(&fConservativeRasterClip) = SkToBool(flags & kConservativeRasterClip_InitFlag);
fAllowSimplifyClip = false;
- fDeviceCMDirty = true;
fSaveCount = 1;
fMetaData = nullptr;
#ifdef SK_EXPERIMENTAL_SHADOWING
fLights = nullptr;
#endif
- fClipStack.reset(new SkClipStack);
-
fMCRec = (MCRec*)fMCStack.push_back();
- new (fMCRec) MCRec(fConservativeRasterClip);
+ new (fMCRec) MCRec;
fMCRec->fRasterClip.setDeviceClipRestriction(&fClipRestrictionRect);
fIsScaleTranslate = true;
SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage));
fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage;
- new (fDeviceCMStorage) DeviceCM(nullptr, nullptr, nullptr, fConservativeRasterClip,
- fMCRec->fMatrix);
+ new (fDeviceCMStorage) DeviceCM(nullptr, nullptr, nullptr, fMCRec->fMatrix);
fMCRec->fTopLayer = fMCRec->fLayer;
@@ -706,9 +611,7 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) {
fMCRec->fRasterClip.setRect(device->getGlobalBounds());
fDeviceClipBounds = qr_clip_bounds(device->getGlobalBounds());
-#ifdef SK_USE_DEVICE_CLIPPING
device->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect);
-#endif
}
return device;
@@ -717,7 +620,6 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) {
SkCanvas::SkCanvas()
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
, fProps(SkSurfaceProps::kLegacyFontHost_InitType)
- , fConservativeRasterClip(false)
{
inc_canvas();
@@ -746,7 +648,6 @@ private:
SkCanvas::SkCanvas(int width, int height, const SkSurfaceProps* props)
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
, fProps(SkSurfacePropsCopyOrDefault(props))
- , fConservativeRasterClip(false)
{
inc_canvas();
@@ -757,7 +658,6 @@ SkCanvas::SkCanvas(int width, int height, const SkSurfaceProps* props)
SkCanvas::SkCanvas(const SkIRect& bounds, InitFlags flags)
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
, fProps(SkSurfaceProps::kLegacyFontHost_InitType)
- , fConservativeRasterClip(false)
{
inc_canvas();
@@ -767,7 +667,6 @@ SkCanvas::SkCanvas(const SkIRect& bounds, InitFlags flags)
SkCanvas::SkCanvas(SkBaseDevice* device)
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
, fProps(device->surfaceProps())
- , fConservativeRasterClip(false)
{
inc_canvas();
@@ -777,7 +676,6 @@ SkCanvas::SkCanvas(SkBaseDevice* device)
SkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags)
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
, fProps(device->surfaceProps())
- , fConservativeRasterClip(false)
{
inc_canvas();
@@ -787,7 +685,6 @@ SkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags)
SkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props)
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
, fProps(props)
- , fConservativeRasterClip(false)
{
inc_canvas();
@@ -800,7 +697,6 @@ SkCanvas::SkCanvas(const SkBitmap& bitmap, std::unique_ptr<SkRasterHandleAllocat
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
, fProps(SkSurfaceProps::kLegacyFontHost_InitType)
, fAllocator(std::move(alloc))
- , fConservativeRasterClip(false)
{
inc_canvas();
@@ -967,26 +863,6 @@ bool SkCanvas::writePixels(const SkImageInfo& srcInfo, const void* pixels, size_
//////////////////////////////////////////////////////////////////////////////
-void SkCanvas::updateDeviceCMCache() {
- if (fDeviceCMDirty) {
- const SkMatrix& totalMatrix = this->getTotalMatrix();
- const SkRasterClip& totalClip = fMCRec->fRasterClip;
- DeviceCM* layer = fMCRec->fTopLayer;
-
- if (nullptr == layer->fNext) { // only one layer
- layer->updateMC(totalMatrix, totalClip, nullptr);
- } else {
- SkRasterClip clip(totalClip);
- do {
- layer->updateMC(totalMatrix, clip, &clip);
- } while ((layer = layer->fNext) != nullptr);
- }
- fDeviceCMDirty = false;
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
void SkCanvas::checkForDeferredSave() {
if (fMCRec->fDeferredSaveCount > 0) {
this->doSave();
@@ -1057,10 +933,7 @@ void SkCanvas::internalSave() {
new (newTop) MCRec(*fMCRec); // balanced in restore()
fMCRec = newTop;
- fClipStack->save();
-#ifdef SK_USE_DEVICE_CLIPPING
FOR_EACH_TOP_DEVICE(device->save());
-#endif
}
bool SkCanvas::BoundsAffectsClip(SaveLayerFlags saveLayerFlags) {
@@ -1091,6 +964,7 @@ bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveLayerFlags saveLayerFlag
// early exit if the layer's bounds are clipped out
if (!ir.intersect(clipBounds)) {
if (BoundsAffectsClip(saveLayerFlags)) {
+ fMCRec->fTopLayer->fDevice->clipRegion(SkRegion(), SkClipOp::kIntersect); // empty
fMCRec->fRasterClip.setEmpty();
fDeviceClipBounds.setEmpty();
}
@@ -1103,7 +977,6 @@ bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveLayerFlags saveLayerFlag
if (BoundsAffectsClip(saveLayerFlags)) {
// Simplify the current clips since they will be applied properly during restore()
- fClipStack->clipDevRect(ir, kReplace_SkClipOp);
fMCRec->fRasterClip.setRect(ir);
fDeviceClipBounds = qr_clip_bounds(ir);
}
@@ -1136,7 +1009,7 @@ int SkCanvas::saveLayer(const SaveLayerRec& origRec) {
void SkCanvas::DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filter,
SkBaseDevice* dst, const SkIPoint& dstOrigin,
- const SkMatrix& ctm, const SkClipStack* clipStack) {
+ const SkMatrix& ctm) {
SkDraw draw;
SkRasterClip rc;
rc.setRect(SkIRect::MakeWH(dst->width(), dst->height()));
@@ -1145,7 +1018,6 @@ void SkCanvas::DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filt
}
draw.fMatrix = &SkMatrix::I();
draw.fRC = &rc;
- draw.fClipStack = clipStack;
SkPaint p;
if (filter) {
@@ -1156,7 +1028,7 @@ void SkCanvas::DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filt
int y = src->getOrigin().y() - dstOrigin.y();
auto special = src->snapSpecial();
if (special) {
- dst->drawSpecial(draw, special.get(), x, y, p);
+ dst->drawSpecial(special.get(), x, y, p);
}
}
@@ -1220,8 +1092,6 @@ void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy stra
// that would invoke a possibly overridden virtual
this->internalSave();
- fDeviceCMDirty = true;
-
SkIRect ir;
if (!this->clipRectBounds(bounds, saveLayerFlags, &ir, imageFilter)) {
return;
@@ -1265,12 +1135,8 @@ void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy stra
return;
}
}
-#ifndef SK_USE_DEVICE_CLIPPING
- newDevice->setOrigin(fMCRec->fMatrix, ir.fLeft, ir.fTop);
-#endif
-
DeviceCM* layer =
- new DeviceCM(newDevice.get(), paint, this, fConservativeRasterClip, stashedMatrix);
+ new DeviceCM(newDevice.get(), paint, this, stashedMatrix);
// only have a "next" if this new layer doesn't affect the clip (rare)
layer->fNext = BoundsAffectsClip(saveLayerFlags) ? nullptr : fMCRec->fTopLayer;
@@ -1279,10 +1145,9 @@ void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy stra
if ((rec.fSaveLayerFlags & kInitWithPrevious_SaveLayerFlag) || rec.fBackdrop) {
DrawDeviceWithFilter(priorDevice, rec.fBackdrop, newDevice.get(), { ir.fLeft, ir.fTop },
- fMCRec->fMatrix, this->getClipStack());
+ fMCRec->fMatrix);
}
-#ifdef SK_USE_DEVICE_CLIPPING
newDevice->setOrigin(fMCRec->fMatrix, ir.fLeft, ir.fTop);
newDevice->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect);
@@ -1295,7 +1160,6 @@ void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy stra
layer->fDevice->clipRegion(hole, SkClipOp::kDifference);
} while (layer->fNext);
}
-#endif
}
int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) {
@@ -1311,10 +1175,6 @@ int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) {
void SkCanvas::internalRestore() {
SkASSERT(fMCStack.count() != 0);
- fDeviceCMDirty = true;
-
- fClipStack->restore();
-
// reserve our layer (if any)
DeviceCM* layer = fMCRec->fLayer; // may be null
// now detach it from fMCRec so we can pop(). Gets freed after its drawn
@@ -1325,11 +1185,9 @@ void SkCanvas::internalRestore() {
fMCStack.pop_back();
fMCRec = (MCRec*)fMCStack.back();
-#ifdef SK_USE_DEVICE_CLIPPING
if (fMCRec) {
FOR_EACH_TOP_DEVICE(device->restore(fMCRec->fMatrix));
}
-#endif
/* Time to draw the layer's offscreen. We can't call the public drawSprite,
since if we're being recorded, we don't want to record this (the
@@ -1342,7 +1200,6 @@ void SkCanvas::internalRestore() {
// restore what we smashed in internalSaveLayer
fMCRec->fMatrix = layer->fStashedMatrix;
// reset this, since internalDrawDevice will have set it to true
- fDeviceCMDirty = true;
delete layer;
} else {
// we're at the root
@@ -1448,10 +1305,10 @@ void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, const SkPa
if (filter) {
sk_sp<SkSpecialImage> specialImage = srcDev->snapSpecial();
if (specialImage) {
- dstDev->drawSpecial(iter, specialImage.get(), pos.x(), pos.y(), *paint);
+ dstDev->drawSpecial(specialImage.get(), pos.x(), pos.y(), *paint);
}
} else {
- dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint);
+ dstDev->drawDevice(srcDev, pos.x(), pos.y(), *paint);
}
}
@@ -1463,15 +1320,12 @@ void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, const SkPa
void SkCanvas::translate(SkScalar dx, SkScalar dy) {
if (dx || dy) {
this->checkForDeferredSave();
- fDeviceCMDirty = true;
fMCRec->fMatrix.preTranslate(dx,dy);
// Translate shouldn't affect the is-scale-translateness of the matrix.
SkASSERT(fIsScaleTranslate == fMCRec->fMatrix.isScaleTranslate());
-#ifdef SK_USE_DEVICE_CLIPPING
FOR_EACH_TOP_DEVICE(device->setGlobalCTM(fMCRec->fMatrix));
-#endif
this->didTranslate(dx,dy);
}
@@ -1507,25 +1361,19 @@ void SkCanvas::concat(const SkMatrix& matrix) {
}
this->checkForDeferredSave();
- fDeviceCMDirty = true;
fMCRec->fMatrix.preConcat(matrix);
fIsScaleTranslate = fMCRec->fMatrix.isScaleTranslate();
-#ifdef SK_USE_DEVICE_CLIPPING
FOR_EACH_TOP_DEVICE(device->setGlobalCTM(fMCRec->fMatrix));
-#endif
this->didConcat(matrix);
}
void SkCanvas::internalSetMatrix(const SkMatrix& matrix) {
- fDeviceCMDirty = true;
fMCRec->fMatrix = matrix;
fIsScaleTranslate = matrix.isScaleTranslate();
-#ifdef SK_USE_DEVICE_CLIPPING
FOR_EACH_TOP_DEVICE(device->setGlobalCTM(fMCRec->fMatrix));
-#endif
}
void SkCanvas::setMatrix(const SkMatrix& matrix) {
@@ -1569,36 +1417,25 @@ void SkCanvas::clipRect(const SkRect& rect, SkClipOp op, bool doAA) {
void SkCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle) {
const bool isAA = kSoft_ClipEdgeStyle == edgeStyle;
-#ifdef SK_USE_DEVICE_CLIPPING
FOR_EACH_TOP_DEVICE(device->clipRect(rect, op, isAA));
-#endif
AutoValidateClip avc(this);
- fClipStack->clipRect(rect, fMCRec->fMatrix, op, isAA);
fMCRec->fRasterClip.op(rect, fMCRec->fMatrix, this->getTopLayerBounds(), (SkRegion::Op)op,
isAA);
- fDeviceCMDirty = true;
fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds());
}
void SkCanvas::androidFramework_setDeviceClipRestriction(const SkIRect& rect) {
fClipRestrictionRect = rect;
- fClipStack->setDeviceClipRestriction(fClipRestrictionRect);
if (fClipRestrictionRect.isEmpty()) {
// we notify the device, but we *dont* resolve deferred saves (since we're just
// removing the restriction if the rect is empty. how I hate this api.
-#ifdef SK_USE_DEVICE_CLIPPING
FOR_EACH_TOP_DEVICE(device->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect));
-#endif
} else {
this->checkForDeferredSave();
-#ifdef SK_USE_DEVICE_CLIPPING
FOR_EACH_TOP_DEVICE(device->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect));
-#endif
AutoValidateClip avc(this);
- fClipStack->clipDevRect(fClipRestrictionRect, kIntersect_SkClipOp);
fMCRec->fRasterClip.op(fClipRestrictionRect, SkRegion::kIntersect_Op);
- fDeviceCMDirty = true;
fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds());
}
}
@@ -1616,19 +1453,13 @@ void SkCanvas::clipRRect(const SkRRect& rrect, SkClipOp op, bool doAA) {
void SkCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle) {
AutoValidateClip avc(this);
- fDeviceCMDirty = true;
-
bool isAA = kSoft_ClipEdgeStyle == edgeStyle;
-#ifdef SK_USE_DEVICE_CLIPPING
FOR_EACH_TOP_DEVICE(device->clipRRect(rrect, op, isAA));
-#endif
-
- fClipStack->clipRRect(rrect, fMCRec->fMatrix, op, isAA);
+
fMCRec->fRasterClip.op(rrect, fMCRec->fMatrix, this->getTopLayerBounds(), (SkRegion::Op)op,
isAA);
fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds());
- return;
}
void SkCanvas::clipPath(const SkPath& path, SkClipOp op, bool doAA) {
@@ -1659,24 +1490,12 @@ void SkCanvas::clipPath(const SkPath& path, SkClipOp op, bool doAA) {
void SkCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle) {
AutoValidateClip avc(this);
- fDeviceCMDirty = true;
bool isAA = kSoft_ClipEdgeStyle == edgeStyle;
-#ifdef SK_USE_DEVICE_CLIPPING
FOR_EACH_TOP_DEVICE(device->clipPath(path, op, isAA));
-#endif
-
- fClipStack->clipPath(path, fMCRec->fMatrix, op, isAA);
const SkPath* rasterClipPath = &path;
const SkMatrix* matrix = &fMCRec->fMatrix;
- SkPath tempPath;
- if (fAllowSimplifyClip) {
- isAA = getClipStack()->asPath(&tempPath);
- rasterClipPath = &tempPath;
- matrix = &SkMatrix::I();
- op = kReplace_SkClipOp;
- }
fMCRec->fRasterClip.op(*rasterClipPath, *matrix, this->getTopLayerBounds(), (SkRegion::Op)op,
isAA);
fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds());
@@ -1688,17 +1507,9 @@ void SkCanvas::clipRegion(const SkRegion& rgn, SkClipOp op) {
}
void SkCanvas::onClipRegion(const SkRegion& rgn, SkClipOp op) {
-#ifdef SK_USE_DEVICE_CLIPPING
FOR_EACH_TOP_DEVICE(device->clipRegion(rgn, op));
-#endif
-
- AutoValidateClip avc(this);
- fDeviceCMDirty = true;
-
- // todo: signal fClipStack that we have a region, and therefore (I guess)
- // we have to ignore it, and use the region directly?
- fClipStack->clipDevRect(rgn.getBounds(), op);
+ AutoValidateClip avc(this);
fMCRec->fRasterClip.op(rgn, (SkRegion::Op)op);
fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds());
@@ -1712,41 +1523,47 @@ void SkCanvas::validateClip() const {
SkASSERT(this->isClipEmpty());
return;
}
-
- SkIRect ir;
- ir.set(0, 0, device->width(), device->height());
- SkRasterClip tmpClip(ir, fConservativeRasterClip);
-
- SkClipStack::B2TIter iter(*fClipStack);
- const SkClipStack::Element* element;
- while ((element = iter.next()) != nullptr) {
- switch (element->getType()) {
- case SkClipStack::Element::kRect_Type:
- element->getRect().round(&ir);
- tmpClip.op(ir, (SkRegion::Op)element->getOp());
- break;
- case SkClipStack::Element::kEmpty_Type:
- tmpClip.setEmpty();
- break;
- default: {
- SkPath path;
- element->asPath(&path);
- tmpClip.op(path, SkMatrix::I(), this->getTopLayerBounds(),
- (SkRegion::Op)element->getOp(), element->isAA());
- break;
- }
- }
- }
}
#endif
void SkCanvas::replayClips(ClipVisitor* visitor) const {
+#if 0
SkClipStack::B2TIter iter(*fClipStack);
const SkClipStack::Element* element;
while ((element = iter.next()) != nullptr) {
element->replay(visitor);
}
+#endif
+}
+
+bool SkCanvas::androidFramework_isClipAA() const {
+ bool containsAA = false;
+
+ FOR_EACH_TOP_DEVICE(containsAA |= device->onClipIsAA());
+
+ return containsAA;
+}
+
+class RgnAccumulator {
+ SkRegion* fRgn;
+public:
+ RgnAccumulator(SkRegion* total) : fRgn(total) {}
+ void accumulate(SkBaseDevice* device, SkRegion* rgn) {
+ SkIPoint origin = device->getOrigin();
+ if (origin.x() | origin.y()) {
+ rgn->translate(origin.x(), origin.y());
+ }
+ fRgn->op(*rgn, SkRegion::kUnion_Op);
+ }
+};
+
+void SkCanvas::temporary_internal_getRgnClip(SkRegion* rgn) {
+ RgnAccumulator accum(rgn);
+ SkRegion tmp;
+
+ rgn->setEmpty();
+ FOR_EACH_TOP_DEVICE(device->onAsRgnClip(&tmp); accum.accumulate(device, &tmp));
}
///////////////////////////////////////////////////////////////////////////////
@@ -1857,38 +1674,13 @@ SkRect SkCanvas::onGetLocalClipBounds() const {
}
SkIRect SkCanvas::onGetDeviceClipBounds() const {
- const SkRasterClip& clip = fMCRec->fRasterClip;
- if (clip.isEmpty()) {
- return SkIRect::MakeEmpty();
- }
- return clip.getBounds();
+ return fMCRec->fRasterClip.getBounds();
}
const SkMatrix& SkCanvas::getTotalMatrix() const {
return fMCRec->fMatrix;
}
-void SkCanvas::temporary_internal_getRgnClip(SkRegion* rgn) {
- // we know that ganesh doesn't track the rgn, so ask for its clipstack
- if (this->getGrContext()) {
- const SkClipStack* cs = this->getClipStack();
- SkClipStack::BoundsType boundType;
- bool isIntersectionOfRects;
- SkRect bounds;
- cs->getBounds(&bounds, &boundType, &isIntersectionOfRects);
- if (isIntersectionOfRects && SkClipStack::kNormal_BoundsType == boundType) {
- rgn->setRect(bounds.round());
- return;
- }
- SkPath path;
- cs->asPath(&path);
- SkISize size = this->getBaseLayerSize();
- rgn->setPath(path, SkRegion(SkIRect::MakeWH(size.width(), size.height())));
- } else {
- *rgn = fMCRec->fRasterClip.forceGetBW();
- }
-}
-
GrRenderTargetContext* SkCanvas::internal_private_accessTopLayerRenderTargetContext() {
SkBaseDevice* dev = this->getTopDevice();
return dev ? dev->accessRenderTargetContext() : nullptr;
@@ -2158,7 +1950,7 @@ void SkCanvas::internalDrawPaint(const SkPaint& paint) {
LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kPaint_Type, nullptr, false)
while (iter.next()) {
- iter.fDevice->drawPaint(iter, looper.paint());
+ iter.fDevice->drawPaint(looper.paint());
}
LOOPER_END
@@ -2192,7 +1984,7 @@ void SkCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[],
LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds)
while (iter.next()) {
- iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint());
+ iter.fDevice->drawPoints(mode, count, pts, looper.paint());
}
LOOPER_END
@@ -2224,7 +2016,7 @@ void SkCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) {
LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kRect_Type, &r, false)
while (iter.next()) {
- iter.fDevice->drawRect(iter, r, looper.paint());
+ iter.fDevice->drawRect(r, looper.paint());
}
LOOPER_END
@@ -2232,7 +2024,7 @@ void SkCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) {
this->predrawNotify(&r, &paint, false);
SkDrawIter iter(this);
while (iter.next()) {
- iter.fDevice->drawRect(iter, r, paint);
+ iter.fDevice->drawRect(r, paint);
}
}
}
@@ -2249,7 +2041,7 @@ void SkCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) {
LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, &regionRect)
while (iter.next()) {
- iter.fDevice->drawRegion(iter, region, looper.paint());
+ iter.fDevice->drawRegion(region, looper.paint());
}
LOOPER_END
@@ -2267,7 +2059,7 @@ void SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) {
LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, &oval)
while (iter.next()) {
- iter.fDevice->drawOval(iter, oval, looper.paint());
+ iter.fDevice->drawOval(oval, looper.paint());
}
LOOPER_END
@@ -2288,7 +2080,7 @@ void SkCanvas::onDrawArc(const SkRect& oval, SkScalar startAngle,
LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, &oval)
while (iter.next()) {
- iter.fDevice->drawArc(iter, oval, startAngle, sweepAngle, useCenter, looper.paint());
+ iter.fDevice->drawArc(oval, startAngle, sweepAngle, useCenter, looper.paint());
}
LOOPER_END
@@ -2316,7 +2108,7 @@ void SkCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, &rrect.getBounds())
while (iter.next()) {
- iter.fDevice->drawRRect(iter, rrect, looper.paint());
+ iter.fDevice->drawRRect(rrect, looper.paint());
}
LOOPER_END
@@ -2333,7 +2125,7 @@ void SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const Sk
LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, &outer.getBounds())
while (iter.next()) {
- iter.fDevice->drawDRRect(iter, outer, inner, looper.paint());
+ iter.fDevice->drawDRRect(outer, inner, looper.paint());
}
LOOPER_END
@@ -2363,7 +2155,7 @@ void SkCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, &pathBounds)
while (iter.next()) {
- iter.fDevice->drawPath(iter, path, looper.paint());
+ iter.fDevice->drawPath(path, looper.paint());
}
LOOPER_END
@@ -2425,12 +2217,12 @@ void SkCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const S
const SkPaint& pnt = looper.paint();
if (special) {
SkPoint pt;
- iter.fMatrix->mapXY(x, y, &pt);
- iter.fDevice->drawSpecial(iter, special.get(),
+ iter.fDevice->ctm().mapXY(x, y, &pt);
+ iter.fDevice->drawSpecial(special.get(),
SkScalarRoundToInt(pt.fX),
SkScalarRoundToInt(pt.fY), pnt);
} else {
- iter.fDevice->drawImage(iter, image, x, y, pnt);
+ iter.fDevice->drawImage(image, x, y, pnt);
}
}
@@ -2458,7 +2250,7 @@ void SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const Sk
image->isOpaque())
while (iter.next()) {
- iter.fDevice->drawImageRect(iter, image, src, dst, looper.paint(), constraint);
+ iter.fDevice->drawImageRect(image, src, dst, looper.paint(), constraint);
}
LOOPER_END
@@ -2506,12 +2298,12 @@ void SkCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, cons
const SkPaint& pnt = looper.paint();
if (special) {
SkPoint pt;
- iter.fMatrix->mapXY(x, y, &pt);
- iter.fDevice->drawSpecial(iter, special.get(),
+ iter.fDevice->ctm().mapXY(x, y, &pt);
+ iter.fDevice->drawSpecial(special.get(),
SkScalarRoundToInt(pt.fX),
SkScalarRoundToInt(pt.fY), pnt);
} else {
- iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint());
+ iter.fDevice->drawBitmap(bitmap, matrix, looper.paint());
}
}
@@ -2542,7 +2334,7 @@ void SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
bitmap.isOpaque())
while (iter.next()) {
- iter.fDevice->drawBitmapRect(iter, bitmap, src, dst, looper.paint(), constraint);
+ iter.fDevice->drawBitmapRect(bitmap, src, dst, looper.paint(), constraint);
}
LOOPER_END
@@ -2574,7 +2366,7 @@ void SkCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, cons
LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst)
while (iter.next()) {
- iter.fDevice->drawImageNine(iter, image, center, dst, looper.paint());
+ iter.fDevice->drawImageNine(image, center, dst, looper.paint());
}
LOOPER_END
@@ -2600,7 +2392,7 @@ void SkCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, c
LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst)
while (iter.next()) {
- iter.fDevice->drawBitmapNine(iter, bitmap, center, dst, looper.paint());
+ iter.fDevice->drawBitmapNine(bitmap, center, dst, looper.paint());
}
LOOPER_END
@@ -2623,7 +2415,7 @@ void SkCanvas::onDrawImageLattice(const SkImage* image, const Lattice& lattice,
LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst)
while (iter.next()) {
- iter.fDevice->drawImageLattice(iter, image, lattice, dst, looper.paint());
+ iter.fDevice->drawImageLattice(image, lattice, dst, looper.paint());
}
LOOPER_END
@@ -2646,7 +2438,7 @@ void SkCanvas::onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattic
LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst)
while (iter.next()) {
- iter.fDevice->drawBitmapLattice(iter, bitmap, lattice, dst, looper.paint());
+ iter.fDevice->drawBitmapLattice(bitmap, lattice, dst, looper.paint());
}
LOOPER_END
@@ -2678,7 +2470,7 @@ void SkCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkSca
while (iter.next()) {
SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
- iter.fDevice->drawText(iter, text, byteLength, x, y, dfp.paint());
+ iter.fDevice->drawText(text, byteLength, x, y, dfp.paint());
}
LOOPER_END
@@ -2692,7 +2484,7 @@ void SkCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint
while (iter.next()) {
SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
- iter.fDevice->drawPosText(iter, text, byteLength, &pos->fX, 2, textOffset,
+ iter.fDevice->drawPosText(text, byteLength, &pos->fX, 2, textOffset,
dfp.paint());
}
@@ -2708,7 +2500,7 @@ void SkCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScala
while (iter.next()) {
SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
- iter.fDevice->drawPosText(iter, text, byteLength, xpos, 1, textOffset,
+ iter.fDevice->drawPosText(text, byteLength, xpos, 1, textOffset,
dfp.paint());
}
@@ -2720,7 +2512,7 @@ void SkCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPat
LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr)
while (iter.next()) {
- iter.fDevice->drawTextOnPath(iter, text, byteLength, path,
+ iter.fDevice->drawTextOnPath(text, byteLength, path,
matrix, looper.paint());
}
@@ -2736,7 +2528,7 @@ void SkCanvas::onDrawTextRSXform(const void* text, size_t byteLength, const SkRS
LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr)
while (iter.next()) {
- iter.fDevice->drawTextRSXform(iter, text, byteLength, xform, looper.paint());
+ iter.fDevice->drawTextRSXform(text, byteLength, xform, looper.paint());
}
LOOPER_END
@@ -2765,7 +2557,7 @@ void SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
while (iter.next()) {
SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
- iter.fDevice->drawTextBlob(iter, blob, x, y, dfp.paint(), drawFilter);
+ iter.fDevice->drawTextBlob(blob, x, y, dfp.paint(), drawFilter);
}
LOOPER_END
@@ -2825,7 +2617,7 @@ void SkCanvas::onDrawVertices(VertexMode vmode, int vertexCount,
LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr)
while (iter.next()) {
- iter.fDevice->drawVertices(iter, vmode, vertexCount, verts, texs,
+ iter.fDevice->drawVertices(vmode, vertexCount, verts, texs,
colors, bmode, indices, indexCount,
looper.paint());
}
@@ -2840,7 +2632,7 @@ void SkCanvas::onDrawVerticesObject(sk_sp<SkVertices> vertices, SkBlendMode bmod
while (iter.next()) {
// In the common case of one iteration we could std::move vertices here.
- iter.fDevice->drawVerticesObject(iter, vertices, bmode, looper.paint(), flags);
+ iter.fDevice->drawVerticesObject(vertices, bmode, looper.paint(), flags);
}
LOOPER_END
@@ -2880,7 +2672,7 @@ void SkCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr)
while (iter.next()) {
- iter.fDevice->drawPatch(iter, cubics, colors, texCoords, bmode, paint);
+ iter.fDevice->drawPatch(cubics, colors, texCoords, bmode, paint);
}
LOOPER_END
@@ -2924,7 +2716,7 @@ void SkCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const
LOOPER_BEGIN(pnt, SkDrawFilter::kPath_Type, nullptr)
while (iter.next()) {
- iter.fDevice->drawAtlas(iter, atlas, xform, tex, colors, count, bmode, pnt);
+ iter.fDevice->drawAtlas(atlas, xform, tex, colors, count, bmode, pnt);
}
LOOPER_END
}
@@ -2935,7 +2727,7 @@ void SkCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* va
SkPaint paint;
LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, nullptr)
while (iter.next()) {
- iter.fDevice->drawAnnotation(iter, rect, key, value);
+ iter.fDevice->drawAnnotation(rect, key, value);
}
LOOPER_END
}
@@ -3310,7 +3102,7 @@ SkBaseDevice* SkCanvas::LayerIter::device() const {
}
const SkMatrix& SkCanvas::LayerIter::matrix() const {
- return fImpl->getMatrix();
+ return fImpl->fDevice->ctm();
}
const SkPaint& SkCanvas::LayerIter::paint() const {
@@ -3321,7 +3113,10 @@ const SkPaint& SkCanvas::LayerIter::paint() const {
return *paint;
}
-const SkRasterClip& SkCanvas::LayerIter::clip() const { return fImpl->getClip(); }
+void SkCanvas::LayerIter::clip(SkRegion* rgn) const {
+ return fImpl->fDevice->onAsRgnClip(rgn);
+}
+
int SkCanvas::LayerIter::x() const { return fImpl->getX(); }
int SkCanvas::LayerIter::y() const { return fImpl->getY(); }
diff --git a/src/core/SkClipStackDevice.cpp b/src/core/SkClipStackDevice.cpp
index 799850b839..33eca4fd7d 100644
--- a/src/core/SkClipStackDevice.cpp
+++ b/src/core/SkClipStackDevice.cpp
@@ -9,6 +9,16 @@
#include "SkDraw.h"
#include "SkRasterClip.h"
+SkIRect SkClipStackDevice::devClipBounds() const {
+ SkIRect r = fClipStack.bounds(this->imageInfo().bounds()).roundOut();
+ if (!r.isEmpty()) {
+ SkASSERT(this->imageInfo().bounds().contains(r));
+ }
+ return r;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
void SkClipStackDevice::onSave() {
fClipStack.save();
}
@@ -52,13 +62,29 @@ void SkClipStackDevice::onSetDeviceClipRestriction(SkIRect* clipRestriction) {
}
}
-SkIRect SkClipStackDevice::devClipBounds(const SkDraw& draw) const {
-#ifdef SK_USE_DEVICE_CLIPPING
- SkIRect r = fClipStack.bounds(this->imageInfo().bounds()).roundOut();
- SkASSERT(this->imageInfo().bounds().contains(r));
- SkASSERT(draw.fRC->getBounds().contains(r));
- return r;
-#else
- return draw.fRC->getBounds();
-#endif
+bool SkClipStackDevice::onClipIsAA() const {
+ SkClipStack::B2TIter iter(fClipStack);
+ const SkClipStack::Element* element;
+
+ while ((element = iter.next()) != nullptr) {
+ if (element->isAA()) {
+ return true;
+ }
+ }
+ return false;
}
+
+void SkClipStackDevice::onAsRgnClip(SkRegion* rgn) const {
+ SkClipStack::BoundsType boundType;
+ bool isIntersectionOfRects;
+ SkRect bounds;
+ fClipStack.getBounds(&bounds, &boundType, &isIntersectionOfRects);
+ if (isIntersectionOfRects && SkClipStack::kNormal_BoundsType == boundType) {
+ rgn->setRect(bounds.round());
+ } else {
+ SkPath path;
+ fClipStack.asPath(&path);
+ rgn->setPath(path, SkRegion(SkIRect::MakeWH(this->width(), this->height())));
+ }
+}
+
diff --git a/src/core/SkClipStackDevice.h b/src/core/SkClipStackDevice.h
index 1836821fc0..3437cbf570 100644
--- a/src/core/SkClipStackDevice.h
+++ b/src/core/SkClipStackDevice.h
@@ -19,7 +19,7 @@ public:
const SkClipStack& cs() const { return fClipStack; }
- SkIRect devClipBounds(const SkDraw&) const;
+ SkIRect devClipBounds() const;
protected:
void onSave() override;
@@ -29,6 +29,8 @@ protected:
void onClipPath(const SkPath& path, SkClipOp, bool aa) override;
void onClipRegion(const SkRegion& deviceRgn, SkClipOp) override;
void onSetDeviceClipRestriction(SkIRect* mutableClipRestriction) override;
+ bool onClipIsAA() const override;
+ void onAsRgnClip(SkRegion*) const override;
private:
SkClipStack fClipStack;
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index cd3bf502c7..fad73e9961 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -71,35 +71,36 @@ static inline bool is_int(float x) {
return x == (float) sk_float_round2int(x);
}
-void SkBaseDevice::drawRegion(const SkDraw& draw, const SkRegion& region, const SkPaint& paint) {
- bool isNonTranslate = draw.fMatrix->getType() & ~(SkMatrix::kTranslate_Mask);
+void SkBaseDevice::drawRegion(const SkRegion& region, const SkPaint& paint) {
+ const SkMatrix& ctm = this->ctm();
+ bool isNonTranslate = ctm.getType() & ~(SkMatrix::kTranslate_Mask);
bool complexPaint = paint.getStyle() != SkPaint::kFill_Style || paint.getMaskFilter() ||
paint.getPathEffect();
- bool antiAlias = paint.isAntiAlias() && (!is_int(draw.fMatrix->getTranslateX()) ||
- !is_int(draw.fMatrix->getTranslateY()));
+ bool antiAlias = paint.isAntiAlias() && (!is_int(ctm.getTranslateX()) ||
+ !is_int(ctm.getTranslateY()));
if (isNonTranslate || complexPaint || antiAlias) {
SkPath path;
region.getBoundaryPath(&path);
- return this->drawPath(draw, path, paint, nullptr, false);
+ return this->drawPath(path, paint, nullptr, false);
}
SkRegion::Iterator it(region);
while (!it.done()) {
- this->drawRect(draw, SkRect::Make(it.rect()), paint);
+ this->drawRect(SkRect::Make(it.rect()), paint);
it.next();
}
}
-void SkBaseDevice::drawArc(const SkDraw& draw, const SkRect& oval, SkScalar startAngle,
+void SkBaseDevice::drawArc(const SkRect& oval, SkScalar startAngle,
SkScalar sweepAngle, bool useCenter, const SkPaint& paint) {
SkPath path;
bool isFillNoPathEffect = SkPaint::kFill_Style == paint.getStyle() && !paint.getPathEffect();
SkPathPriv::CreateDrawArcPath(&path, oval, startAngle, sweepAngle, useCenter,
isFillNoPathEffect);
- this->drawPath(draw, path, paint);
+ this->drawPath(path, paint);
}
-void SkBaseDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
+void SkBaseDevice::drawDRRect(const SkRRect& outer,
const SkRRect& inner, const SkPaint& paint) {
SkPath path;
path.addRRect(outer);
@@ -109,25 +110,25 @@ void SkBaseDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
const SkMatrix* preMatrix = nullptr;
const bool pathIsMutable = true;
- this->drawPath(draw, path, paint, preMatrix, pathIsMutable);
+ this->drawPath(path, paint, preMatrix, pathIsMutable);
}
-void SkBaseDevice::drawPatch(const SkDraw& draw, const SkPoint cubics[12], const SkColor colors[4],
+void SkBaseDevice::drawPatch(const SkPoint cubics[12], const SkColor colors[4],
const SkPoint texCoords[4], SkBlendMode bmode, const SkPaint& paint) {
SkPatchUtils::VertexData data;
- SkISize lod = SkPatchUtils::GetLevelOfDetail(cubics, draw.fMatrix);
+ SkISize lod = SkPatchUtils::GetLevelOfDetail(cubics, &this->ctm());
// It automatically adjusts lodX and lodY in case it exceeds the number of indices.
// If it fails to generate the vertices, then we do not draw.
if (SkPatchUtils::getVertexData(&data, cubics, colors, texCoords, lod.width(), lod.height())) {
- this->drawVertices(draw, SkCanvas::kTriangles_VertexMode, data.fVertexCount, data.fPoints,
+ this->drawVertices(SkCanvas::kTriangles_VertexMode, data.fVertexCount, data.fPoints,
data.fTexCoords, data.fColors, bmode, data.fIndices, data.fIndexCount,
paint);
}
}
-void SkBaseDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkScalar x, SkScalar y,
+void SkBaseDevice::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
const SkPaint &paint, SkDrawFilter* drawFilter) {
SkPaint runPaint = paint;
@@ -150,14 +151,14 @@ void SkBaseDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkSc
switch (it.positioning()) {
case SkTextBlob::kDefault_Positioning:
- this->drawText(draw, it.glyphs(), textLen, x + offset.x(), y + offset.y(), runPaint);
+ this->drawText(it.glyphs(), textLen, x + offset.x(), y + offset.y(), runPaint);
break;
case SkTextBlob::kHorizontal_Positioning:
- this->drawPosText(draw, it.glyphs(), textLen, it.pos(), 1,
+ this->drawPosText(it.glyphs(), textLen, it.pos(), 1,
SkPoint::Make(x, y + offset.y()), runPaint);
break;
case SkTextBlob::kFull_Positioning:
- this->drawPosText(draw, it.glyphs(), textLen, it.pos(), 2,
+ this->drawPosText(it.glyphs(), textLen, it.pos(), 2,
SkPoint::Make(x, y), runPaint);
break;
default:
@@ -171,66 +172,66 @@ void SkBaseDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkSc
}
}
-void SkBaseDevice::drawImage(const SkDraw& draw, const SkImage* image, SkScalar x, SkScalar y,
+void SkBaseDevice::drawImage(const SkImage* image, SkScalar x, SkScalar y,
const SkPaint& paint) {
SkBitmap bm;
if (as_IB(image)->getROPixels(&bm, this->imageInfo().colorSpace())) {
- this->drawBitmap(draw, bm, SkMatrix::MakeTrans(x, y), paint);
+ this->drawBitmap(bm, SkMatrix::MakeTrans(x, y), paint);
}
}
-void SkBaseDevice::drawImageRect(const SkDraw& draw, const SkImage* image, const SkRect* src,
+void SkBaseDevice::drawImageRect(const SkImage* image, const SkRect* src,
const SkRect& dst, const SkPaint& paint,
SkCanvas::SrcRectConstraint constraint) {
SkBitmap bm;
if (as_IB(image)->getROPixels(&bm, this->imageInfo().colorSpace())) {
- this->drawBitmapRect(draw, bm, src, dst, paint, constraint);
+ this->drawBitmapRect(bm, src, dst, paint, constraint);
}
}
-void SkBaseDevice::drawImageNine(const SkDraw& draw, const SkImage* image, const SkIRect& center,
+void SkBaseDevice::drawImageNine(const SkImage* image, const SkIRect& center,
const SkRect& dst, const SkPaint& paint) {
SkLatticeIter iter(image->width(), image->height(), center, dst);
SkRect srcR, dstR;
while (iter.next(&srcR, &dstR)) {
- this->drawImageRect(draw, image, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
+ this->drawImageRect(image, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
}
}
-void SkBaseDevice::drawBitmapNine(const SkDraw& draw, const SkBitmap& bitmap, const SkIRect& center,
+void SkBaseDevice::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
const SkRect& dst, const SkPaint& paint) {
SkLatticeIter iter(bitmap.width(), bitmap.height(), center, dst);
SkRect srcR, dstR;
while (iter.next(&srcR, &dstR)) {
- this->drawBitmapRect(draw, bitmap, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
+ this->drawBitmapRect(bitmap, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
}
}
-void SkBaseDevice::drawImageLattice(const SkDraw& draw, const SkImage* image,
+void SkBaseDevice::drawImageLattice(const SkImage* image,
const SkCanvas::Lattice& lattice, const SkRect& dst,
const SkPaint& paint) {
SkLatticeIter iter(lattice, dst);
SkRect srcR, dstR;
while (iter.next(&srcR, &dstR)) {
- this->drawImageRect(draw, image, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
+ this->drawImageRect(image, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
}
}
-void SkBaseDevice::drawBitmapLattice(const SkDraw& draw, const SkBitmap& bitmap,
+void SkBaseDevice::drawBitmapLattice(const SkBitmap& bitmap,
const SkCanvas::Lattice& lattice, const SkRect& dst,
const SkPaint& paint) {
SkLatticeIter iter(lattice, dst);
SkRect srcR, dstR;
while (iter.next(&srcR, &dstR)) {
- this->drawBitmapRect(draw, bitmap, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
+ this->drawBitmapRect(bitmap, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
}
}
-void SkBaseDevice::drawAtlas(const SkDraw& draw, const SkImage* atlas, const SkRSXform xform[],
+void SkBaseDevice::drawAtlas(const SkImage* atlas, const SkRSXform xform[],
const SkRect tex[], const SkColor colors[], int count,
SkBlendMode mode, const SkPaint& paint) {
SkPath path;
@@ -260,23 +261,23 @@ void SkBaseDevice::drawAtlas(const SkDraw& draw, const SkImage* atlas, const SkR
path.rewind();
path.addPoly(quad, 4, true);
path.setConvexity(SkPath::kConvex_Convexity);
- this->drawPath(draw, path, pnt, nullptr, true);
+ this->drawPath(path, pnt, nullptr, true);
}
}
-void SkBaseDevice::drawVerticesObject(const SkDraw& draw, sk_sp<SkVertices> vertices,
+void SkBaseDevice::drawVerticesObject(sk_sp<SkVertices> vertices,
SkBlendMode mode, const SkPaint& paint, uint32_t flags) {
const SkPoint* texs =
(flags & SkCanvas::kIgnoreTexCoords_VerticesFlag) ? nullptr : vertices->texCoords();
const SkColor* colors =
(flags & SkCanvas::kIgnoreColors_VerticesFlag) ? nullptr : vertices->colors();
- this->drawVertices(draw, vertices->mode(), vertices->vertexCount(), vertices->positions(), texs,
+ this->drawVertices(vertices->mode(), vertices->vertexCount(), vertices->positions(), texs,
colors, mode, vertices->indices(), vertices->indexCount(), paint);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
-void SkBaseDevice::drawSpecial(const SkDraw&, SkSpecialImage*, int x, int y, const SkPaint&) {}
+void SkBaseDevice::drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&) {}
sk_sp<SkSpecialImage> SkBaseDevice::makeSpecial(const SkBitmap&) { return nullptr; }
sk_sp<SkSpecialImage> SkBaseDevice::makeSpecial(const SkImage*) { return nullptr; }
sk_sp<SkSpecialImage> SkBaseDevice::snapSpecial() { return nullptr; }
@@ -392,13 +393,13 @@ static void morphpath(SkPath* dst, const SkPath& src, SkPathMeasure& meas,
}
}
-void SkBaseDevice::drawTextOnPath(const SkDraw& draw, const void* text, size_t byteLength,
+void SkBaseDevice::drawTextOnPath(const void* text, size_t byteLength,
const SkPath& follow, const SkMatrix* matrix,
const SkPaint& paint) {
SkASSERT(byteLength == 0 || text != nullptr);
// nothing to draw
- if (text == nullptr || byteLength == 0 || draw.fRC->isEmpty()) {
+ if (text == nullptr || byteLength == 0) {
return;
}
@@ -433,7 +434,7 @@ void SkBaseDevice::drawTextOnPath(const SkDraw& draw, const void* text, size_t b
m.postConcat(*matrix);
}
morphpath(&tmp, *iterPath, meas, m);
- this->drawPath(draw, tmp, iter.getPaint(), nullptr, true);
+ this->drawPath(tmp, iter.getPaint(), nullptr, true);
}
}
}
@@ -448,7 +449,7 @@ static int count_utf16(const char* text) {
static int return_4(const char* text) { return 4; }
static int return_2(const char* text) { return 2; }
-void SkBaseDevice::drawTextRSXform(const SkDraw& draw, const void* text, size_t len,
+void SkBaseDevice::drawTextRSXform(const void* text, size_t len,
const SkRSXform xform[], const SkPaint& paint) {
CountTextProc proc = nullptr;
switch (paint.getTextEncoding()) {
@@ -466,19 +467,15 @@ void SkBaseDevice::drawTextRSXform(const SkDraw& draw, const void* text, size_t
break;
}
- SkDraw localD(draw);
SkMatrix localM, currM;
const void* stopText = (const char*)text + len;
while ((const char*)text < (const char*)stopText) {
localM.setRSXform(*xform++);
- currM.setConcat(*draw.fMatrix, localM);
- localD.fMatrix = &currM;
-#ifdef SK_USE_DEVICE_CLIPPING
+ currM.setConcat(this->ctm(), localM);
SkAutoDeviceCTMRestore adc(this, currM);
-#endif
int subLen = proc((const char*)text);
- this->drawText(localD, text, subLen, 0, 0, paint);
+ this->drawText(text, subLen, 0, 0, paint);
text = (const char*)text + subLen;
}
}
diff --git a/src/core/SkDevice.h b/src/core/SkDevice.h
index cd0e1d01ea..527ec2d560 100644
--- a/src/core/SkDevice.h
+++ b/src/core/SkDevice.h
@@ -14,7 +14,6 @@
#include "SkSurfaceProps.h"
class SkBitmap;
-class SkDraw;
class SkDrawFilter;
class SkImageFilterCache;
struct SkIRect;
@@ -150,29 +149,31 @@ protected:
virtual void onClipPath(const SkPath& path, SkClipOp, bool aa) {}
virtual void onClipRegion(const SkRegion& deviceRgn, SkClipOp) {}
virtual void onSetDeviceClipRestriction(SkIRect* mutableClipRestriction) {}
+ virtual bool onClipIsAA() const = 0;
+ virtual void onAsRgnClip(SkRegion*) const = 0;
/** These are called inside the per-device-layer loop for each draw call.
When these are called, we have already applied any saveLayer operations,
and are handling any looping from the paint, and any effects from the
DrawFilter.
*/
- virtual void drawPaint(const SkDraw&, const SkPaint& paint) = 0;
- virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
+ virtual void drawPaint(const SkPaint& paint) = 0;
+ virtual void drawPoints(SkCanvas::PointMode mode, size_t count,
const SkPoint[], const SkPaint& paint) = 0;
- virtual void drawRect(const SkDraw&, const SkRect& r,
+ virtual void drawRect(const SkRect& r,
const SkPaint& paint) = 0;
- virtual void drawRegion(const SkDraw&, const SkRegion& r,
+ virtual void drawRegion(const SkRegion& r,
const SkPaint& paint);
- virtual void drawOval(const SkDraw&, const SkRect& oval,
+ virtual void drawOval(const SkRect& oval,
const SkPaint& paint) = 0;
/** By the time this is called we know that abs(sweepAngle) is in the range [0, 360). */
- virtual void drawArc(const SkDraw&, const SkRect& oval, SkScalar startAngle,
+ virtual void drawArc(const SkRect& oval, SkScalar startAngle,
SkScalar sweepAngle, bool useCenter, const SkPaint& paint);
- virtual void drawRRect(const SkDraw&, const SkRRect& rr,
+ virtual void drawRRect(const SkRRect& rr,
const SkPaint& paint) = 0;
// Default impl calls drawPath()
- virtual void drawDRRect(const SkDraw&, const SkRRect& outer,
+ virtual void drawDRRect(const SkRRect& outer,
const SkRRect& inner, const SkPaint&);
/**
@@ -186,77 +187,77 @@ protected:
* affect the geometry/rasterization, then the pre matrix can just be
* pre-concated with the current matrix.
*/
- virtual void drawPath(const SkDraw&, const SkPath& path,
+ virtual void drawPath(const SkPath& path,
const SkPaint& paint,
const SkMatrix* prePathMatrix = NULL,
bool pathIsMutable = false) = 0;
- virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
+ virtual void drawBitmap(const SkBitmap& bitmap,
const SkMatrix& matrix, const SkPaint& paint) = 0;
- virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
+ virtual void drawSprite(const SkBitmap& bitmap,
int x, int y, const SkPaint& paint) = 0;
/**
* The default impl. will create a bitmap-shader from the bitmap,
* and call drawRect with it.
*/
- virtual void drawBitmapRect(const SkDraw&, const SkBitmap&,
+ virtual void drawBitmapRect(const SkBitmap&,
const SkRect* srcOrNull, const SkRect& dst,
const SkPaint& paint,
SkCanvas::SrcRectConstraint) = 0;
- virtual void drawBitmapNine(const SkDraw&, const SkBitmap&, const SkIRect& center,
+ virtual void drawBitmapNine(const SkBitmap&, const SkIRect& center,
const SkRect& dst, const SkPaint&);
- virtual void drawBitmapLattice(const SkDraw&, const SkBitmap&, const SkCanvas::Lattice&,
+ virtual void drawBitmapLattice(const SkBitmap&, const SkCanvas::Lattice&,
const SkRect& dst, const SkPaint&);
- virtual void drawImage(const SkDraw&, const SkImage*, SkScalar x, SkScalar y, const SkPaint&);
- virtual void drawImageRect(const SkDraw&, const SkImage*, const SkRect* src, const SkRect& dst,
+ virtual void drawImage(const SkImage*, SkScalar x, SkScalar y, const SkPaint&);
+ virtual void drawImageRect(const SkImage*, const SkRect* src, const SkRect& dst,
const SkPaint&, SkCanvas::SrcRectConstraint);
- virtual void drawImageNine(const SkDraw&, const SkImage*, const SkIRect& center,
+ virtual void drawImageNine(const SkImage*, const SkIRect& center,
const SkRect& dst, const SkPaint&);
- virtual void drawImageLattice(const SkDraw&, const SkImage*, const SkCanvas::Lattice&,
+ virtual void drawImageLattice(const SkImage*, const SkCanvas::Lattice&,
const SkRect& dst, const SkPaint&);
/**
* Does not handle text decoration.
* Decorations (underline and stike-thru) will be handled by SkCanvas.
*/
- virtual void drawText(const SkDraw&, const void* text, size_t len,
+ virtual void drawText(const void* text, size_t len,
SkScalar x, SkScalar y, const SkPaint& paint) = 0;
- virtual void drawPosText(const SkDraw&, const void* text, size_t len,
+ virtual void drawPosText(const void* text, size_t len,
const SkScalar pos[], int scalarsPerPos,
const SkPoint& offset, const SkPaint& paint) = 0;
- virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
+ virtual void drawVertices(SkCanvas::VertexMode, int vertexCount,
const SkPoint verts[], const SkPoint texs[],
const SkColor colors[], SkBlendMode,
const uint16_t indices[], int indexCount,
const SkPaint& paint) = 0;
- virtual void drawVerticesObject(const SkDraw&, sk_sp<SkVertices>, SkBlendMode, const SkPaint&,
+ virtual void drawVerticesObject(sk_sp<SkVertices>, SkBlendMode, const SkPaint&,
uint32_t flags);
// default implementation unrolls the blob runs.
- virtual void drawTextBlob(const SkDraw&, const SkTextBlob*, SkScalar x, SkScalar y,
+ virtual void drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y,
const SkPaint& paint, SkDrawFilter* drawFilter);
// default implementation calls drawVertices
- virtual void drawPatch(const SkDraw&, const SkPoint cubics[12], const SkColor colors[4],
+ virtual void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
const SkPoint texCoords[4], SkBlendMode, const SkPaint& paint);
// default implementation calls drawPath
- virtual void drawAtlas(const SkDraw&, const SkImage* atlas, const SkRSXform[], const SkRect[],
+ virtual void drawAtlas(const SkImage* atlas, const SkRSXform[], const SkRect[],
const SkColor[], int count, SkBlendMode, const SkPaint&);
- virtual void drawAnnotation(const SkDraw&, const SkRect&, const char[], SkData*) {}
+ virtual void drawAnnotation(const SkRect&, const char[], SkData*) {}
/** The SkDevice passed will be an SkDevice which was returned by a call to
onCreateDevice on this device with kNeverTile_TileExpectation.
*/
- virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
+ virtual void drawDevice(SkBaseDevice*, int x, int y,
const SkPaint&) = 0;
- virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len, const SkPath&,
+ virtual void drawTextOnPath(const void* text, size_t len, const SkPath&,
const SkMatrix*, const SkPaint&);
- virtual void drawTextRSXform(const SkDraw&, const void* text, size_t len, const SkRSXform[],
+ virtual void drawTextRSXform(const void* text, size_t len, const SkRSXform[],
const SkPaint&);
- virtual void drawSpecial(const SkDraw&, SkSpecialImage*, int x, int y, const SkPaint&);
+ virtual void drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&);
virtual sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&);
virtual sk_sp<SkSpecialImage> makeSpecial(const SkImage*);
virtual sk_sp<SkSpecialImage> snapSpecial();
diff --git a/src/core/SkDeviceLooper.cpp b/src/core/SkDeviceLooper.cpp
index c4e401361c..cea92704ef 100644
--- a/src/core/SkDeviceLooper.cpp
+++ b/src/core/SkDeviceLooper.cpp
@@ -11,7 +11,6 @@ SkDeviceLooper::SkDeviceLooper(const SkPixmap& base, const SkRasterClip& rc, con
bool aa)
: fBaseDst(base)
, fBaseRC(rc)
- , fSubsetRC(rc.isForceConservativeRects())
, fDelta(aa ? kAA_Delta : kBW_Delta)
{
// sentinels that next() has not yet been called, and so our mapper functions
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index a60325c8f7..52a0bf79db 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -577,11 +577,9 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
// then path then
path.setIsVolatile((count-1) == i);
if (device) {
- device->drawPath(*this, path, newPaint, &preMatrix,
- (count-1) == i);
+ device->drawPath(path, newPaint, &preMatrix, (count-1) == i);
} else {
- this->drawPath(path, newPaint, &preMatrix,
- (count-1) == i);
+ this->drawPath(path, newPaint, &preMatrix, (count-1) == i);
}
}
} else {
@@ -593,7 +591,7 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
r.fRight = r.fLeft + width;
r.fBottom = r.fTop + width;
if (device) {
- device->drawRect(*this, r, newPaint);
+ device->drawRect(r, newPaint);
} else {
this->drawRect(r, newPaint);
}
@@ -624,7 +622,7 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
if (!pointData.fFirst.isEmpty()) {
if (device) {
- device->drawPath(*this, pointData.fFirst, newP);
+ device->drawPath(pointData.fFirst, newP);
} else {
this->drawPath(pointData.fFirst, newP);
}
@@ -632,7 +630,7 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
if (!pointData.fLast.isEmpty()) {
if (device) {
- device->drawPath(*this, pointData.fLast, newP);
+ device->drawPath(pointData.fLast, newP);
} else {
this->drawPath(pointData.fLast, newP);
}
@@ -649,11 +647,10 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
}
if (device) {
- device->drawPoints(*this,
- SkCanvas::kPoints_PointMode,
- pointData.fNumPoints,
- pointData.fPoints,
- newP);
+ device->drawPoints(SkCanvas::kPoints_PointMode,
+ pointData.fNumPoints,
+ pointData.fPoints,
+ newP);
} else {
this->drawPoints(SkCanvas::kPoints_PointMode,
pointData.fNumPoints,
@@ -675,7 +672,7 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
pointData.fPoints[i].fX + pointData.fSize.fX,
pointData.fPoints[i].fY + pointData.fSize.fY);
if (device) {
- device->drawRect(*this, r, newP);
+ device->drawRect(r, newP);
} else {
this->drawRect(r, newP);
}
@@ -697,7 +694,7 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
path.moveTo(pts[i]);
path.lineTo(pts[i+1]);
if (device) {
- device->drawPath(*this, path, p, nullptr, true);
+ device->drawPath(path, p, nullptr, true);
} else {
this->drawPath(path, p, nullptr, true);
}
@@ -1422,8 +1419,7 @@ void SkDraw::drawText_asPaths(const char text[], size_t byteLength, SkScalar x,
while (iter.next(&iterPath, &xpos)) {
matrix.postTranslate(xpos - prevXPos, 0);
if (iterPath) {
- const SkPaint& pnt = iter.getPaint();
- this->drawPath(*iterPath, pnt, &matrix, false);
+ this->drawPath(*iterPath, iter.getPaint(), &matrix, false);
}
prevXPos = xpos;
}
diff --git a/src/core/SkDraw.h b/src/core/SkDraw.h
index 534333984b..0b29468d8e 100644
--- a/src/core/SkDraw.h
+++ b/src/core/SkDraw.h
@@ -149,7 +149,6 @@ public:
SkPixmap fDst;
const SkMatrix* fMatrix; // required
const SkRasterClip* fRC; // required
- const SkClipStack* fClipStack; // optional, may be null
#ifdef SK_DEBUG
void validate() const;
diff --git a/src/core/SkRasterClip.cpp b/src/core/SkRasterClip.cpp
index a9e043f84f..f43d14e483 100644
--- a/src/core/SkRasterClip.cpp
+++ b/src/core/SkRasterClip.cpp
@@ -8,10 +8,125 @@
#include "SkRasterClip.h"
#include "SkPath.h"
+enum MutateResult {
+ kDoNothing_MutateResult,
+ kReplaceClippedAgainstGlobalBounds_MutateResult,
+ kContinue_MutateResult,
+};
+
+static MutateResult mutate_conservative_op(SkRegion::Op* op, bool inverseFilled) {
+ if (inverseFilled) {
+ switch (*op) {
+ case SkRegion::kIntersect_Op:
+ case SkRegion::kDifference_Op:
+ // These ops can only shrink the current clip. So leaving
+ // the clip unchanged conservatively respects the contract.
+ return kDoNothing_MutateResult;
+ case SkRegion::kUnion_Op:
+ case SkRegion::kReplace_Op:
+ case SkRegion::kReverseDifference_Op:
+ case SkRegion::kXOR_Op: {
+ // These ops can grow the current clip up to the extents of
+ // the input clip, which is inverse filled, so we just set
+ // the current clip to the device bounds.
+ *op = SkRegion::kReplace_Op;
+ return kReplaceClippedAgainstGlobalBounds_MutateResult;
+ }
+ }
+ } else {
+ // Not inverse filled
+ switch (*op) {
+ case SkRegion::kIntersect_Op:
+ case SkRegion::kUnion_Op:
+ case SkRegion::kReplace_Op:
+ return kContinue_MutateResult;
+ case SkRegion::kDifference_Op:
+ // Difference can only shrink the current clip.
+ // Leaving clip unchanged conservatively fullfills the contract.
+ return kDoNothing_MutateResult;
+ case SkRegion::kReverseDifference_Op:
+ // To reverse, we swap in the bounds with a replace op.
+ // As with difference, leave it unchanged.
+ *op = SkRegion::kReplace_Op;
+ return kContinue_MutateResult;
+ case SkRegion::kXOR_Op:
+ // Be conservative, based on (A XOR B) always included in (A union B),
+ // which is always included in (bounds(A) union bounds(B))
+ *op = SkRegion::kUnion_Op;
+ return kContinue_MutateResult;
+ }
+ }
+ SkFAIL("should not get here");
+ return kDoNothing_MutateResult;
+}
+
+void SkConservativeClip::op(const SkRect& localRect, const SkMatrix& ctm, const SkIRect& devBounds,
+ SkRegion::Op op, bool doAA) {
+ SkRect devRect;
+
+ SkIRect bounds(devBounds);
+ this->applyClipRestriction(op, &bounds);
+ SkIRect ir;
+ switch (mutate_conservative_op(&op, false)) {
+ case kDoNothing_MutateResult:
+ return;
+ case kReplaceClippedAgainstGlobalBounds_MutateResult:
+ ir = bounds;
+ break;
+ case kContinue_MutateResult:
+ ctm.mapRect(&devRect, localRect);
+ ir = doAA ? devRect.roundOut() : devRect.round();
+ break;
+ }
+ this->op(ir, op);
+}
+
+void SkConservativeClip::op(const SkRRect& rrect, const SkMatrix& ctm, const SkIRect& devBounds,
+ SkRegion::Op op, bool doAA) {
+ SkIRect bounds(devBounds);
+ this->applyClipRestriction(op, &bounds);
+ this->op(rrect.getBounds(), ctm, bounds, op, doAA);
+}
+
+void SkConservativeClip::op(const SkPath& path, const SkMatrix& ctm, const SkIRect& devBounds,
+ SkRegion::Op op, bool doAA) {
+ SkIRect bounds(devBounds);
+ this->applyClipRestriction(op, &bounds);
+
+ SkIRect ir;
+ switch (mutate_conservative_op(&op, path.isInverseFillType())) {
+ case kDoNothing_MutateResult:
+ return;
+ case kReplaceClippedAgainstGlobalBounds_MutateResult:
+ ir = bounds;
+ break;
+ case kContinue_MutateResult: {
+ SkRect bounds = path.getBounds();
+ ctm.mapRect(&bounds);
+ ir = bounds.roundOut();
+ break;
+ }
+ }
+ return this->op(ir, op);
+}
+
+void SkConservativeClip::op(const SkRegion& rgn, SkRegion::Op op) {
+ this->op(rgn.getBounds(), op);
+}
+
+void SkConservativeClip::op(const SkIRect& devRect, SkRegion::Op op) {
+ // This may still create a complex region (which we would then take the bounds
+ // Perhaps we should inline the op-logic directly to never create the rgn...
+ SkRegion result;
+ result.op(SkRegion(fBounds), SkRegion(devRect), op);
+ fBounds = result.getBounds();
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
SkRasterClip::SkRasterClip(const SkRasterClip& src) {
AUTO_RASTERCLIP_VALIDATE(src);
- fForceConservativeRects = src.fForceConservativeRects;
fIsBW = src.fIsBW;
if (fIsBW) {
fBW = src.fBW;
@@ -26,23 +141,20 @@ SkRasterClip::SkRasterClip(const SkRasterClip& src) {
}
SkRasterClip::SkRasterClip(const SkRegion& rgn) : fBW(rgn) {
- fForceConservativeRects = false;
fIsBW = true;
fIsEmpty = this->computeIsEmpty(); // bounds might be empty, so compute
fIsRect = !fIsEmpty;
SkDEBUGCODE(this->validate();)
}
-SkRasterClip::SkRasterClip(const SkIRect& bounds, bool forceConservativeRects) : fBW(bounds) {
- fForceConservativeRects = forceConservativeRects;
+SkRasterClip::SkRasterClip(const SkIRect& bounds) : fBW(bounds) {
fIsBW = true;
fIsEmpty = this->computeIsEmpty(); // bounds might be empty, so compute
fIsRect = !fIsEmpty;
SkDEBUGCODE(this->validate();)
}
-SkRasterClip::SkRasterClip(bool forceConservativeRects) {
- fForceConservativeRects = forceConservativeRects;
+SkRasterClip::SkRasterClip() {
fIsBW = true;
fIsEmpty = true;
fIsRect = false;
@@ -54,8 +166,6 @@ SkRasterClip::~SkRasterClip() {
}
bool SkRasterClip::operator==(const SkRasterClip& other) const {
- // This impl doesn't care if fForceConservativeRects is the same in both, only the current state
-
if (fIsBW != other.fIsBW) {
return false;
}
@@ -114,65 +224,9 @@ bool SkRasterClip::setConservativeRect(const SkRect& r, const SkIRect& clipR, bo
/////////////////////////////////////////////////////////////////////////////////////
-enum MutateResult {
- kDoNothing_MutateResult,
- kReplaceClippedAgainstGlobalBounds_MutateResult,
- kContinue_MutateResult,
-};
-
-static MutateResult mutate_conservative_op(SkRegion::Op* op, bool inverseFilled) {
- if (inverseFilled) {
- switch (*op) {
- case SkRegion::kIntersect_Op:
- case SkRegion::kDifference_Op:
- // These ops can only shrink the current clip. So leaving
- // the clip unchanged conservatively respects the contract.
- return kDoNothing_MutateResult;
- case SkRegion::kUnion_Op:
- case SkRegion::kReplace_Op:
- case SkRegion::kReverseDifference_Op:
- case SkRegion::kXOR_Op: {
- // These ops can grow the current clip up to the extents of
- // the input clip, which is inverse filled, so we just set
- // the current clip to the device bounds.
- *op = SkRegion::kReplace_Op;
- return kReplaceClippedAgainstGlobalBounds_MutateResult;
- }
- }
- } else {
- // Not inverse filled
- switch (*op) {
- case SkRegion::kIntersect_Op:
- case SkRegion::kUnion_Op:
- case SkRegion::kReplace_Op:
- return kContinue_MutateResult;
- case SkRegion::kDifference_Op:
- // Difference can only shrink the current clip.
- // Leaving clip unchanged conservatively fullfills the contract.
- return kDoNothing_MutateResult;
- case SkRegion::kReverseDifference_Op:
- // To reverse, we swap in the bounds with a replace op.
- // As with difference, leave it unchanged.
- *op = SkRegion::kReplace_Op;
- return kContinue_MutateResult;
- case SkRegion::kXOR_Op:
- // Be conservative, based on (A XOR B) always included in (A union B),
- // which is always included in (bounds(A) union bounds(B))
- *op = SkRegion::kUnion_Op;
- return kContinue_MutateResult;
- }
- }
- SkFAIL("should not get here");
- return kDoNothing_MutateResult;
-}
-
bool SkRasterClip::setPath(const SkPath& path, const SkRegion& clip, bool doAA) {
AUTO_RASTERCLIP_VALIDATE(*this);
- if (fForceConservativeRects) {
- return this->setConservativeRect(path.getBounds(), clip.getBounds(), path.isInverseFillType());
- }
-
if (this->isBW() && !doAA) {
(void)fBW.setPath(path, clip);
} else {
@@ -190,9 +244,6 @@ bool SkRasterClip::op(const SkRRect& rrect, const SkMatrix& matrix, const SkIRec
SkRegion::Op op, bool doAA) {
SkIRect bounds(devBounds);
this->applyClipRestriction(op, &bounds);
- if (fForceConservativeRects) {
- return this->op(rrect.getBounds(), matrix, bounds, op, doAA);
- }
SkPath path;
path.addRRect(rrect);
@@ -206,24 +257,6 @@ bool SkRasterClip::op(const SkPath& path, const SkMatrix& matrix, const SkIRect&
SkIRect bounds(devBounds);
this->applyClipRestriction(op, &bounds);
- if (fForceConservativeRects) {
- SkIRect ir;
- switch (mutate_conservative_op(&op, path.isInverseFillType())) {
- case kDoNothing_MutateResult:
- return !this->isEmpty();
- case kReplaceClippedAgainstGlobalBounds_MutateResult:
- ir = bounds;
- break;
- case kContinue_MutateResult: {
- SkRect bounds = path.getBounds();
- matrix.mapRect(&bounds);
- ir = bounds.roundOut();
- break;
- }
- }
- return this->op(ir, op);
- }
-
// base is used to limit the size (and therefore memory allocation) of the
// region that results from scan converting devPath.
SkRegion base;
@@ -246,7 +279,7 @@ bool SkRasterClip::op(const SkPath& path, const SkMatrix& matrix, const SkIRect&
return this->setPath(devPath, this->bwRgn(), doAA);
} else {
base.setRect(this->getBounds());
- SkRasterClip clip(fForceConservativeRects);
+ SkRasterClip clip;
clip.setPath(devPath, base, doAA);
return this->op(clip, op);
}
@@ -256,7 +289,7 @@ bool SkRasterClip::op(const SkPath& path, const SkMatrix& matrix, const SkIRect&
if (SkRegion::kReplace_Op == op) {
return this->setPath(devPath, base, doAA);
} else {
- SkRasterClip clip(fForceConservativeRects);
+ SkRasterClip clip;
clip.setPath(devPath, base, doAA);
return this->op(clip, op);
}
@@ -331,23 +364,6 @@ bool SkRasterClip::op(const SkRect& localRect, const SkMatrix& matrix, const SkI
AUTO_RASTERCLIP_VALIDATE(*this);
SkRect devRect;
- if (fForceConservativeRects) {
- SkIRect bounds(devBounds);
- this->applyClipRestriction(op, &bounds);
- SkIRect ir;
- switch (mutate_conservative_op(&op, false)) {
- case kDoNothing_MutateResult:
- return !this->isEmpty();
- case kReplaceClippedAgainstGlobalBounds_MutateResult:
- ir = bounds;
- break;
- case kContinue_MutateResult:
- matrix.mapRect(&devRect, localRect);
- ir = devRect.roundOut();
- break;
- }
- return this->op(ir, op);
- }
const bool isScaleTrans = matrix.isScaleTranslate();
if (!isScaleTrans) {
SkPath path;
@@ -427,8 +443,6 @@ const SkRegion& SkRasterClip::forceGetBW() {
void SkRasterClip::convertToAA() {
AUTO_RASTERCLIP_VALIDATE(*this);
- SkASSERT(!fForceConservativeRects);
-
SkASSERT(fIsBW);
fAA.setRegion(fBW);
fIsBW = false;
diff --git a/src/core/SkRasterClip.h b/src/core/SkRasterClip.h
index 0dc84e491f..1e50e04539 100644
--- a/src/core/SkRasterClip.h
+++ b/src/core/SkRasterClip.h
@@ -13,6 +13,39 @@
class SkRRect;
+class SkConservativeClip {
+ SkIRect fBounds;
+ const SkIRect* fClipRestrictionRect;
+
+ inline void applyClipRestriction(SkRegion::Op op, SkIRect* bounds) {
+ if (op >= SkRegion::kUnion_Op && fClipRestrictionRect
+ && !fClipRestrictionRect->isEmpty()) {
+ if (!bounds->intersect(*fClipRestrictionRect)) {
+ bounds->setEmpty();
+ }
+ }
+ }
+
+public:
+ SkConservativeClip() : fBounds(SkIRect::MakeEmpty()), fClipRestrictionRect(nullptr) {}
+
+ bool isEmpty() const { return fBounds.isEmpty(); }
+ bool isRect() const { return true; }
+ const SkIRect& getBounds() const { return fBounds; }
+
+ void setEmpty() { fBounds.setEmpty(); }
+ void setRect(const SkIRect& r) { fBounds = r; }
+ void setDeviceClipRestriction(const SkIRect* rect) {
+ fClipRestrictionRect = rect;
+ }
+
+ void op(const SkRect&, const SkMatrix&, const SkIRect& limit, SkRegion::Op, bool isAA);
+ void op(const SkRRect&, const SkMatrix&, const SkIRect& limit, SkRegion::Op, bool isAA);
+ void op(const SkPath&, const SkMatrix&, const SkIRect& limit, SkRegion::Op, bool isAA);
+ void op(const SkRegion&, SkRegion::Op);
+ void op(const SkIRect&, SkRegion::Op);
+};
+
/**
* Wraps a SkRegion and SkAAClip, so we have a single object that can represent either our
* BW or antialiased clips.
@@ -24,8 +57,8 @@ class SkRRect;
*/
class SkRasterClip {
public:
- SkRasterClip(bool forceConservativeRects = false);
- SkRasterClip(const SkIRect&, bool forceConservativeRects = false);
+ SkRasterClip();
+ SkRasterClip(const SkIRect&);
SkRasterClip(const SkRegion&);
SkRasterClip(const SkRasterClip&);
~SkRasterClip();
@@ -37,8 +70,6 @@ public:
return !(*this == other);
}
- bool isForceConservativeRects() const { return fForceConservativeRects; }
-
bool isBW() const { return fIsBW; }
bool isAA() const { return !fIsBW; }
const SkRegion& bwRgn() const { SkASSERT(fIsBW); return fBW; }
@@ -101,7 +132,6 @@ public:
private:
SkRegion fBW;
SkAAClip fAA;
- bool fForceConservativeRects;
bool fIsBW;
// these 2 are caches based on querying the right obj based on fIsBW
bool fIsEmpty;