aboutsummaryrefslogtreecommitdiffhomepage
path: root/gm/reveal.cpp
diff options
context:
space:
mode:
authorGravatar Robert Phillips <robertphillips@google.com>2016-10-20 11:58:40 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-10-20 16:57:35 +0000
commitd2fe3bce079671b0210d5c7cddcc712988d0b686 (patch)
tree7026a72db56291aec557115186435a7889166736 /gm/reveal.cpp
parentddb37d67ba4db42fa5c6012b58d0f4985b454dc0 (diff)
Fix bug in raster implementation of SkRRectsGaussianEdgeMaskFilter
The bug was the raster version didn't correctly handle the CTM. This CL also adds a way to test the behavior (by translating the reveal GM around in SampleApp) GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=3729 Change-Id: Iaacc905167d20b453203307e5ef840f552fdbb38 Reviewed-on: https://skia-review.googlesource.com/3729 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'gm/reveal.cpp')
-rw-r--r--gm/reveal.cpp57
1 files changed, 45 insertions, 12 deletions
diff --git a/gm/reveal.cpp b/gm/reveal.cpp
index ef374d3119..b88e7fe62c 100644
--- a/gm/reveal.cpp
+++ b/gm/reveal.cpp
@@ -28,7 +28,9 @@ constexpr int kClipOffset = 32;
class Object {
public:
virtual ~Object() {}
- virtual bool asRRect(SkRRect* rr) const = 0;
+ // When it returns true, this call will have placed a device-space _circle, rect or
+ // simple circular_ RRect in "rr"
+ virtual bool asDevSpaceRRect(const SkMatrix& ctm, SkRRect* rr) const = 0;
virtual SkPath asPath(SkScalar inset) const = 0;
virtual void draw(SkCanvas* canvas, const SkPaint& paint) const = 0;
virtual void clip(SkCanvas* canvas) const = 0;
@@ -44,8 +46,24 @@ public:
fRRect = SkRRect::MakeRectXY(r, 4*kPad, 4*kPad);
}
- bool asRRect(SkRRect* rr) const override {
- *rr = fRRect;
+ bool asDevSpaceRRect(const SkMatrix& ctm, SkRRect* rr) const override {
+ if (!ctm.isSimilarity()) { // the corners have to remain circular
+ return false;
+ }
+
+ SkScalar scales[2];
+ if (!ctm.getMinMaxScales(scales)) {
+ return false;
+ }
+
+ SkASSERT(SkScalarNearlyEqual(scales[0], scales[1]));
+
+ SkRect devRect;
+ ctm.mapRect(&devRect, fRRect.rect());
+
+ SkScalar scaledRad = scales[0] * fRRect.getSimpleRadii().fX;
+
+ *rr = SkRRect::MakeRectXY(devRect, scaledRad, scaledRad);
return true;
}
@@ -88,7 +106,7 @@ public:
fStrokedBounds = r.makeOutset(kPad, kPad);
}
- bool asRRect(SkRRect* rr) const override {
+ bool asDevSpaceRRect(const SkMatrix& ctm, SkRRect* rr) const override {
return false;
}
@@ -144,8 +162,14 @@ public:
fRRect = SkRRect::MakeOval(r);
}
- bool asRRect(SkRRect* rr) const override {
- *rr = fRRect;
+ bool asDevSpaceRRect(const SkMatrix& ctm, SkRRect* rr) const override {
+ if (!ctm.isSimilarity()) { // circles have to remain circles
+ return false;
+ }
+
+ SkRect devRect;
+ ctm.mapRect(&devRect, fRRect.rect());
+ *rr = SkRRect::MakeOval(devRect);
return true;
}
@@ -186,8 +210,14 @@ class Rect : public Object {
public:
Rect(const SkRect& r) : fRect(r) { }
- bool asRRect(SkRRect* rr) const override {
- *rr = SkRRect::MakeRect(fRect);
+ bool asDevSpaceRRect(const SkMatrix& ctm, SkRRect* rr) const override {
+ if (!ctm.rectStaysRect()) {
+ return false;
+ }
+
+ SkRect devRect;
+ ctm.mapRect(&devRect, fRect);
+ *rr = SkRRect::MakeRect(devRect);
return true;
}
@@ -246,7 +276,7 @@ public:
fPath.close();
}
- bool asRRect(SkRRect* rr) const override {
+ bool asDevSpaceRRect(const SkMatrix& ctm, SkRRect* rr) const override {
return false;
}
@@ -311,6 +341,7 @@ public:
}
protected:
+ bool runAsBench() const override { return true; }
SkString onShortName() override {
return SkString("reveal");
@@ -393,10 +424,12 @@ protected:
SkPaint paint;
- SkRRect clipRR, drawnRR;
+ SkRRect devSpaceClipRR, devSpaceDrawnRR;
- if (clipObj->asRRect(&clipRR) && drawObj->asRRect(&drawnRR)) {
- paint.setMaskFilter(SkRRectsGaussianEdgeMaskFilter::Make(clipRR, drawnRR,
+ if (clipObj->asDevSpaceRRect(canvas->getTotalMatrix(), &devSpaceClipRR) &&
+ drawObj->asDevSpaceRRect(canvas->getTotalMatrix(), &devSpaceDrawnRR)) {
+ paint.setMaskFilter(SkRRectsGaussianEdgeMaskFilter::Make(devSpaceClipRR,
+ devSpaceDrawnRR,
fBlurRadius));
}