1580a17241c51712f26441c6551c773e3769738e9sugoi@google.com/*
2580a17241c51712f26441c6551c773e3769738e9sugoi@google.com * Copyright 2013 Google Inc.
3580a17241c51712f26441c6551c773e3769738e9sugoi@google.com *
4580a17241c51712f26441c6551c773e3769738e9sugoi@google.com * Use of this source code is governed by a BSD-style license that can be
5580a17241c51712f26441c6551c773e3769738e9sugoi@google.com * found in the LICENSE file.
6580a17241c51712f26441c6551c773e3769738e9sugoi@google.com */
7f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina#include "Benchmark.h"
81f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com#include "SkBitmapDevice.h"
9580a17241c51712f26441c6551c773e3769738e9sugoi@google.com#include "SkBitmapSource.h"
10580a17241c51712f26441c6551c773e3769738e9sugoi@google.com#include "SkCanvas.h"
11580a17241c51712f26441c6551c773e3769738e9sugoi@google.com#include "SkDisplacementMapEffect.h"
12580a17241c51712f26441c6551c773e3769738e9sugoi@google.com
13ca425d9fd9a35e2edd6ebdeb97f0cb88b341ef5bsugoi@google.com#define FILTER_WIDTH_SMALL  32
14ca425d9fd9a35e2edd6ebdeb97f0cb88b341ef5bsugoi@google.com#define FILTER_HEIGHT_SMALL 32
15ca425d9fd9a35e2edd6ebdeb97f0cb88b341ef5bsugoi@google.com#define FILTER_WIDTH_LARGE  256
16ca425d9fd9a35e2edd6ebdeb97f0cb88b341ef5bsugoi@google.com#define FILTER_HEIGHT_LARGE 256
17580a17241c51712f26441c6551c773e3769738e9sugoi@google.com
18f168b86d7fafc5c20c87bebc6fd393cb17e120catfarinaclass DisplacementBaseBench : public Benchmark {
19580a17241c51712f26441c6551c773e3769738e9sugoi@google.compublic:
20410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.com    DisplacementBaseBench(bool small) :
21410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.com        fInitialized(false), fIsSmall(small) {
22580a17241c51712f26441c6551c773e3769738e9sugoi@google.com    }
23580a17241c51712f26441c6551c773e3769738e9sugoi@google.com
24580a17241c51712f26441c6551c773e3769738e9sugoi@google.comprotected:
25580a17241c51712f26441c6551c773e3769738e9sugoi@google.com    virtual void onPreDraw() SK_OVERRIDE {
26580a17241c51712f26441c6551c773e3769738e9sugoi@google.com        if (!fInitialized) {
2726e30c5223c627d1a2fed0ac8010d442bc546b8arobertphillips@google.com            this->makeBitmap();
2826e30c5223c627d1a2fed0ac8010d442bc546b8arobertphillips@google.com            this->makeCheckerboard();
29580a17241c51712f26441c6551c773e3769738e9sugoi@google.com            fInitialized = true;
30580a17241c51712f26441c6551c773e3769738e9sugoi@google.com        }
31580a17241c51712f26441c6551c773e3769738e9sugoi@google.com    }
32580a17241c51712f26441c6551c773e3769738e9sugoi@google.com
3326e30c5223c627d1a2fed0ac8010d442bc546b8arobertphillips@google.com    void makeBitmap() {
3426e30c5223c627d1a2fed0ac8010d442bc546b8arobertphillips@google.com        const int w = this->isSmall() ? FILTER_WIDTH_SMALL : FILTER_WIDTH_LARGE;
3526e30c5223c627d1a2fed0ac8010d442bc546b8arobertphillips@google.com        const int h = this->isSmall() ? FILTER_HEIGHT_LARGE : FILTER_HEIGHT_LARGE;
366c22573edb234ad14df947278cfed010669a39a7reed        fBitmap.allocN32Pixels(w, h);
376c22573edb234ad14df947278cfed010669a39a7reed        SkCanvas canvas(fBitmap);
38580a17241c51712f26441c6551c773e3769738e9sugoi@google.com        canvas.clear(0x00000000);
39580a17241c51712f26441c6551c773e3769738e9sugoi@google.com        SkPaint paint;
40580a17241c51712f26441c6551c773e3769738e9sugoi@google.com        paint.setAntiAlias(true);
41580a17241c51712f26441c6551c773e3769738e9sugoi@google.com        paint.setColor(0xFF884422);
42580a17241c51712f26441c6551c773e3769738e9sugoi@google.com        paint.setTextSize(SkIntToScalar(96));
43580a17241c51712f26441c6551c773e3769738e9sugoi@google.com        const char* str = "g";
44580a17241c51712f26441c6551c773e3769738e9sugoi@google.com        canvas.drawText(str, strlen(str), SkIntToScalar(15), SkIntToScalar(55), paint);
45580a17241c51712f26441c6551c773e3769738e9sugoi@google.com    }
46580a17241c51712f26441c6551c773e3769738e9sugoi@google.com
4726e30c5223c627d1a2fed0ac8010d442bc546b8arobertphillips@google.com    void makeCheckerboard() {
4826e30c5223c627d1a2fed0ac8010d442bc546b8arobertphillips@google.com        const int w = this->isSmall() ? FILTER_WIDTH_SMALL : FILTER_WIDTH_LARGE;
4926e30c5223c627d1a2fed0ac8010d442bc546b8arobertphillips@google.com        const int h = this->isSmall() ? FILTER_HEIGHT_LARGE : FILTER_HEIGHT_LARGE;
506c22573edb234ad14df947278cfed010669a39a7reed        fCheckerboard.allocN32Pixels(w, h);
516c22573edb234ad14df947278cfed010669a39a7reed        SkCanvas canvas(fCheckerboard);
52580a17241c51712f26441c6551c773e3769738e9sugoi@google.com        canvas.clear(0x00000000);
53580a17241c51712f26441c6551c773e3769738e9sugoi@google.com        SkPaint darkPaint;
54580a17241c51712f26441c6551c773e3769738e9sugoi@google.com        darkPaint.setColor(0xFF804020);
55580a17241c51712f26441c6551c773e3769738e9sugoi@google.com        SkPaint lightPaint;
56580a17241c51712f26441c6551c773e3769738e9sugoi@google.com        lightPaint.setColor(0xFF244484);
57580a17241c51712f26441c6551c773e3769738e9sugoi@google.com        for (int y = 0; y < h; y += 16) {
58580a17241c51712f26441c6551c773e3769738e9sugoi@google.com            for (int x = 0; x < w; x += 16) {
59580a17241c51712f26441c6551c773e3769738e9sugoi@google.com                canvas.save();
60580a17241c51712f26441c6551c773e3769738e9sugoi@google.com                canvas.translate(SkIntToScalar(x), SkIntToScalar(y));
61580a17241c51712f26441c6551c773e3769738e9sugoi@google.com                canvas.drawRect(SkRect::MakeXYWH(0, 0, 8, 8), darkPaint);
62580a17241c51712f26441c6551c773e3769738e9sugoi@google.com                canvas.drawRect(SkRect::MakeXYWH(8, 0, 8, 8), lightPaint);
63580a17241c51712f26441c6551c773e3769738e9sugoi@google.com                canvas.drawRect(SkRect::MakeXYWH(0, 8, 8, 8), lightPaint);
64580a17241c51712f26441c6551c773e3769738e9sugoi@google.com                canvas.drawRect(SkRect::MakeXYWH(8, 8, 8, 8), darkPaint);
65580a17241c51712f26441c6551c773e3769738e9sugoi@google.com                canvas.restore();
66580a17241c51712f26441c6551c773e3769738e9sugoi@google.com            }
67580a17241c51712f26441c6551c773e3769738e9sugoi@google.com        }
68580a17241c51712f26441c6551c773e3769738e9sugoi@google.com    }
69580a17241c51712f26441c6551c773e3769738e9sugoi@google.com
70580a17241c51712f26441c6551c773e3769738e9sugoi@google.com    void drawClippedBitmap(SkCanvas* canvas, int x, int y, const SkPaint& paint) {
71580a17241c51712f26441c6551c773e3769738e9sugoi@google.com        canvas->save();
72580a17241c51712f26441c6551c773e3769738e9sugoi@google.com        canvas->clipRect(SkRect::MakeXYWH(SkIntToScalar(x), SkIntToScalar(y),
7370402c3168485f86d0445d1d9d7a41739c651e67skia.committer@gmail.com                                          SkIntToScalar(fBitmap.width()),
7426e30c5223c627d1a2fed0ac8010d442bc546b8arobertphillips@google.com                                          SkIntToScalar(fBitmap.height())));
75580a17241c51712f26441c6551c773e3769738e9sugoi@google.com        canvas->drawBitmap(fBitmap, SkIntToScalar(x), SkIntToScalar(y), &paint);
76580a17241c51712f26441c6551c773e3769738e9sugoi@google.com        canvas->restore();
77580a17241c51712f26441c6551c773e3769738e9sugoi@google.com    }
78580a17241c51712f26441c6551c773e3769738e9sugoi@google.com
79580a17241c51712f26441c6551c773e3769738e9sugoi@google.com    inline bool isSmall() const { return fIsSmall; }
80580a17241c51712f26441c6551c773e3769738e9sugoi@google.com
81580a17241c51712f26441c6551c773e3769738e9sugoi@google.com    SkBitmap fBitmap, fCheckerboard;
82580a17241c51712f26441c6551c773e3769738e9sugoi@google.comprivate:
83580a17241c51712f26441c6551c773e3769738e9sugoi@google.com    bool fInitialized;
84580a17241c51712f26441c6551c773e3769738e9sugoi@google.com    bool fIsSmall;
85f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina    typedef Benchmark INHERITED;
86580a17241c51712f26441c6551c773e3769738e9sugoi@google.com};
87580a17241c51712f26441c6551c773e3769738e9sugoi@google.com
88580a17241c51712f26441c6551c773e3769738e9sugoi@google.comclass DisplacementZeroBench : public DisplacementBaseBench {
89580a17241c51712f26441c6551c773e3769738e9sugoi@google.compublic:
90410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.com    DisplacementZeroBench(bool small) : INHERITED(small) {
91580a17241c51712f26441c6551c773e3769738e9sugoi@google.com    }
92580a17241c51712f26441c6551c773e3769738e9sugoi@google.com
93580a17241c51712f26441c6551c773e3769738e9sugoi@google.comprotected:
94580a17241c51712f26441c6551c773e3769738e9sugoi@google.com    virtual const char* onGetName() SK_OVERRIDE {
9526e30c5223c627d1a2fed0ac8010d442bc546b8arobertphillips@google.com        return this->isSmall() ? "displacement_zero_small" : "displacement_zero_large";
96580a17241c51712f26441c6551c773e3769738e9sugoi@google.com    }
97580a17241c51712f26441c6551c773e3769738e9sugoi@google.com
983361471a3504ecd0351ff70f4c42d8d6fee963d4commit-bot@chromium.org    virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
99580a17241c51712f26441c6551c773e3769738e9sugoi@google.com        SkPaint paint;
100cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org        SkAutoTUnref<SkImageFilter> displ(SkBitmapSource::Create(fCheckerboard));
101580a17241c51712f26441c6551c773e3769738e9sugoi@google.com        // No displacement effect
102cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org        paint.setImageFilter(SkDisplacementMapEffect::Create(
103cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org            SkDisplacementMapEffect::kR_ChannelSelectorType,
104cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org            SkDisplacementMapEffect::kG_ChannelSelectorType, 0.0f, displ))->unref();
105c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
1063361471a3504ecd0351ff70f4c42d8d6fee963d4commit-bot@chromium.org        for (int i = 0; i < loops; i++) {
10726e30c5223c627d1a2fed0ac8010d442bc546b8arobertphillips@google.com            this->drawClippedBitmap(canvas, 0, 0, paint);
108c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        }
109580a17241c51712f26441c6551c773e3769738e9sugoi@google.com    }
110580a17241c51712f26441c6551c773e3769738e9sugoi@google.com
111580a17241c51712f26441c6551c773e3769738e9sugoi@google.comprivate:
112580a17241c51712f26441c6551c773e3769738e9sugoi@google.com    typedef DisplacementBaseBench INHERITED;
113580a17241c51712f26441c6551c773e3769738e9sugoi@google.com};
114580a17241c51712f26441c6551c773e3769738e9sugoi@google.com
115580a17241c51712f26441c6551c773e3769738e9sugoi@google.comclass DisplacementAlphaBench : public DisplacementBaseBench {
116580a17241c51712f26441c6551c773e3769738e9sugoi@google.compublic:
117410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.com    DisplacementAlphaBench(bool small) : INHERITED(small) {
118580a17241c51712f26441c6551c773e3769738e9sugoi@google.com    }
119580a17241c51712f26441c6551c773e3769738e9sugoi@google.com
120580a17241c51712f26441c6551c773e3769738e9sugoi@google.comprotected:
121580a17241c51712f26441c6551c773e3769738e9sugoi@google.com    virtual const char* onGetName() SK_OVERRIDE {
122580a17241c51712f26441c6551c773e3769738e9sugoi@google.com        return isSmall() ? "displacement_alpha_small" : "displacement_alpha_large";
123580a17241c51712f26441c6551c773e3769738e9sugoi@google.com    }
124580a17241c51712f26441c6551c773e3769738e9sugoi@google.com
1253361471a3504ecd0351ff70f4c42d8d6fee963d4commit-bot@chromium.org    virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
126580a17241c51712f26441c6551c773e3769738e9sugoi@google.com        SkPaint paint;
127cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org        SkAutoTUnref<SkImageFilter> displ(SkBitmapSource::Create(fCheckerboard));
128580a17241c51712f26441c6551c773e3769738e9sugoi@google.com        // Displacement, with 1 alpha component (which isn't pre-multiplied)
129cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org        paint.setImageFilter(SkDisplacementMapEffect::Create(
130cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org            SkDisplacementMapEffect::kB_ChannelSelectorType,
131cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org            SkDisplacementMapEffect::kA_ChannelSelectorType, 16.0f, displ))->unref();
1323361471a3504ecd0351ff70f4c42d8d6fee963d4commit-bot@chromium.org        for (int i = 0; i < loops; i++) {
133c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            drawClippedBitmap(canvas, 100, 0, paint);
134c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        }
135580a17241c51712f26441c6551c773e3769738e9sugoi@google.com    }
136580a17241c51712f26441c6551c773e3769738e9sugoi@google.com
137580a17241c51712f26441c6551c773e3769738e9sugoi@google.comprivate:
138580a17241c51712f26441c6551c773e3769738e9sugoi@google.com    typedef DisplacementBaseBench INHERITED;
139580a17241c51712f26441c6551c773e3769738e9sugoi@google.com};
140580a17241c51712f26441c6551c773e3769738e9sugoi@google.com
141580a17241c51712f26441c6551c773e3769738e9sugoi@google.comclass DisplacementFullBench : public DisplacementBaseBench {
142580a17241c51712f26441c6551c773e3769738e9sugoi@google.compublic:
143410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.com    DisplacementFullBench(bool small) : INHERITED(small) {
144580a17241c51712f26441c6551c773e3769738e9sugoi@google.com    }
145580a17241c51712f26441c6551c773e3769738e9sugoi@google.com
146580a17241c51712f26441c6551c773e3769738e9sugoi@google.comprotected:
147580a17241c51712f26441c6551c773e3769738e9sugoi@google.com    virtual const char* onGetName() SK_OVERRIDE {
148580a17241c51712f26441c6551c773e3769738e9sugoi@google.com        return isSmall() ? "displacement_full_small" : "displacement_full_large";
149580a17241c51712f26441c6551c773e3769738e9sugoi@google.com    }
150580a17241c51712f26441c6551c773e3769738e9sugoi@google.com
1513361471a3504ecd0351ff70f4c42d8d6fee963d4commit-bot@chromium.org    virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
152580a17241c51712f26441c6551c773e3769738e9sugoi@google.com        SkPaint paint;
153cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org        SkAutoTUnref<SkImageFilter> displ(SkBitmapSource::Create(fCheckerboard));
154580a17241c51712f26441c6551c773e3769738e9sugoi@google.com        // Displacement, with 2 non-alpha components
155cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org        paint.setImageFilter(SkDisplacementMapEffect::Create(
156cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org            SkDisplacementMapEffect::kR_ChannelSelectorType,
157cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org            SkDisplacementMapEffect::kB_ChannelSelectorType, 32.0f, displ))->unref();
1583361471a3504ecd0351ff70f4c42d8d6fee963d4commit-bot@chromium.org        for (int i = 0; i < loops; ++i) {
15926e30c5223c627d1a2fed0ac8010d442bc546b8arobertphillips@google.com            this->drawClippedBitmap(canvas, 200, 0, paint);
160c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        }
161580a17241c51712f26441c6551c773e3769738e9sugoi@google.com    }
162580a17241c51712f26441c6551c773e3769738e9sugoi@google.com
163580a17241c51712f26441c6551c773e3769738e9sugoi@google.comprivate:
164580a17241c51712f26441c6551c773e3769738e9sugoi@google.com    typedef DisplacementBaseBench INHERITED;
165580a17241c51712f26441c6551c773e3769738e9sugoi@google.com};
166580a17241c51712f26441c6551c773e3769738e9sugoi@google.com
167580a17241c51712f26441c6551c773e3769738e9sugoi@google.com///////////////////////////////////////////////////////////////////////////////
168580a17241c51712f26441c6551c773e3769738e9sugoi@google.com
169410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return new DisplacementZeroBench(true); )
170410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return new DisplacementAlphaBench(true); )
171410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return new DisplacementFullBench(true); )
172410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return new DisplacementZeroBench(false); )
173410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return new DisplacementAlphaBench(false); )
174410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return new DisplacementFullBench(false); )
175