Index: bench/BlurOccludedRRectBench.cpp |
diff --git a/bench/BlurOccludedRRectBench.cpp b/bench/BlurOccludedRRectBench.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..db36c5f74d0e2cf755c25f59f4f0f39d8d2c3717 |
--- /dev/null |
+++ b/bench/BlurOccludedRRectBench.cpp |
@@ -0,0 +1,136 @@ |
+/* |
+ * 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 "Benchmark.h" |
+#include "SkBlurMaskFilter.h" |
+#include "SkCanvas.h" |
+#include "SkPaint.h" |
+#include "SkRRect.h" |
+#include "SkRect.h" |
+ |
+// compute the intersection point between the diagonal and the ellipse in the |
+// lower right corner |
+static SkPoint intersection(SkScalar w, SkScalar h) { |
+ SkASSERT(w > 0.0f || h > 0.0f); |
+ |
+ return SkPoint::Make(w / SK_ScalarSqrt2, h / SK_ScalarSqrt2); |
+} |
+ |
+// Use the intersection of the corners' diagonals with their ellipses to shrink |
+// the bounding rect |
+static SkRect compute_central_occluder(const SkRRect& rr) { |
reed1
2016/08/03 20:16:18
This could be checked in centrally (but perhaps st
robertphillips
2016/08/04 14:49:58
Done.
|
+ const SkRect r = rr.getBounds(); |
+ |
+ SkScalar newL = r.fLeft, newT = r.fTop, newR = r.fRight, newB = r.fBottom; |
+ |
+ SkVector radii = rr.radii(SkRRect::kUpperLeft_Corner); |
+ if (!radii.isZero()) { |
+ SkPoint p = intersection(radii.fX, radii.fY); |
+ |
+ newL = SkTMax(newL, r.fLeft + radii.fX - p.fX); |
+ newT = SkTMax(newT, r.fTop + radii.fY - p.fY); |
+ } |
+ |
+ radii = rr.radii(SkRRect::kUpperRight_Corner); |
+ if (!radii.isZero()) { |
+ SkPoint p = intersection(radii.fX, radii.fY); |
+ |
+ newR = SkTMin(newR, r.fRight + p.fX - radii.fX); |
+ newT = SkTMax(newT, r.fTop + radii.fY - p.fY); |
+ } |
+ |
+ radii = rr.radii(SkRRect::kLowerRight_Corner); |
+ if (!radii.isZero()) { |
+ SkPoint p = intersection(radii.fX, radii.fY); |
+ |
+ newR = SkTMin(newR, r.fRight + p.fX - radii.fX); |
+ newB = SkTMin(newB, r.fBottom - radii.fY + p.fY); |
+ } |
+ |
+ radii = rr.radii(SkRRect::kLowerLeft_Corner); |
+ if (!radii.isZero()) { |
+ SkPoint p = intersection(radii.fX, radii.fY); |
+ |
+ newL = SkTMax(newL, r.fLeft + radii.fX - p.fX); |
+ newB = SkTMin(newB, r.fBottom - radii.fY + p.fY); |
+ } |
+ |
+ return SkRect::MakeLTRB(newL, newT, newR, newB); |
+} |
+ |
+class BlurOccludedRRectBench : public Benchmark { |
+public: |
+ BlurOccludedRRectBench() {} |
+ |
+ const char* onGetName() override { |
+ return "bluroccludedrrect"; |
+ } |
+ |
+ SkIPoint onGetSize() override { |
+ return SkIPoint::Make(1024, 2048); |
+ } |
+ |
+ void onDraw(int loops, SkCanvas* canvas) override { |
+ for (int l = 0; l < loops; ++l) { |
+ canvas->clear(0xFFFAFAFA); |
+ |
+ SkPaint opaque; |
+ opaque.setAntiAlias(true); |
+ opaque.setColor(SK_ColorWHITE); |
+ |
+ const SkRect r = SkRect::MakeWH(480, 230); |
+ const SkRRect rr = SkRRect::MakeRectXY(r, 8, 8); |
+ SkRect occRect = compute_central_occluder(rr); |
+ |
+ for (int i = 0; i < 2; ++i) { |
+ canvas->save(); |
+ |
+ canvas->translate(i*502.0f+20, 10.0f); |
+ |
+ for (int j = 0; j < 8; ++j) { |
+ canvas->save(); |
+ |
+ canvas->translate(0.0f, j*256.0f); |
+ |
+ SkPaint firstBlur; |
+ firstBlur.setAntiAlias(true); |
+ firstBlur.setColor(0x09000000); |
+ firstBlur.setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle, |
+ 2.5f)); |
+ //, occRect)); |
+ |
+ canvas->drawRRect(rr, firstBlur); |
+ |
+ canvas->save(); |
+ canvas->translate(1.5f, 1.5f); |
+ |
+ SkPaint secondBlur; |
+ secondBlur.setAntiAlias(true); |
+ secondBlur.setColor(0x30000000); |
+ secondBlur.setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle, |
+ 6.0f)); |
+ //, occRect)); |
+ |
+ canvas->drawRRect(rr, secondBlur); |
+ |
+ canvas->restore(); |
+ |
+ canvas->drawRRect(rr, opaque); |
+ |
+ canvas->restore(); |
+ } |
+ |
+ canvas->restore(); |
+ } |
+ } |
+ } |
+ |
+private: |
+ typedef Benchmark INHERITED; |
+}; |
+ |
+DEF_BENCH(return new BlurOccludedRRectBench();) |