remove 'deprecated' region from SkDraw
Most call-sites that used it just took its bounds, so it was trivial to convert them
to get the bounds of the RasterClip. Two clients wanted the actual region:
1. layeriter for android
2. pdf
Android already only has BW clips, so should be safe.
PDF now overrides its clip methods to ensure that all clips are BW.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1925693002
Review URL: https://codereview.chromium.org/1925693002
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 9058492..6c4cd27 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -349,7 +349,6 @@
if (rec && rec->fDevice) {
fMatrix = rec->fMatrix;
- fClip = &((SkRasterClip*)&rec->fClip)->forceGetBW();
fRC = &rec->fClip;
fDevice = rec->fDevice;
if (!fDevice->accessPixels(&fDst)) {
@@ -367,10 +366,10 @@
}
SkBaseDevice* getDevice() const { return fDevice; }
+ 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 SkRegion& getClip() const { return *fClip; }
const SkPaint* getPaint() const { return fPaint; }
private:
@@ -2503,7 +2502,7 @@
// nothing to draw
if (text == nullptr || byteLength == 0 ||
- draw.fClip->isEmpty() ||
+ draw.fRC->isEmpty() ||
(paint.getAlpha() == 0 && paint.getXfermode() == nullptr)) {
return;
}
@@ -2994,7 +2993,7 @@
return *paint;
}
-const SkRegion& SkCanvas::LayerIter::clip() const { return fImpl->getClip(); }
+const SkRasterClip& SkCanvas::LayerIter::clip() const { return fImpl->getClip(); }
int SkCanvas::LayerIter::x() const { return fImpl->getX(); }
int SkCanvas::LayerIter::y() const { return fImpl->getY(); }
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index 24118f4..70f4e07 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -412,7 +412,7 @@
SkIPoint offset = SkIPoint::Make(0, 0);
SkMatrix matrix = *draw.fMatrix;
matrix.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y));
- const SkIRect clipBounds = draw.fClip->getBounds().makeOffset(-x, -y);
+ const SkIRect clipBounds = draw.fRC->getBounds().makeOffset(-x, -y);
SkAutoTUnref<SkImageFilter::Cache> cache(this->getImageFilterCache());
SkImageFilter::Context ctx(matrix, clipBounds, cache.get());
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index 2329734..0cdd3a1 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -1965,7 +1965,6 @@
void SkDraw::validate() const {
SkASSERT(fMatrix != nullptr);
- SkASSERT(fClip != nullptr);
SkASSERT(fRC != nullptr);
const SkIRect& cr = fRC->getBounds();
@@ -2041,7 +2040,6 @@
-SkIntToScalar(mask.fBounds.fTop));
draw.fRC = &clip;
- draw.fClip = &clip.bwRgn();
draw.fMatrix = &matrix;
paint.setAntiAlias(true);
paint.setStyle(style);
diff --git a/src/core/SkRasterClip.cpp b/src/core/SkRasterClip.cpp
index 8946767..88bfbaf 100644
--- a/src/core/SkRasterClip.cpp
+++ b/src/core/SkRasterClip.cpp
@@ -24,6 +24,14 @@
SkDEBUGCODE(this->validate();)
}
+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;
fIsBW = true;
@@ -44,6 +52,22 @@
SkDEBUGCODE(this->validate();)
}
+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;
+ }
+ bool isEqual = fIsBW ? fBW == other.fBW : fAA == other.fAA;
+#ifdef SK_DEBUG
+ if (isEqual) {
+ SkASSERT(fIsEmpty == other.fIsEmpty);
+ SkASSERT(fIsRect == other.fIsRect);
+ }
+#endif
+ return isEqual;
+}
+
bool SkRasterClip::isComplex() const {
return fIsBW ? fBW.isComplex() : !fAA.isEmpty();
}
diff --git a/src/core/SkRasterClip.h b/src/core/SkRasterClip.h
index 5d99f1d..14d34fd 100644
--- a/src/core/SkRasterClip.h
+++ b/src/core/SkRasterClip.h
@@ -13,13 +13,30 @@
class SkRRect;
+/**
+ * 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(bool forceConservativeRects = false);
SkRasterClip(const SkIRect&, bool forceConservativeRects = false);
+ SkRasterClip(const SkRegion&);
SkRasterClip(const SkRasterClip&);
~SkRasterClip();
+ // Only compares the current state. Does not compare isForceConservativeRects(), so that field
+ // could be different but this could still return true.
+ bool operator==(const SkRasterClip&) const;
+ bool operator!=(const SkRasterClip& other) const {
+ return !(*this == other);
+ }
+
bool isForceConservativeRects() const { return fForceConservativeRects; }
bool isBW() const { return fIsBW; }
diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp
index ad753df..85e8994 100644
--- a/src/core/SkScalerContext.cpp
+++ b/src/core/SkScalerContext.cpp
@@ -402,7 +402,6 @@
SkDraw draw;
draw.fDst = dst;
draw.fRC = &clip;
- draw.fClip = &clip.bwRgn();
draw.fMatrix = &matrix;
draw.drawPath(path, paint);
diff --git a/src/effects/SkLayerRasterizer.cpp b/src/effects/SkLayerRasterizer.cpp
index 91502b7..39e3e23 100644
--- a/src/effects/SkLayerRasterizer.cpp
+++ b/src/effects/SkLayerRasterizer.cpp
@@ -129,7 +129,6 @@
draw.fMatrix = &drawMatrix;
draw.fRC = &rectClip;
- draw.fClip = &rectClip.bwRgn();
// we set the matrixproc in the loop, as the matrix changes each time (potentially)
SkDeque::F2BIter iter(*fLayers);
diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp
index 0e1fd3e..b69edab 100644
--- a/src/gpu/GrSWMaskHelper.cpp
+++ b/src/gpu/GrSWMaskHelper.cpp
@@ -215,7 +215,6 @@
fDraw.fDst = fPixels;
fRasterClip.setRect(bounds);
fDraw.fRC = &fRasterClip;
- fDraw.fClip = &fRasterClip.bwRgn();
fDraw.fMatrix = &fMatrix;
return true;
}
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index f6137de..535d55e 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -32,6 +32,7 @@
#include "SkPathEffect.h"
#include "SkPicture.h"
#include "SkPictureData.h"
+#include "SkRasterClip.h"
#include "SkRRect.h"
#include "SkRecord.h"
#include "SkStroke.h"
@@ -515,7 +516,7 @@
GrBlurUtils::drawPathWithMaskFilter(fContext, fDrawContext,
fClip, path, paint,
*draw.fMatrix, nullptr,
- draw.fClip->getBounds(), true);
+ draw.fRC->getBounds(), true);
return;
}
@@ -553,12 +554,12 @@
if (devRRect.allCornersCircular()) {
SkRect maskRect;
if (paint.getMaskFilter()->canFilterMaskGPU(devRRect,
- draw.fClip->getBounds(),
+ draw.fRC->getBounds(),
*draw.fMatrix,
&maskRect)) {
SkIRect finalIRect;
maskRect.roundOut(&finalIRect);
- if (draw.fClip->quickReject(finalIRect)) {
+ if (draw.fRC->quickReject(finalIRect)) {
// clipped out
return;
}
@@ -587,7 +588,7 @@
GrBlurUtils::drawPathWithMaskFilter(fContext, fDrawContext,
fClip, path, paint,
*draw.fMatrix, nullptr,
- draw.fClip->getBounds(), true);
+ draw.fRC->getBounds(), true);
return;
}
@@ -633,7 +634,7 @@
GrBlurUtils::drawPathWithMaskFilter(fContext, fDrawContext,
fClip, path, paint,
*draw.fMatrix, nullptr,
- draw.fClip->getBounds(), true);
+ draw.fRC->getBounds(), true);
}
@@ -703,7 +704,7 @@
GrBlurUtils::drawPathWithMaskFilter(fContext, fDrawContext,
fClip, origSrcPath, paint,
*draw.fMatrix, prePathMatrix,
- draw.fClip->getBounds(), pathIsMutable);
+ draw.fRC->getBounds(), pathIsMutable);
}
static const int kBmpSmallTileSize = 1 << 10;
@@ -1676,7 +1677,7 @@
SkDEBUGCODE(this->validate();)
fDrawContext->drawText(fClip, grPaint, paint, *draw.fMatrix,
- (const char *)text, byteLength, x, y, draw.fClip->getBounds());
+ (const char *)text, byteLength, x, y, draw.fRC->getBounds());
}
void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text, size_t byteLength,
@@ -1696,7 +1697,7 @@
fDrawContext->drawPosText(fClip, grPaint, paint, *draw.fMatrix,
(const char *)text, byteLength, pos, scalarsPerPos, offset,
- draw.fClip->getBounds());
+ draw.fRC->getBounds());
}
void SkGpuDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkScalar x, SkScalar y,
@@ -1708,7 +1709,7 @@
SkDEBUGCODE(this->validate();)
fDrawContext->drawTextBlob(fClip, paint, *draw.fMatrix,
- blob, x, y, drawFilter, draw.fClip->getBounds());
+ blob, x, y, drawFilter, draw.fRC->getBounds());
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp b/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
index 655a771..f891b8d 100644
--- a/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
+++ b/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
@@ -379,7 +379,6 @@
SkRasterClip rasterClip;
rasterClip.setRect(devPathBounds);
draw.fRC = &rasterClip;
- draw.fClip = &rasterClip.bwRgn();
draw.fMatrix = &drawMatrix;
draw.fDst = dst;
diff --git a/src/pdf/SkPDFCanvas.cpp b/src/pdf/SkPDFCanvas.cpp
index de3dc93..f3ba66b 100644
--- a/src/pdf/SkPDFCanvas.cpp
+++ b/src/pdf/SkPDFCanvas.cpp
@@ -14,6 +14,23 @@
SkPDFCanvas::~SkPDFCanvas() {}
+/*
+ * PDF's impl sometimes wants to access the raster clip as a SkRegion. To keep this valid,
+ * we intercept all clip calls to ensure that the clip stays BW (i.e. never antialiased), since
+ * an antialiased clip won't build a SkRegion (it builds SkAAClip).
+ */
+void SkPDFCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
+ this->INHERITED::onClipRect(rect, op, kHard_ClipEdgeStyle);
+}
+
+void SkPDFCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
+ this->INHERITED::onClipRRect(rrect, op, kHard_ClipEdgeStyle);
+}
+
+void SkPDFCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
+ this->INHERITED::onClipPath(path, op, kHard_ClipEdgeStyle);
+}
+
void SkPDFCanvas::onDrawBitmapNine(const SkBitmap& bitmap,
const SkIRect& center,
const SkRect& dst,
diff --git a/src/pdf/SkPDFCanvas.h b/src/pdf/SkPDFCanvas.h
index 3a673e2..1c3ec71 100644
--- a/src/pdf/SkPDFCanvas.h
+++ b/src/pdf/SkPDFCanvas.h
@@ -17,6 +17,10 @@
~SkPDFCanvas();
protected:
+ void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) override;
+ void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) override;
+ void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) override;
+
void onDrawBitmapNine(const SkBitmap&, const SkIRect&, const SkRect&,
const SkPaint*) override;
@@ -34,6 +38,9 @@
const SkRect&,
const SkPaint*,
SkCanvas::SrcRectConstraint) override;
+
+private:
+ typedef SkCanvas INHERITED;
};
#endif // SkPDFCanvas_DEFINED
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index fb4d251..5b4ae93 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -567,7 +567,7 @@
fContentEntry(nullptr),
fXfermode(SkXfermode::kSrcOver_Mode),
fDstFormXObject(nullptr) {
- init(draw.fClipStack, *draw.fClip, *draw.fMatrix, paint, hasText);
+ init(draw.fClipStack, draw.fRC->bwRgn(), *draw.fMatrix, paint, hasText);
}
ScopedContentEntry(SkPDFDevice* device, const SkClipStack* clipStack,
const SkRegion& clipRegion, const SkMatrix& matrix,
@@ -752,7 +752,7 @@
// We only use this when there's a path effect because of the overhead
// of multiple calls to setUpContentEntry it causes.
if (passedPaint.getPathEffect()) {
- if (d.fClip->isEmpty()) {
+ if (d.fRC->isEmpty()) {
return;
}
SkDraw pointDraw(d);
@@ -876,7 +876,7 @@
r.sort();
if (paint.getPathEffect()) {
- if (d.fClip->isEmpty()) {
+ if (d.fRC->isEmpty()) {
return;
}
SkPath path;
@@ -938,7 +938,7 @@
}
if (paint.getPathEffect()) {
- if (d.fClip->isEmpty()) {
+ if (d.fRC->isEmpty()) {
return;
}
if (!pathIsMutable) {
@@ -963,7 +963,7 @@
return;
}
- ScopedContentEntry content(this, d.fClipStack, *d.fClip, matrix, paint);
+ ScopedContentEntry content(this, d.fClipStack, d.fRC->bwRgn(), matrix, paint);
if (!content.entry()) {
return;
}
@@ -996,7 +996,7 @@
replace_srcmode_on_opaque_paint(&paint);
}
- if (d.fClip->isEmpty()) {
+ if (d.fRC->isEmpty()) {
return;
}
@@ -1004,7 +1004,7 @@
transform.postConcat(*d.fMatrix);
SkImageBitmap imageBitmap(bitmap);
this->internalDrawImage(
- transform, d.fClipStack, *d.fClip, imageBitmap, paint);
+ transform, d.fClipStack, d.fRC->bwRgn(), imageBitmap, paint);
}
void SkPDFDevice::drawSprite(const SkDraw& d,
@@ -1017,7 +1017,7 @@
replace_srcmode_on_opaque_paint(&paint);
}
- if (d.fClip->isEmpty()) {
+ if (d.fRC->isEmpty()) {
return;
}
@@ -1025,7 +1025,7 @@
matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y));
SkImageBitmap imageBitmap(bitmap);
this->internalDrawImage(
- matrix, d.fClipStack, *d.fClip, imageBitmap, paint);
+ matrix, d.fClipStack, d.fRC->bwRgn(), imageBitmap, paint);
}
void SkPDFDevice::drawImage(const SkDraw& draw,
@@ -1040,14 +1040,14 @@
if (image->isOpaque()) {
replace_srcmode_on_opaque_paint(&paint);
}
- if (draw.fClip->isEmpty()) {
+ if (draw.fRC->isEmpty()) {
return;
}
SkMatrix transform = SkMatrix::MakeTrans(x, y);
transform.postConcat(*draw.fMatrix);
SkImageBitmap imageBitmap(const_cast<SkImage*>(image));
this->internalDrawImage(
- transform, draw.fClipStack, *draw.fClip, imageBitmap, paint);
+ transform, draw.fClipStack, draw.fRC->bwRgn(), imageBitmap, paint);
}
void SkPDFDevice::drawImageRect(const SkDraw& draw,
@@ -1277,7 +1277,7 @@
const SkPoint texs[], const SkColor colors[],
SkXfermode* xmode, const uint16_t indices[],
int indexCount, const SkPaint& paint) {
- if (d.fClip->isEmpty()) {
+ if (d.fRC->isEmpty()) {
return;
}
// TODO: implement drawVertices
@@ -1309,7 +1309,7 @@
SkMatrix matrix;
matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y));
- ScopedContentEntry content(this, d.fClipStack, *d.fClip, matrix, paint);
+ ScopedContentEntry content(this, d.fClipStack, d.fRC->bwRgn(), matrix, paint);
if (!content.entry()) {
return;
}
@@ -1434,7 +1434,7 @@
return false;
}
- if (d.fClip->isEmpty()) {
+ if (d.fRC->isEmpty()) {
return false;
}
@@ -1470,7 +1470,7 @@
if (!totalMatrix.invert(&transformInverse)) {
return false;
}
- bounds.set(d.fClip->getBounds());
+ bounds.set(d.fRC->getBounds());
transformInverse.mapRect(&bounds);
// Extend the bounds by the line width (plus some padding)
@@ -1758,9 +1758,10 @@
SkPDFFormXObject* dstMask = srcFormXObject.get();
if (shape != nullptr) {
// Draw shape into a form-xobject.
+ SkRasterClip rc(clipRegion);
SkDraw d;
d.fMatrix = &identity;
- d.fClip = &clipRegion;
+ d.fRC = &rc;
d.fClipStack = &clipStack;
SkPaint filledPaint;
filledPaint.setColor(SK_ColorBLACK);
diff --git a/src/utils/SkCanvasStateUtils.cpp b/src/utils/SkCanvasStateUtils.cpp
index 2c34d36..462636e 100644
--- a/src/utils/SkCanvasStateUtils.cpp
+++ b/src/utils/SkCanvasStateUtils.cpp
@@ -11,6 +11,7 @@
#include "SkCanvasStack.h"
#include "SkDevice.h"
#include "SkErrorInternals.h"
+#include "SkRasterClip.h"
#include "SkWriter32.h"
/*
@@ -250,7 +251,7 @@
layerState->raster.rowBytes = pmap.rowBytes();
layerState->raster.pixels = pmap.writable_addr();
- setup_MC_state(&layerState->mcState, layer.matrix(), layer.clip());
+ setup_MC_state(&layerState->mcState, layer.matrix(), layer.clip().bwRgn());
layerCount++;
}
diff --git a/src/xps/SkXPSDevice.cpp b/src/xps/SkXPSDevice.cpp
index febd027..90fc680 100644
--- a/src/xps/SkXPSDevice.cpp
+++ b/src/xps/SkXPSDevice.cpp
@@ -35,6 +35,7 @@
#include "SkPathEffect.h"
#include "SkPathOps.h"
#include "SkPoint.h"
+#include "SkRasterClip.h"
#include "SkRasterizer.h"
#include "SkSFNTHeader.h"
#include "SkShader.h"
@@ -1210,7 +1211,7 @@
bool transformRect,
const SkPaint& paint) {
//Exit early if there is nothing to draw.
- if (d.fClip->isEmpty() ||
+ if (d.fRC->isEmpty() ||
(paint.getAlpha() == 0 && paint.getXfermode() == nullptr)) {
return;
}
@@ -1526,7 +1527,7 @@
SkTCopyOnFirstWrite<SkPaint> paint(origPaint);
// nothing to draw
- if (d.fClip->isEmpty() ||
+ if (d.fRC->isEmpty() ||
(paint->getAlpha() == 0 && paint->getXfermode() == nullptr)) {
return;
}
@@ -1609,7 +1610,7 @@
this->convertToPpm(filter,
&matrix,
&ppuScale,
- d.fClip->getBounds(),
+ d.fRC->getBounds(),
&clipIRect);
SkMask* mask = nullptr;
@@ -1647,7 +1648,7 @@
this->convertToPpm(filter,
&matrix,
&ppuScale,
- d.fClip->getBounds(),
+ d.fRC->getBounds(),
&clipIRect);
//[Fillable-path -> Pixel-path]
@@ -1765,7 +1766,13 @@
HRESULT SkXPSDevice::clip(IXpsOMVisual* xpsVisual, const SkDraw& d) {
SkPath clipPath;
- SkAssertResult(d.fClip->getBoundaryPath(&clipPath));
+ if (d.fRC->isBW()) {
+ SkAssertResult(d.fRC->bwRgn().getBoundaryPath(&clipPath));
+ } else {
+ // Don't have a way to turn a AAClip into a path, so we just use the bounds.
+ // TODO: consider using fClipStack instead?
+ clipPath.addRect(SkRect::Make(d.fRC->getBounds()));
+ }
return this->clipToPath(xpsVisual, clipPath, XPS_FILL_RULE_EVENODD);
}
@@ -1797,7 +1804,7 @@
void SkXPSDevice::drawBitmap(const SkDraw& d, const SkBitmap& bitmap,
const SkMatrix& matrix, const SkPaint& paint) {
- if (d.fClip->isEmpty()) {
+ if (d.fRC->isEmpty()) {
return;
}