10d64356efd8a3ca40d39729f62e0fa9a5bc3a365senorblanco@chromium.org/*
20d64356efd8a3ca40d39729f62e0fa9a5bc3a365senorblanco@chromium.org * Copyright 2014 Google Inc.
30d64356efd8a3ca40d39729f62e0fa9a5bc3a365senorblanco@chromium.org *
40d64356efd8a3ca40d39729f62e0fa9a5bc3a365senorblanco@chromium.org * Use of this source code is governed by a BSD-style license that can be
50d64356efd8a3ca40d39729f62e0fa9a5bc3a365senorblanco@chromium.org * found in the LICENSE file.
60d64356efd8a3ca40d39729f62e0fa9a5bc3a365senorblanco@chromium.org */
70d64356efd8a3ca40d39729f62e0fa9a5bc3a365senorblanco@chromium.org
8f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina#include "Benchmark.h"
904a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman#include "Resources.h"
100d64356efd8a3ca40d39729f62e0fa9a5bc3a365senorblanco@chromium.org#include "SkBlurImageFilter.h"
117b87ee7a1c43ad9d4d20955cc25f3c31af161bb5senorblanco#include "SkDisplacementMapEffect.h"
120d64356efd8a3ca40d39729f62e0fa9a5bc3a365senorblanco@chromium.org#include "SkCanvas.h"
13ab244f045a0740fa6106ed21a4e5824cd09f84f3Florin Malita#include "SkImage.h"
14f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina#include "SkMergeImageFilter.h"
150d64356efd8a3ca40d39729f62e0fa9a5bc3a365senorblanco@chromium.org
160d64356efd8a3ca40d39729f62e0fa9a5bc3a365senorblanco@chromium.org
170d64356efd8a3ca40d39729f62e0fa9a5bc3a365senorblanco@chromium.org// Exercise a blur filter connected to 5 inputs of the same merge filter.
180d64356efd8a3ca40d39729f62e0fa9a5bc3a365senorblanco@chromium.org// This bench shows an improvement in performance once cacheing of re-used
190d64356efd8a3ca40d39729f62e0fa9a5bc3a365senorblanco@chromium.org// nodes is implemented, since the DAG is no longer flattened to a tree.
20f168b86d7fafc5c20c87bebc6fd393cb17e120catfarinaclass ImageFilterDAGBench : public Benchmark {
210d64356efd8a3ca40d39729f62e0fa9a5bc3a365senorblanco@chromium.orgpublic:
22bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein    ImageFilterDAGBench() {}
230d64356efd8a3ca40d39729f62e0fa9a5bc3a365senorblanco@chromium.org
240d64356efd8a3ca40d39729f62e0fa9a5bc3a365senorblanco@chromium.orgprotected:
2536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    const char* onGetName() override {
260d64356efd8a3ca40d39729f62e0fa9a5bc3a365senorblanco@chromium.org        return "image_filter_dag";
270d64356efd8a3ca40d39729f62e0fa9a5bc3a365senorblanco@chromium.org    }
280d64356efd8a3ca40d39729f62e0fa9a5bc3a365senorblanco@chromium.org
29a1ebeb25e9acfcd801e089e063311d716b83b8a5mtklein    void onDraw(int loops, SkCanvas* canvas) override {
302238c9dbca4b791edc512957728a18ce14d55912robertphillips        const SkRect rect = SkRect::Make(SkIRect::MakeWH(400, 400));
312238c9dbca4b791edc512957728a18ce14d55912robertphillips
32bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein        for (int j = 0; j < loops; j++) {
336e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips            sk_sp<SkImageFilter> blur(SkBlurImageFilter::Make(20.0f, 20.0f, nullptr));
342238c9dbca4b791edc512957728a18ce14d55912robertphillips            sk_sp<SkImageFilter> inputs[kNumInputs];
35bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein            for (int i = 0; i < kNumInputs; ++i) {
362238c9dbca4b791edc512957728a18ce14d55912robertphillips                inputs[i] = blur;
37bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein            }
38bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein            SkPaint paint;
390bdaf05fc17ebe5d4ad01d70c80df2425e83c737Mike Reed            paint.setImageFilter(SkMergeImageFilter::Make(inputs, kNumInputs));
40bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein            canvas->drawRect(rect, paint);
410d64356efd8a3ca40d39729f62e0fa9a5bc3a365senorblanco@chromium.org        }
420d64356efd8a3ca40d39729f62e0fa9a5bc3a365senorblanco@chromium.org    }
430d64356efd8a3ca40d39729f62e0fa9a5bc3a365senorblanco@chromium.org
440d64356efd8a3ca40d39729f62e0fa9a5bc3a365senorblanco@chromium.orgprivate:
452238c9dbca4b791edc512957728a18ce14d55912robertphillips    static const int kNumInputs = 5;
462238c9dbca4b791edc512957728a18ce14d55912robertphillips
47f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina    typedef Benchmark INHERITED;
480d64356efd8a3ca40d39729f62e0fa9a5bc3a365senorblanco@chromium.org};
490d64356efd8a3ca40d39729f62e0fa9a5bc3a365senorblanco@chromium.org
5004a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosmanclass ImageMakeWithFilterDAGBench : public Benchmark {
5104a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosmanpublic:
5204a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman    ImageMakeWithFilterDAGBench() {}
5304a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman
5404a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosmanprotected:
5504a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman    const char* onGetName() override {
5604a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman        return "image_make_with_filter_dag";
5704a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman    }
5804a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman
5904a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman    void onDelayedSetup() override {
6004a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman        fImage = GetResourceAsImage("mandrill_512.png");
6104a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman    }
6204a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman
6304a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman    void onDraw(int loops, SkCanvas* canvas) override {
6404a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman        SkIRect subset = SkIRect::MakeSize(fImage->dimensions());
6504a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman        SkIPoint offset = SkIPoint::Make(0, 0);
6604a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman        SkIRect discardSubset;
6704a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman        sk_sp<SkImage> image = fImage;
6804a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman
6904a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman        for (int j = 0; j < loops; j++) {
7004a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman            sk_sp<SkImageFilter> blur(SkBlurImageFilter::Make(20.0f, 20.0f, nullptr));
7104a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman            sk_sp<SkImageFilter> inputs[kNumInputs];
7204a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman            for (int i = 0; i < kNumInputs; ++i) {
7304a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman                inputs[i] = blur;
7404a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman            }
750bdaf05fc17ebe5d4ad01d70c80df2425e83c737Mike Reed            sk_sp<SkImageFilter> mergeFilter = SkMergeImageFilter::Make(inputs, kNumInputs);
7604a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman            image = image->makeWithFilter(mergeFilter.get(), subset, subset, &discardSubset,
7704a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman                                          &offset);
7804a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman            SkASSERT(image && image->dimensions() == fImage->dimensions());
7904a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman        }
8004a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman    }
8104a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman
8204a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosmanprivate:
8304a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman    static const int kNumInputs = 5;
8404a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman    sk_sp<SkImage> fImage;
8504a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman
8604a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman    typedef Benchmark INHERITED;
8704a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman};
8804a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosman
897b87ee7a1c43ad9d4d20955cc25f3c31af161bb5senorblanco// Exercise a blur filter connected to both inputs of an SkDisplacementMapEffect.
907b87ee7a1c43ad9d4d20955cc25f3c31af161bb5senorblanco
917b87ee7a1c43ad9d4d20955cc25f3c31af161bb5senorblancoclass ImageFilterDisplacedBlur : public Benchmark {
927b87ee7a1c43ad9d4d20955cc25f3c31af161bb5senorblancopublic:
937b87ee7a1c43ad9d4d20955cc25f3c31af161bb5senorblanco    ImageFilterDisplacedBlur() {}
947b87ee7a1c43ad9d4d20955cc25f3c31af161bb5senorblanco
957b87ee7a1c43ad9d4d20955cc25f3c31af161bb5senorblancoprotected:
967b87ee7a1c43ad9d4d20955cc25f3c31af161bb5senorblanco    const char* onGetName() override {
977b87ee7a1c43ad9d4d20955cc25f3c31af161bb5senorblanco        return "image_filter_displaced_blur";
987b87ee7a1c43ad9d4d20955cc25f3c31af161bb5senorblanco    }
997b87ee7a1c43ad9d4d20955cc25f3c31af161bb5senorblanco
1007b87ee7a1c43ad9d4d20955cc25f3c31af161bb5senorblanco    void onDraw(int loops, SkCanvas* canvas) override {
1017b87ee7a1c43ad9d4d20955cc25f3c31af161bb5senorblanco        for (int j = 0; j < loops; j++) {
1026e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips            sk_sp<SkImageFilter> blur(SkBlurImageFilter::Make(4.0f, 4.0f, nullptr));
1036e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips            auto xSelector = SkDisplacementMapEffect::kR_ChannelSelectorType;
1046e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips            auto ySelector = SkDisplacementMapEffect::kB_ChannelSelectorType;
1057b87ee7a1c43ad9d4d20955cc25f3c31af161bb5senorblanco            SkScalar scale = 2;
106bfe11fc9a6e660f83a454b6a5f5945089a4800f3robertphillips
1077b87ee7a1c43ad9d4d20955cc25f3c31af161bb5senorblanco            SkPaint paint;
108bfe11fc9a6e660f83a454b6a5f5945089a4800f3robertphillips            paint.setImageFilter(SkDisplacementMapEffect::Make(xSelector, ySelector, scale,
109bfe11fc9a6e660f83a454b6a5f5945089a4800f3robertphillips                                                               blur, blur));
110bfe11fc9a6e660f83a454b6a5f5945089a4800f3robertphillips
1117b87ee7a1c43ad9d4d20955cc25f3c31af161bb5senorblanco            SkRect rect = SkRect::Make(SkIRect::MakeWH(400, 400));
1127b87ee7a1c43ad9d4d20955cc25f3c31af161bb5senorblanco            canvas->drawRect(rect, paint);
1137b87ee7a1c43ad9d4d20955cc25f3c31af161bb5senorblanco        }
1147b87ee7a1c43ad9d4d20955cc25f3c31af161bb5senorblanco    }
1157b87ee7a1c43ad9d4d20955cc25f3c31af161bb5senorblanco
1167b87ee7a1c43ad9d4d20955cc25f3c31af161bb5senorblancoprivate:
1177b87ee7a1c43ad9d4d20955cc25f3c31af161bb5senorblanco    typedef Benchmark INHERITED;
1187b87ee7a1c43ad9d4d20955cc25f3c31af161bb5senorblanco};
1197b87ee7a1c43ad9d4d20955cc25f3c31af161bb5senorblanco
1200d64356efd8a3ca40d39729f62e0fa9a5bc3a365senorblanco@chromium.orgDEF_BENCH(return new ImageFilterDAGBench;)
12104a44d0fd45f5596c716e99e7a3bbcc03db0e05abrianosmanDEF_BENCH(return new ImageMakeWithFilterDAGBench;)
1227b87ee7a1c43ad9d4d20955cc25f3c31af161bb5senorblancoDEF_BENCH(return new ImageFilterDisplacedBlur;)
123