aboutsummaryrefslogtreecommitdiffhomepage
path: root/gm/occludedrrectblur.cpp
diff options
context:
space:
mode:
authorGravatar robertphillips <robertphillips@google.com>2016-08-04 12:35:46 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-08-04 12:35:46 -0700
commit401c1968a1727b7dd1543f7e5536ca544fc6d752 (patch)
tree6c3149fdb57b5b9b4a59e2162117e50519433264 /gm/occludedrrectblur.cpp
parent1ba1d372c2727db56021d0687825320b12d10d4e (diff)
Add new GM for occluded blurmask filter draws
This splits out just the GM portion of https://codereview.chromium.org/2201993003/ (Add GM to test out blurmaskfilter occluders) which included some API changes GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2214033002 Review-Url: https://codereview.chromium.org/2214033002
Diffstat (limited to 'gm/occludedrrectblur.cpp')
-rw-r--r--gm/occludedrrectblur.cpp320
1 files changed, 320 insertions, 0 deletions
diff --git a/gm/occludedrrectblur.cpp b/gm/occludedrrectblur.cpp
new file mode 100644
index 0000000000..da2bf5d38e
--- /dev/null
+++ b/gm/occludedrrectblur.cpp
@@ -0,0 +1,320 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gm.h"
+#include "SkBlurMaskFilter.h"
+#include "SkRRect.h"
+#include "sk_tool_utils.h"
+
+static SkRect offset_center_to(const SkIRect& src, SkScalar x, SkScalar y) {
+ SkScalar halfW = 0.5f * src.width();
+ SkScalar halfH = 0.5f * src.height();
+
+ return SkRect::MakeLTRB(x - halfW, y - halfH, x + halfW, y + halfH);
+}
+
+static void draw_rrect(SkCanvas* canvas, const SkRRect& rr, const SkRRect& occRR) {
+ const SkScalar kBlurSigma = 5.0f;
+
+ SkRect occRect;
+ SkColor strokeColor;
+
+ {
+ SkRect occRect1 = sk_tool_utils::compute_central_occluder(occRR);
+ SkRect occRect2 = sk_tool_utils::compute_widest_occluder(occRR);
+ SkRect occRect3 = sk_tool_utils::compute_tallest_occluder(occRR);
+
+ SkScalar area1 = occRect1.width() * occRect1.height();
+ SkScalar area2 = occRect2.width() * occRect2.height();
+ SkScalar area3 = occRect3.width() * occRect3.height();
+
+ if (area1 >= area2 && area1 >= area3) {
+ strokeColor = SK_ColorRED;
+ occRect = occRect1;
+ } else if (area2 > area3) {
+ strokeColor = SK_ColorYELLOW;
+ occRect = occRect2;
+ } else {
+ strokeColor = SK_ColorCYAN;
+ occRect = occRect3;
+ }
+ }
+
+ // draw the blur
+ SkPaint paint;
+ paint.setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle, kBlurSigma)); //, occRect));
+ canvas->drawRRect(rr, paint);
+
+ // draw the stroked geometry of the full occluder
+ SkPaint stroke;
+ stroke.setStyle(SkPaint::kStroke_Style);
+ stroke.setColor(SK_ColorBLUE);
+ canvas->drawRRect(occRR, stroke);
+
+ // draw the geometry of the occluding rect
+ stroke.setColor(strokeColor);
+ canvas->drawRect(occRect, stroke);
+}
+
+static void draw_45(SkCanvas* canvas, SkRRect::Corner corner,
+ SkScalar dist, const SkPoint& center) {
+ SkRRect::Corner left = SkRRect::kUpperLeft_Corner, right = SkRRect::kUpperLeft_Corner;
+ SkVector dir = { 0, 0 };
+
+ static const SkScalar kSize = 64.0f / SK_ScalarSqrt2;
+
+ switch (corner) {
+ case SkRRect::kUpperLeft_Corner:
+ left = SkRRect::kUpperRight_Corner;
+ right = SkRRect::kLowerLeft_Corner;
+
+ dir.set(-SK_ScalarRoot2Over2, -SK_ScalarRoot2Over2);
+ break;
+ case SkRRect::kUpperRight_Corner:
+ left = SkRRect::kUpperLeft_Corner;
+ right = SkRRect::kLowerRight_Corner;
+ dir.set(SK_ScalarRoot2Over2, -SK_ScalarRoot2Over2);
+ break;
+ case SkRRect::kLowerRight_Corner:
+ left = SkRRect::kLowerLeft_Corner;
+ right = SkRRect::kUpperRight_Corner;
+ dir.set(SK_ScalarRoot2Over2, SK_ScalarRoot2Over2);
+ break;
+ case SkRRect::kLowerLeft_Corner:
+ left = SkRRect::kLowerRight_Corner;
+ right = SkRRect::kUpperLeft_Corner;
+ dir.set(-SK_ScalarRoot2Over2, SK_ScalarRoot2Over2);
+ break;
+ default:
+ SkFAIL("Invalid shape.");
+ }
+
+ SkRect r = SkRect::MakeWH(kSize, kSize);
+ // UL, UR, LR, LL
+ SkVector radii[4] = { { 0.0f, 0.0f }, { 0.0f, 0.0f }, { 0.0f, 0.0f }, { 0.0f, 0.0f } };
+ radii[left] = SkVector::Make(kSize, kSize);
+ radii[right] = SkVector::Make(kSize, kSize);
+ SkRRect rr;
+ rr.setRectRadii(
+ offset_center_to(r.roundOut(), center.fX + dist*dir.fX, center.fY + dist*dir.fY),
+ radii);
+
+ SkRRect occRR;
+ dist -= 10.0f;
+ occRR.setRectRadii(
+ offset_center_to(r.roundOut(), center.fX + dist*dir.fX, center.fY + dist*dir.fY),
+ radii);
+
+ draw_rrect(canvas, rr, occRR);
+}
+
+static void draw_45_simple(SkCanvas* canvas, const SkVector& v,
+ SkScalar dist, const SkPoint& center) {
+ SkIRect r = SkIRect::MakeWH(64, 64);
+ SkRRect rr = SkRRect::MakeRectXY(
+ offset_center_to(r, center.fX + dist*v.fX, center.fY + dist*v.fY),
+ 8, 8);
+
+ dist -= 10.0f;
+ SkRRect occRR = SkRRect::MakeRectXY(
+ offset_center_to(r, center.fX + dist*v.fX, center.fY + dist*v.fY),
+ 8, 8);
+
+ draw_rrect(canvas, rr, occRR);
+}
+
+static void draw_90(SkCanvas* canvas, const SkVector& v, SkScalar dist, const SkPoint& center) {
+ static const int kWidth = 25;
+
+ SkIRect r;
+ if (fabs(v.fX) < fabs(v.fY)) {
+ r = SkIRect::MakeWH(kWidth, 64);
+ } else {
+ r = SkIRect::MakeWH(64, kWidth);
+ }
+ SkRRect rr = SkRRect::MakeOval(
+ offset_center_to(r, center.fX + dist*v.fX, center.fY + dist*v.fY));
+
+ dist -= 10.0f;
+ SkRRect occRR = SkRRect::MakeOval(
+ offset_center_to(r, center.fX + dist*v.fX, center.fY + dist*v.fY));
+
+ draw_rrect(canvas, rr, occRR);
+}
+
+static void draw_90_simple(SkCanvas* canvas, const SkVector& v,
+ SkScalar dist, const SkPoint& center) {
+ static const int kLength = 128;
+ static const int kWidth = 32;
+
+ SkIRect r;
+ if (fabs(v.fX) < fabs(v.fY)) {
+ r = SkIRect::MakeWH(kLength, kWidth);
+ } else {
+ r = SkIRect::MakeWH(kWidth, kLength);
+ }
+ SkRRect rr = SkRRect::MakeRectXY(
+ offset_center_to(r, center.fX + dist*v.fX, center.fY + dist*v.fY),
+ 8, 8);
+
+ dist -= 10.0f;
+ SkRRect occRR = SkRRect::MakeRectXY(
+ offset_center_to(r, center.fX + dist*v.fX, center.fY + dist*v.fY),
+ 8, 8);
+
+ draw_rrect(canvas, rr, occRR);
+}
+
+static void draw_30_60(SkCanvas* canvas, SkRRect::Corner corner, const SkVector& v,
+ SkScalar dist, const SkPoint& center) {
+ SkRRect::Corner left = SkRRect::kUpperLeft_Corner, right = SkRRect::kUpperLeft_Corner;
+
+ static const int kLength = 64;
+ static const int kWidth = 30;
+
+ switch (corner) {
+ case SkRRect::kUpperLeft_Corner:
+ left = SkRRect::kUpperRight_Corner;
+ right = SkRRect::kLowerLeft_Corner;
+ break;
+ case SkRRect::kUpperRight_Corner:
+ left = SkRRect::kUpperLeft_Corner;
+ right = SkRRect::kLowerRight_Corner;
+ break;
+ case SkRRect::kLowerRight_Corner:
+ left = SkRRect::kLowerLeft_Corner;
+ right = SkRRect::kUpperRight_Corner;
+ break;
+ case SkRRect::kLowerLeft_Corner:
+ left = SkRRect::kLowerRight_Corner;
+ right = SkRRect::kUpperLeft_Corner;
+ break;
+ default:
+ SkFAIL("Invalid shape.");
+ }
+
+ SkIRect r;
+ if (fabs(v.fX) < fabs(v.fY)) {
+ r = SkIRect::MakeWH(kLength, kWidth);
+ } else {
+ r = SkIRect::MakeWH(kWidth, kLength);
+ }
+ // UL, UR, LR, LL
+ SkVector radii[4] = { { 0.0f, 0.0f }, { 0.0f, 0.0f }, { 0.0f, 0.0f }, { 0.0f, 0.0f } };
+ radii[left] = SkVector::Make(SkIntToScalar(kWidth), SkIntToScalar(kWidth));
+ radii[right] = SkVector::Make(SkIntToScalar(kWidth), SkIntToScalar(kWidth));
+ SkRRect rr;
+ rr.setRectRadii(offset_center_to(r, center.fX + dist*v.fX, center.fY + dist*v.fY), radii);
+
+ dist -= 10.0f;
+ SkRRect occRR;
+ occRR.setRectRadii(offset_center_to(r, center.fX + dist*v.fX, center.fY + dist*v.fY), radii);
+ draw_rrect(canvas, rr, occRR);
+}
+
+namespace skiagm {
+
+class OccludedRRectBlurGM : public GM {
+public:
+ OccludedRRectBlurGM() {
+ this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC));
+ }
+
+protected:
+
+ SkString onShortName() override {
+ return SkString("occludedrrectblur");
+ }
+
+ SkISize onISize() override {
+ return SkISize::Make(kWidth, kHeight);
+ }
+
+ void onDraw(SkCanvas* canvas) override {
+ const SkPoint center = SkPoint::Make(kWidth/2, kHeight/2);
+
+ // outer-most big RR
+ {
+ SkIRect r = SkIRect::MakeWH(420, 420);
+ SkRRect rr = SkRRect::MakeRectXY(offset_center_to(r, center.fX, center.fY), 64, 64);
+ draw_rrect(canvas, rr, rr);
+
+#if 1
+ // TODO: remove this. Until we actually start skipping the middle draw we need this
+ // to provide contrast
+ SkPaint temp;
+ temp.setColor(sk_tool_utils::color_to_565(0xFFCCCCCC));
+ r.inset(32, 32);
+ canvas->drawRect(offset_center_to(r, center.fX, center.fY), temp);
+#endif
+ }
+
+ // center circle
+ {
+ SkIRect r = SkIRect::MakeWH(32, 32);
+ SkRRect rr = SkRRect::MakeOval(offset_center_to(r, center.fX, center.fY));
+ draw_rrect(canvas, rr, rr);
+ }
+
+ draw_45(canvas, SkRRect::kUpperLeft_Corner, 64, center);
+ draw_45(canvas, SkRRect::kUpperRight_Corner, 64, center);
+ draw_45(canvas, SkRRect::kLowerRight_Corner, 64, center);
+ draw_45(canvas, SkRRect::kLowerLeft_Corner, 64, center);
+
+ draw_90(canvas, SkVector::Make(-1.0f, 0.0f), 64, center);
+ draw_90(canvas, SkVector::Make(0.0f, -1.0f), 64, center);
+ draw_90(canvas, SkVector::Make(1.0f, 0.0f), 64, center);
+ draw_90(canvas, SkVector::Make(0.0f, 1.0f), 64, center);
+
+ static const SkScalar kRoot3Over2 = 0.8660254037844386f;
+
+ draw_30_60(canvas, SkRRect::kLowerLeft_Corner,
+ SkVector::Make(0.5f, kRoot3Over2), 120, center);
+ draw_30_60(canvas, SkRRect::kUpperRight_Corner,
+ SkVector::Make(kRoot3Over2, 0.5f), 120, center);
+
+ draw_30_60(canvas, SkRRect::kUpperLeft_Corner,
+ SkVector::Make(-0.5f, kRoot3Over2), 120, center);
+ draw_30_60(canvas, SkRRect::kLowerRight_Corner,
+ SkVector::Make(-kRoot3Over2, 0.5f), 120, center);
+
+ draw_30_60(canvas, SkRRect::kLowerLeft_Corner,
+ SkVector::Make(-0.5f, -kRoot3Over2), 120, center);
+ draw_30_60(canvas, SkRRect::kUpperRight_Corner,
+ SkVector::Make(-kRoot3Over2, -0.5f), 120, center);
+
+ draw_30_60(canvas, SkRRect::kUpperLeft_Corner,
+ SkVector::Make(0.5f, -kRoot3Over2), 120, center);
+ draw_30_60(canvas, SkRRect::kLowerRight_Corner,
+ SkVector::Make(kRoot3Over2, -0.5f), 120, center);
+
+ draw_45_simple(canvas, SkVector::Make(-SK_ScalarRoot2Over2, -SK_ScalarRoot2Over2),
+ 190, center);
+ draw_45_simple(canvas, SkVector::Make(SK_ScalarRoot2Over2, -SK_ScalarRoot2Over2),
+ 190, center);
+ draw_45_simple(canvas, SkVector::Make(SK_ScalarRoot2Over2, SK_ScalarRoot2Over2),
+ 190, center);
+ draw_45_simple(canvas, SkVector::Make(-SK_ScalarRoot2Over2, SK_ScalarRoot2Over2),
+ 190, center);
+
+ draw_90_simple(canvas, SkVector::Make(-1.0f, 0.0f), 150, center);
+ draw_90_simple(canvas, SkVector::Make(0.0f, -1.0f), 150, center);
+ draw_90_simple(canvas, SkVector::Make(1.0f, 0.0f), 150, center);
+ draw_90_simple(canvas, SkVector::Make(0.0f, 1.0f), 150, center);
+ }
+
+private:
+ static const int kWidth = 440;
+ static const int kHeight = 440;
+
+ typedef GM INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+DEF_GM(return new OccludedRRectBlurGM;)
+}