aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar senorblanco <senorblanco@chromium.org>2016-02-02 18:44:15 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2016-02-02 18:44:16 -0800
commitafc7cce5d68663934128d76963cd501f771d71de (patch)
treeb13153dfaeb926a130a946ccf7010b8253f06518 /src/core
parent67e8bd207261ed4a4b30c4e488a6a2b6baf04d7a (diff)
Fix for rounded-rect clips with filters.
Don't use the base canvas size to limit raster of complex clips, since the top canvas size may actually be larger (e.g., a blur filter which expands the clip bounds to accommodate filter margins). Use the top canvas bounds instead. BUG=skia:4879,471212 GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1657333002 Review URL: https://codereview.chromium.org/1657333002
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkCanvas.cpp29
-rw-r--r--src/core/SkRasterClip.cpp16
-rw-r--r--src/core/SkRasterClip.h6
3 files changed, 22 insertions, 29 deletions
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index ce08d41a1f..c8c4b8749b 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -812,19 +812,17 @@ void SkCanvas::flush() {
}
}
-SkISize SkCanvas::getTopLayerSize() const {
- SkBaseDevice* d = this->getTopDevice();
+SkISize SkCanvas::getBaseLayerSize() const {
+ SkBaseDevice* d = this->getDevice();
return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0);
}
-SkIPoint SkCanvas::getTopLayerOrigin() const {
+SkIRect SkCanvas::getTopLayerBounds() const {
SkBaseDevice* d = this->getTopDevice();
- return d ? d->getOrigin() : SkIPoint::Make(0, 0);
-}
-
-SkISize SkCanvas::getBaseLayerSize() const {
- SkBaseDevice* d = this->getDevice();
- return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0);
+ if (!d) {
+ return SkIRect::MakeEmpty();
+ }
+ return SkIRect::MakeXYWH(d->getOrigin().x(), d->getOrigin().y(), d->width(), d->height());
}
SkBaseDevice* SkCanvas::getDevice() const {
@@ -1516,7 +1514,7 @@ void SkCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edg
if (rectStaysRect) {
const bool isAA = kSoft_ClipEdgeStyle == edgeStyle;
fClipStack->clipDevRect(devR, op, isAA);
- fMCRec->fRasterClip.op(devR, this->getBaseLayerSize(), op, isAA);
+ fMCRec->fRasterClip.op(devR, this->getTopLayerBounds(), op, isAA);
} else {
// since we're rotated or some such thing, we convert the rect to a path
// and clip against that, since it can handle any matrix. However, to
@@ -1529,11 +1527,6 @@ void SkCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edg
}
}
-static void rasterclip_path(SkRasterClip* rc, const SkCanvas* canvas, const SkPath& devPath,
- SkRegion::Op op, bool doAA) {
- rc->op(devPath, canvas->getBaseLayerSize(), op, doAA);
-}
-
void SkCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) {
this->checkForDeferredSave();
ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle;
@@ -1557,7 +1550,7 @@ void SkCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle
fClipStack->clipDevRRect(transformedRRect, op, kSoft_ClipEdgeStyle == edgeStyle);
- fMCRec->fRasterClip.op(transformedRRect, this->getBaseLayerSize(), op,
+ fMCRec->fRasterClip.op(transformedRRect, this->getTopLayerBounds(), op,
kSoft_ClipEdgeStyle == edgeStyle);
return;
}
@@ -1643,7 +1636,7 @@ void SkCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edg
op = SkRegion::kReplace_Op;
}
- rasterclip_path(&fMCRec->fRasterClip, this, devPath, op, edgeStyle);
+ fMCRec->fRasterClip.op(devPath, this->getTopLayerBounds(), op, edgeStyle);
}
void SkCanvas::clipRegion(const SkRegion& rgn, SkRegion::Op op) {
@@ -1691,7 +1684,7 @@ void SkCanvas::validateClip() const {
default: {
SkPath path;
element->asPath(&path);
- rasterclip_path(&tmpClip, this, path, element->getOp(), element->isAA());
+ tmpClip.op(path, this->getTopLayerBounds(), element->getOp(), element->isAA());
break;
}
}
diff --git a/src/core/SkRasterClip.cpp b/src/core/SkRasterClip.cpp
index ea1a7db429..5afe279b95 100644
--- a/src/core/SkRasterClip.cpp
+++ b/src/core/SkRasterClip.cpp
@@ -161,18 +161,18 @@ bool SkRasterClip::setPath(const SkPath& path, const SkRegion& clip, bool doAA)
return this->updateCacheAndReturnNonEmpty();
}
-bool SkRasterClip::op(const SkRRect& rrect, const SkISize& size, SkRegion::Op op, bool doAA) {
+bool SkRasterClip::op(const SkRRect& rrect, const SkIRect& bounds, SkRegion::Op op, bool doAA) {
if (fForceConservativeRects) {
- return this->op(rrect.getBounds(), size, op, doAA);
+ return this->op(rrect.getBounds(), bounds, op, doAA);
}
SkPath path;
path.addRRect(rrect);
- return this->op(path, size, op, doAA);
+ return this->op(path, bounds, op, doAA);
}
-bool SkRasterClip::op(const SkPath& path, const SkISize& size, SkRegion::Op op, bool doAA) {
+bool SkRasterClip::op(const SkPath& path, const SkIRect& bounds, SkRegion::Op op, bool doAA) {
AUTO_RASTERCLIP_VALIDATE(*this);
if (fForceConservativeRects) {
@@ -181,7 +181,7 @@ bool SkRasterClip::op(const SkPath& path, const SkISize& size, SkRegion::Op op,
case kDoNothing_MutateResult:
return !this->isEmpty();
case kReplaceClippedAgainstGlobalBounds_MutateResult:
- ir = SkIRect::MakeSize(size);
+ ir = bounds;
break;
case kContinue_MutateResult:
ir = path.getBounds().roundOut();
@@ -210,7 +210,7 @@ bool SkRasterClip::op(const SkPath& path, const SkISize& size, SkRegion::Op op,
return this->op(clip, op);
}
} else {
- base.setRect(0, 0, size.width(), size.height());
+ base.setRect(bounds);
if (SkRegion::kReplace_Op == op) {
return this->setPath(path, base, doAA);
@@ -285,7 +285,7 @@ static bool nearly_integral(SkScalar x) {
return x - SkScalarFloorToScalar(x) < domain;
}
-bool SkRasterClip::op(const SkRect& r, const SkISize& size, SkRegion::Op op, bool doAA) {
+bool SkRasterClip::op(const SkRect& r, const SkIRect& bounds, SkRegion::Op op, bool doAA) {
AUTO_RASTERCLIP_VALIDATE(*this);
if (fForceConservativeRects) {
@@ -294,7 +294,7 @@ bool SkRasterClip::op(const SkRect& r, const SkISize& size, SkRegion::Op op, boo
case kDoNothing_MutateResult:
return !this->isEmpty();
case kReplaceClippedAgainstGlobalBounds_MutateResult:
- ir = SkIRect::MakeSize(size);
+ ir = bounds;
break;
case kContinue_MutateResult:
ir = r.roundOut();
diff --git a/src/core/SkRasterClip.h b/src/core/SkRasterClip.h
index 4e2b1416e8..8f05bb9b3d 100644
--- a/src/core/SkRasterClip.h
+++ b/src/core/SkRasterClip.h
@@ -45,9 +45,9 @@ public:
bool op(const SkIRect&, SkRegion::Op);
bool op(const SkRegion&, SkRegion::Op);
- bool op(const SkRect&, const SkISize&, SkRegion::Op, bool doAA);
- bool op(const SkRRect&, const SkISize&, SkRegion::Op, bool doAA);
- bool op(const SkPath&, const SkISize&, SkRegion::Op, bool doAA);
+ bool op(const SkRect&, const SkIRect&, SkRegion::Op, bool doAA);
+ bool op(const SkRRect&, const SkIRect&, SkRegion::Op, bool doAA);
+ bool op(const SkPath&, const SkIRect&, SkRegion::Op, bool doAA);
void translate(int dx, int dy, SkRasterClip* dst) const;
void translate(int dx, int dy) {