| robertphillips@google.com | 1d2f631 | 2013-05-13 14:10:31 +0000 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright 2013 Google Inc. | 
|  | 3 | * | 
|  | 4 | * Use of this source code is governed by a BSD-style license that can be | 
|  | 5 | * found in the LICENSE file. | 
|  | 6 | */ | 
|  | 7 |  | 
| tfarina | f168b86 | 2014-06-19 12:32:29 -0700 | [diff] [blame] | 8 | #include "Benchmark.h" | 
|  | 9 | #include "SkBlurMaskFilter.h" | 
| robertphillips@google.com | 1d2f631 | 2013-05-13 14:10:31 +0000 | [diff] [blame] | 10 | #include "SkCanvas.h" | 
| tfarina | f168b86 | 2014-06-19 12:32:29 -0700 | [diff] [blame] | 11 | #include "SkLayerDrawLooper.h" | 
| robertphillips@google.com | 1d2f631 | 2013-05-13 14:10:31 +0000 | [diff] [blame] | 12 | #include "SkPaint.h" | 
|  | 13 | #include "SkRandom.h" | 
| robertphillips@google.com | 1d2f631 | 2013-05-13 14:10:31 +0000 | [diff] [blame] | 14 |  | 
|  | 15 | // This bench replicates a problematic use case of a draw looper used | 
|  | 16 | // to create an inner blurred rect | 
| tfarina | f168b86 | 2014-06-19 12:32:29 -0700 | [diff] [blame] | 17 | class RectoriBench : public Benchmark { | 
| robertphillips@google.com | 1d2f631 | 2013-05-13 14:10:31 +0000 | [diff] [blame] | 18 | public: | 
| mtklein@google.com | 410e6e8 | 2013-09-13 19:52:27 +0000 | [diff] [blame] | 19 | RectoriBench() {} | 
| robertphillips@google.com | 1d2f631 | 2013-05-13 14:10:31 +0000 | [diff] [blame] | 20 |  | 
|  | 21 | protected: | 
|  | 22 |  | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 23 | const char* onGetName() override { | 
| robertphillips@google.com | 1d2f631 | 2013-05-13 14:10:31 +0000 | [diff] [blame] | 24 | return "rectori"; | 
|  | 25 | } | 
|  | 26 |  | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 27 | void onDraw(const int loops, SkCanvas* canvas) override { | 
| commit-bot@chromium.org | e0e7cfe | 2013-09-09 20:09:12 +0000 | [diff] [blame] | 28 | SkRandom Random; | 
| robertphillips@google.com | 1d2f631 | 2013-05-13 14:10:31 +0000 | [diff] [blame] | 29 |  | 
| commit-bot@chromium.org | 3361471 | 2013-12-03 18:17:16 +0000 | [diff] [blame] | 30 | for (int i = 0; i < loops; i++) { | 
| robertphillips@google.com | b706117 | 2013-09-06 14:16:12 +0000 | [diff] [blame] | 31 | SkScalar blurSigma = Random.nextRangeScalar(1.5f, 25.0f); | 
|  | 32 | SkScalar size = Random.nextRangeScalar(20*blurSigma, 50*blurSigma); | 
| robertphillips@google.com | 1d2f631 | 2013-05-13 14:10:31 +0000 | [diff] [blame] | 33 |  | 
|  | 34 | SkScalar x = Random.nextRangeScalar(0.0f, W - size); | 
|  | 35 | SkScalar y = Random.nextRangeScalar(0.0f, H - size); | 
|  | 36 |  | 
|  | 37 | SkRect inner = { x, y, x + size, y + size }; | 
|  | 38 |  | 
|  | 39 | SkRect outer(inner); | 
|  | 40 | // outer is always outset either 2x or 4x the blur radius (we go with 2x) | 
| robertphillips@google.com | b706117 | 2013-09-06 14:16:12 +0000 | [diff] [blame] | 41 | outer.outset(2*blurSigma, 2*blurSigma); | 
| robertphillips@google.com | 1d2f631 | 2013-05-13 14:10:31 +0000 | [diff] [blame] | 42 |  | 
|  | 43 | SkPath p; | 
|  | 44 |  | 
|  | 45 | p.addRect(outer); | 
|  | 46 | p.addRect(inner); | 
|  | 47 | p.setFillType(SkPath::kEvenOdd_FillType); | 
|  | 48 |  | 
|  | 49 | // This will be used to translate the normal draw outside the | 
|  | 50 | // clip rect and translate the blurred version back inside | 
|  | 51 | SkScalar translate = 2.0f * size; | 
|  | 52 |  | 
|  | 53 | SkPaint paint; | 
| robertphillips@google.com | b706117 | 2013-09-06 14:16:12 +0000 | [diff] [blame] | 54 | paint.setLooper(this->createLooper(-translate, blurSigma))->unref(); | 
| robertphillips@google.com | 1d2f631 | 2013-05-13 14:10:31 +0000 | [diff] [blame] | 55 | paint.setColor(0xff000000 | Random.nextU()); | 
|  | 56 | paint.setAntiAlias(true); | 
|  | 57 |  | 
|  | 58 | canvas->save(); | 
|  | 59 | // clip always equals inner rect so we get the inside blur | 
|  | 60 | canvas->clipRect(inner); | 
|  | 61 | canvas->translate(translate, 0); | 
|  | 62 | canvas->drawPath(p, paint); | 
|  | 63 | canvas->restore(); | 
|  | 64 | } | 
|  | 65 | } | 
|  | 66 |  | 
|  | 67 | private: | 
|  | 68 | enum { | 
|  | 69 | W = 640, | 
|  | 70 | H = 480, | 
|  | 71 | }; | 
|  | 72 |  | 
| robertphillips@google.com | b706117 | 2013-09-06 14:16:12 +0000 | [diff] [blame] | 73 | SkLayerDrawLooper* createLooper(SkScalar xOff, SkScalar sigma) { | 
| commit-bot@chromium.org | 73cb153 | 2014-04-15 15:48:36 +0000 | [diff] [blame] | 74 | SkLayerDrawLooper::Builder looperBuilder; | 
| robertphillips@google.com | 1d2f631 | 2013-05-13 14:10:31 +0000 | [diff] [blame] | 75 |  | 
|  | 76 | //----------------------------------------------- | 
|  | 77 | SkLayerDrawLooper::LayerInfo info; | 
|  | 78 |  | 
| robertphillips@google.com | 1d2f631 | 2013-05-13 14:10:31 +0000 | [diff] [blame] | 79 | // TODO: add a color filter to better match what is seen in the wild | 
| skia.committer@gmail.com | 0431b87 | 2013-05-14 07:01:11 +0000 | [diff] [blame] | 80 | info.fPaintBits = /* SkLayerDrawLooper::kColorFilter_Bit |*/ | 
| robertphillips@google.com | 1d2f631 | 2013-05-13 14:10:31 +0000 | [diff] [blame] | 81 | SkLayerDrawLooper::kMaskFilter_Bit; | 
|  | 82 | info.fColorMode = SkXfermode::kDst_Mode; | 
|  | 83 | info.fOffset.set(xOff, 0); | 
|  | 84 | info.fPostTranslate = false; | 
|  | 85 |  | 
| commit-bot@chromium.org | 73cb153 | 2014-04-15 15:48:36 +0000 | [diff] [blame] | 86 | SkPaint* paint = looperBuilder.addLayer(info); | 
| robertphillips@google.com | 1d2f631 | 2013-05-13 14:10:31 +0000 | [diff] [blame] | 87 |  | 
| commit-bot@chromium.org | e396455 | 2014-04-28 16:25:35 +0000 | [diff] [blame] | 88 | SkMaskFilter* mf = SkBlurMaskFilter::Create(kNormal_SkBlurStyle, | 
| robertphillips@google.com | b706117 | 2013-09-06 14:16:12 +0000 | [diff] [blame] | 89 | sigma, | 
| robertphillips@google.com | 1d2f631 | 2013-05-13 14:10:31 +0000 | [diff] [blame] | 90 | SkBlurMaskFilter::kHighQuality_BlurFlag); | 
|  | 91 | paint->setMaskFilter(mf)->unref(); | 
|  | 92 |  | 
|  | 93 | //----------------------------------------------- | 
|  | 94 | info.fPaintBits = 0; | 
|  | 95 | info.fOffset.set(0, 0); | 
|  | 96 |  | 
| commit-bot@chromium.org | 73cb153 | 2014-04-15 15:48:36 +0000 | [diff] [blame] | 97 | paint = looperBuilder.addLayer(info); | 
|  | 98 | return looperBuilder.detachLooper(); | 
| robertphillips@google.com | 1d2f631 | 2013-05-13 14:10:31 +0000 | [diff] [blame] | 99 | } | 
|  | 100 |  | 
| tfarina | f168b86 | 2014-06-19 12:32:29 -0700 | [diff] [blame] | 101 | typedef Benchmark INHERITED; | 
| robertphillips@google.com | 1d2f631 | 2013-05-13 14:10:31 +0000 | [diff] [blame] | 102 | }; | 
|  | 103 |  | 
| mtklein@google.com | 410e6e8 | 2013-09-13 19:52:27 +0000 | [diff] [blame] | 104 | DEF_BENCH( return SkNEW_ARGS(RectoriBench, ()); ) |