11d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com/*
21d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com * Copyright 2013 Google Inc.
31d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com *
41d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com * Use of this source code is governed by a BSD-style license that can be
51d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com * found in the LICENSE file.
61d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com */
71d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
8f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina#include "Benchmark.h"
9f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina#include "SkBlurMaskFilter.h"
101d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com#include "SkCanvas.h"
11f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina#include "SkLayerDrawLooper.h"
121d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com#include "SkPaint.h"
13d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include "SkPath.h"
141d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com#include "SkRandom.h"
151d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
161d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com// This bench replicates a problematic use case of a draw looper used
171d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com// to create an inner blurred rect
18f168b86d7fafc5c20c87bebc6fd393cb17e120catfarinaclass RectoriBench : public Benchmark {
191d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.compublic:
20410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.com    RectoriBench() {}
211d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
221d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.comprotected:
231d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
2436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    const char* onGetName() override {
251d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        return "rectori";
261d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com    }
271d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
28a1ebeb25e9acfcd801e089e063311d716b83b8a5mtklein    void onDraw(int loops, SkCanvas* canvas) override {
29e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org        SkRandom Random;
301d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
313361471a3504ecd0351ff70f4c42d8d6fee963d4commit-bot@chromium.org        for (int i = 0; i < loops; i++) {
32b7061176c7f414616fe2e79e832b3e0abe326af6robertphillips@google.com            SkScalar blurSigma = Random.nextRangeScalar(1.5f, 25.0f);
33b7061176c7f414616fe2e79e832b3e0abe326af6robertphillips@google.com            SkScalar size = Random.nextRangeScalar(20*blurSigma, 50*blurSigma);
341d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
351d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            SkScalar x = Random.nextRangeScalar(0.0f, W - size);
361d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            SkScalar y = Random.nextRangeScalar(0.0f, H - size);
371d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
381d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            SkRect inner = { x, y, x + size, y + size };
391d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
401d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            SkRect outer(inner);
411d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            // outer is always outset either 2x or 4x the blur radius (we go with 2x)
42b7061176c7f414616fe2e79e832b3e0abe326af6robertphillips@google.com            outer.outset(2*blurSigma, 2*blurSigma);
431d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
441d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            SkPath p;
451d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
461d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            p.addRect(outer);
471d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            p.addRect(inner);
481d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            p.setFillType(SkPath::kEvenOdd_FillType);
491d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
501d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            // This will be used to translate the normal draw outside the
511d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            // clip rect and translate the blurred version back inside
521d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            SkScalar translate = 2.0f * size;
531d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
541d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            SkPaint paint;
557b380d0d0e91ae6967c52bfa14853a77b9551de4reed            paint.setLooper(this->createLooper(-translate, blurSigma));
561d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            paint.setColor(0xff000000 | Random.nextU());
571d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            paint.setAntiAlias(true);
581d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
591d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            canvas->save();
601d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            // clip always equals inner rect so we get the inside blur
611d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            canvas->clipRect(inner);
621d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            canvas->translate(translate, 0);
631d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            canvas->drawPath(p, paint);
641d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            canvas->restore();
651d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        }
661d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com    }
671d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
681d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.comprivate:
691d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com    enum {
701d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        W = 640,
711d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        H = 480,
721d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com    };
731d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
747b380d0d0e91ae6967c52bfa14853a77b9551de4reed    sk_sp<SkDrawLooper> createLooper(SkScalar xOff, SkScalar sigma) {
7573cb15351f33459e0c861a96135c634dec77ef9dcommit-bot@chromium.org        SkLayerDrawLooper::Builder looperBuilder;
761d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
771d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        //-----------------------------------------------
781d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        SkLayerDrawLooper::LayerInfo info;
791d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
801d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        // TODO: add a color filter to better match what is seen in the wild
810431b87a98f2f3721d8e5dba04bf81a2fd8b5d1cskia.committer@gmail.com        info.fPaintBits = /* SkLayerDrawLooper::kColorFilter_Bit |*/
821d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com                          SkLayerDrawLooper::kMaskFilter_Bit;
83faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed        info.fColorMode = SkBlendMode::kDst;
841d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        info.fOffset.set(xOff, 0);
851d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        info.fPostTranslate = false;
861d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
8773cb15351f33459e0c861a96135c634dec77ef9dcommit-bot@chromium.org        SkPaint* paint = looperBuilder.addLayer(info);
881d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
89efdfd51b68a300d5c6e28743fe0344ca05d1cec9reed        paint->setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle, sigma,
90efdfd51b68a300d5c6e28743fe0344ca05d1cec9reed                                                    SkBlurMaskFilter::kHighQuality_BlurFlag));
911d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
921d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        //-----------------------------------------------
931d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        info.fPaintBits = 0;
941d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        info.fOffset.set(0, 0);
951d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
9673cb15351f33459e0c861a96135c634dec77ef9dcommit-bot@chromium.org        paint = looperBuilder.addLayer(info);
977b380d0d0e91ae6967c52bfa14853a77b9551de4reed        return looperBuilder.detach();
981d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com    }
991d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
100f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina    typedef Benchmark INHERITED;
1011d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com};
1021d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
103385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanaryDEF_BENCH(return new RectoriBench();)
104