1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
76c22573edb234ad14df947278cfed010669a39a7reed
8f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina#include "Benchmark.h"
9f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com#include "SkBitmap.h"
10f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com#include "SkCanvas.h"
11f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com#include "SkColorPriv.h"
12f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina#include "SkPaint.h"
13f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com#include "SkRandom.h"
14f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com#include "SkString.h"
156c22573edb234ad14df947278cfed010669a39a7reed#include "sk_tool_utils.h"
16f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com
17f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.comstatic int conv6ToByte(int x) {
18f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    return x * 0xFF / 5;
19f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com}
20f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com
21f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.comstatic int convByteTo6(int x) {
22f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    return x * 5 / 255;
23f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com}
24f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com
25f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.comstatic uint8_t compute666Index(SkPMColor c) {
26f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    int r = SkGetPackedR32(c);
27f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    int g = SkGetPackedG32(c);
28f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    int b = SkGetPackedB32(c);
29fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
30f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    return convByteTo6(r) * 36 + convByteTo6(g) * 6 + convByteTo6(b);
31f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com}
32f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com
336c22573edb234ad14df947278cfed010669a39a7reedstatic void convertToIndex666(const SkBitmap& src, SkBitmap* dst, SkAlphaType aType) {
340a6151d66cc32d91eca037c91e557158cf8a2be2reed@google.com    SkPMColor storage[216];
350a6151d66cc32d91eca037c91e557158cf8a2be2reed@google.com    SkPMColor* colors = storage;
36f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    // rrr ggg bbb
37f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    for (int r = 0; r < 6; r++) {
38f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        int rr = conv6ToByte(r);
39f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        for (int g = 0; g < 6; g++) {
40f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            int gg = conv6ToByte(g);
41f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            for (int b = 0; b < 6; b++) {
42f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com                int bb = conv6ToByte(b);
43f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com                *colors++ = SkPreMultiplyARGB(0xFF, rr, gg, bb);
44f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            }
45f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        }
46f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    }
47c5e15a1afab2621e860a251c3fcf5917867ad49freed    SkColorTable* ctable = new SkColorTable(storage, 216);
486c22573edb234ad14df947278cfed010669a39a7reed    dst->allocPixels(SkImageInfo::Make(src.width(), src.height(), kIndex_8_SkColorType, aType),
492880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                     nullptr, ctable);
50f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    ctable->unref();
51fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
52f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    SkAutoLockPixels alps(src);
53f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    SkAutoLockPixels alpd(*dst);
54f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com
55f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    for (int y = 0; y < src.height(); y++) {
56f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        const SkPMColor* srcP = src.getAddr32(0, y);
57f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        uint8_t* dstP = dst->getAddr8(0, y);
58f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        for (int x = src.width() - 1; x >= 0; --x) {
59f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            *dstP++ = compute666Index(*srcP++);
60f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        }
61f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    }
62f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com}
63f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com
64f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com/*  Variants for bitmaps
65fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
66f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    - src depth (32 w+w/o alpha), 565, 4444, index, a8
67f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    - paint options: filtering, dither, alpha
68f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    - matrix options: translate, scale, rotate, persp
69f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    - tiling: none, repeat, mirror, clamp
70fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
71f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com */
72f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com
73f168b86d7fafc5c20c87bebc6fd393cb17e120catfarinaclass BitmapBench : public Benchmark {
746c22573edb234ad14df947278cfed010669a39a7reed    const SkColorType   fColorType;
756c22573edb234ad14df947278cfed010669a39a7reed    const SkAlphaType   fAlphaType;
766c22573edb234ad14df947278cfed010669a39a7reed    const bool          fForceUpdate; //bitmap marked as dirty before each draw. forces bitmap to be updated on device cache
776c22573edb234ad14df947278cfed010669a39a7reed    const bool          fIsVolatile;
7814e4d392d4ffa50c0ddf359a426668d1718d7f92mtklein    const bool          fDoScale;
796c22573edb234ad14df947278cfed010669a39a7reed
806c22573edb234ad14df947278cfed010669a39a7reed    SkBitmap            fBitmap;
816c22573edb234ad14df947278cfed010669a39a7reed    SkPaint             fPaint;
826c22573edb234ad14df947278cfed010669a39a7reed    SkString            fName;
836c22573edb234ad14df947278cfed010669a39a7reed
84c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com    enum { W = 128 };
85c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com    enum { H = 128 };
86f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.compublic:
8714e4d392d4ffa50c0ddf359a426668d1718d7f92mtklein    BitmapBench(SkColorType ct, SkAlphaType at, bool forceUpdate, bool isVolatile, bool doScale)
886c22573edb234ad14df947278cfed010669a39a7reed        : fColorType(ct)
896c22573edb234ad14df947278cfed010669a39a7reed        , fAlphaType(at)
90c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        , fForceUpdate(forceUpdate)
916c22573edb234ad14df947278cfed010669a39a7reed        , fIsVolatile(isVolatile)
9214e4d392d4ffa50c0ddf359a426668d1718d7f92mtklein        , fDoScale(doScale)
936c22573edb234ad14df947278cfed010669a39a7reed    {}
94f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com
95f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.comprotected:
96f059900f75639f1b1a03f2c25333ef9aa22d58b8mtklein    const char* onGetName() override {
97f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        fName.set("bitmap");
986c22573edb234ad14df947278cfed010669a39a7reed        fName.appendf("_%s%s", sk_tool_utils::colortype_name(fColorType),
996c22573edb234ad14df947278cfed010669a39a7reed                      kOpaque_SkAlphaType == fAlphaType ? "" : "_A");
10014e4d392d4ffa50c0ddf359a426668d1718d7f92mtklein        if (fDoScale) {
10114e4d392d4ffa50c0ddf359a426668d1718d7f92mtklein            fName.append("_scale");
10214e4d392d4ffa50c0ddf359a426668d1718d7f92mtklein        }
10314e4d392d4ffa50c0ddf359a426668d1718d7f92mtklein        if (fForceUpdate) {
1044ee7ae5dcfe2055cfcfc21bf2cec1d790330eb4ajunov@google.com            fName.append("_update");
10514e4d392d4ffa50c0ddf359a426668d1718d7f92mtklein        }
10614e4d392d4ffa50c0ddf359a426668d1718d7f92mtklein        if (fIsVolatile) {
1074ee7ae5dcfe2055cfcfc21bf2cec1d790330eb4ajunov@google.com            fName.append("_volatile");
10814e4d392d4ffa50c0ddf359a426668d1718d7f92mtklein        }
1094ee7ae5dcfe2055cfcfc21bf2cec1d790330eb4ajunov@google.com
110f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        return fName.c_str();
111f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    }
112f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com
1132880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    void onDelayedSetup() override {
114c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        SkBitmap bm;
115c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com
1166c22573edb234ad14df947278cfed010669a39a7reed        if (kIndex_8_SkColorType == fColorType) {
117bae704b050491a8a98c67cb23eaccb10852d2bd5reed            bm.allocPixels(SkImageInfo::MakeN32(W, H, fAlphaType));
118c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        } else {
119bae704b050491a8a98c67cb23eaccb10852d2bd5reed            bm.allocPixels(SkImageInfo::Make(W, H, fColorType, fAlphaType));
120c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        }
1216c22573edb234ad14df947278cfed010669a39a7reed        bm.eraseColor(kOpaque_SkAlphaType == fAlphaType ? SK_ColorBLACK : 0);
122c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com
123f059900f75639f1b1a03f2c25333ef9aa22d58b8mtklein        this->onDrawIntoBitmap(bm);
124c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com
1256c22573edb234ad14df947278cfed010669a39a7reed        if (kIndex_8_SkColorType == fColorType) {
1266c22573edb234ad14df947278cfed010669a39a7reed            convertToIndex666(bm, &fBitmap, fAlphaType);
127c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        } else {
128c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com            fBitmap = bm;
129c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        }
130c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com
131c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        fBitmap.setIsVolatile(fIsVolatile);
132c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com    }
133c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com
1342880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    void onDraw(int loops, SkCanvas* canvas) override {
13514e4d392d4ffa50c0ddf359a426668d1718d7f92mtklein        if (fDoScale) {
13614e4d392d4ffa50c0ddf359a426668d1718d7f92mtklein            canvas->scale(.99f, .99f);
13714e4d392d4ffa50c0ddf359a426668d1718d7f92mtklein        }
138f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        SkIPoint dim = this->getSize();
139e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org        SkRandom rand;
140f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com
141f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        SkPaint paint(fPaint);
142f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        this->setupPaint(&paint);
143f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com
144f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        const SkBitmap& bitmap = fBitmap;
145f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        const SkScalar x0 = SkIntToScalar(-bitmap.width() / 2);
146f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        const SkScalar y0 = SkIntToScalar(-bitmap.height() / 2);
147fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1483361471a3504ecd0351ff70f4c42d8d6fee963d4commit-bot@chromium.org        for (int i = 0; i < loops; i++) {
149f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            SkScalar x = x0 + rand.nextUScalar1() * dim.fX;
150f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            SkScalar y = y0 + rand.nextUScalar1() * dim.fY;
1514ee7ae5dcfe2055cfcfc21bf2cec1d790330eb4ajunov@google.com
1524ee7ae5dcfe2055cfcfc21bf2cec1d790330eb4ajunov@google.com            if (fForceUpdate)
1534ee7ae5dcfe2055cfcfc21bf2cec1d790330eb4ajunov@google.com                bitmap.notifyPixelsChanged();
1544ee7ae5dcfe2055cfcfc21bf2cec1d790330eb4ajunov@google.com
155f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            canvas->drawBitmap(bitmap, x, y, &paint);
156f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        }
157f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    }
158f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com
159f059900f75639f1b1a03f2c25333ef9aa22d58b8mtklein     virtual void onDrawIntoBitmap(const SkBitmap& bm) {
160c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        const int w = bm.width();
161c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        const int h = bm.height();
162c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com
163c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        SkCanvas canvas(bm);
164c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        SkPaint p;
165c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        p.setAntiAlias(true);
166c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        p.setColor(SK_ColorRED);
167c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        canvas.drawCircle(SkIntToScalar(w)/2, SkIntToScalar(h)/2,
168c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com                          SkIntToScalar(SkMin32(w, h))*3/8, p);
169c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com
170c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        SkRect r;
171c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        r.set(0, 0, SkIntToScalar(w), SkIntToScalar(h));
172c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        p.setStyle(SkPaint::kStroke_Style);
173c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        p.setStrokeWidth(SkIntToScalar(4));
174c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        p.setColor(SK_ColorBLUE);
175c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        canvas.drawRect(r, p);
176c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com    }
177c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com
178f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.comprivate:
179f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina    typedef Benchmark INHERITED;
180f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com};
181f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com
182c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com/** Explicitly invoke some filter types to improve coverage of acceleration
183c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com    procs. */
184c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com
185ef77ec210416733e38072175cc948dcbdb831685reed@google.comenum Flags {
186ef77ec210416733e38072175cc948dcbdb831685reed@google.com    kScale_Flag             = 1 << 0,
187ef77ec210416733e38072175cc948dcbdb831685reed@google.com    kRotate_Flag            = 1 << 1,
188ef77ec210416733e38072175cc948dcbdb831685reed@google.com    kBilerp_Flag            = 1 << 2,
189ef77ec210416733e38072175cc948dcbdb831685reed@google.com    kBicubic_Flag           = 1 << 3,
190ef77ec210416733e38072175cc948dcbdb831685reed@google.com};
191ef77ec210416733e38072175cc948dcbdb831685reed@google.com
192ef77ec210416733e38072175cc948dcbdb831685reed@google.comstatic bool isBilerp(uint32_t flags) {
193ef77ec210416733e38072175cc948dcbdb831685reed@google.com    return (flags & (kBilerp_Flag | kBicubic_Flag)) == (kBilerp_Flag);
194ef77ec210416733e38072175cc948dcbdb831685reed@google.com}
195ef77ec210416733e38072175cc948dcbdb831685reed@google.com
196ef77ec210416733e38072175cc948dcbdb831685reed@google.comstatic bool isBicubic(uint32_t flags) {
197ef77ec210416733e38072175cc948dcbdb831685reed@google.com    return (flags & (kBilerp_Flag | kBicubic_Flag)) == (kBilerp_Flag | kBicubic_Flag);
198ef77ec210416733e38072175cc948dcbdb831685reed@google.com}
199ef77ec210416733e38072175cc948dcbdb831685reed@google.com
200c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.comclass FilterBitmapBench : public BitmapBench {
201ef77ec210416733e38072175cc948dcbdb831685reed@google.com    uint32_t    fFlags;
202c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com    SkString    fFullName;
203c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.compublic:
2046c22573edb234ad14df947278cfed010669a39a7reed    FilterBitmapBench(SkColorType ct, SkAlphaType at,
205ef77ec210416733e38072175cc948dcbdb831685reed@google.com                      bool forceUpdate, bool isVolitile, uint32_t flags)
20614e4d392d4ffa50c0ddf359a426668d1718d7f92mtklein        : INHERITED(ct, at, forceUpdate, isVolitile, false)
207ef77ec210416733e38072175cc948dcbdb831685reed@google.com        , fFlags(flags) {
208c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com    }
209c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com
210c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.comprotected:
211f059900f75639f1b1a03f2c25333ef9aa22d58b8mtklein    const char* onGetName() override {
212c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com        fFullName.set(INHERITED::onGetName());
213ef77ec210416733e38072175cc948dcbdb831685reed@google.com        if (fFlags & kScale_Flag) {
214c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com            fFullName.append("_scale");
215ef77ec210416733e38072175cc948dcbdb831685reed@google.com        }
216ef77ec210416733e38072175cc948dcbdb831685reed@google.com        if (fFlags & kRotate_Flag) {
217c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com            fFullName.append("_rotate");
218ef77ec210416733e38072175cc948dcbdb831685reed@google.com        }
219ef77ec210416733e38072175cc948dcbdb831685reed@google.com        if (isBilerp(fFlags)) {
220ef77ec210416733e38072175cc948dcbdb831685reed@google.com            fFullName.append("_bilerp");
221ef77ec210416733e38072175cc948dcbdb831685reed@google.com        } else if (isBicubic(fFlags)) {
222ef77ec210416733e38072175cc948dcbdb831685reed@google.com            fFullName.append("_bicubic");
223ef77ec210416733e38072175cc948dcbdb831685reed@google.com        }
224c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com
225c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com        return fFullName.c_str();
226c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com    }
227c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com
2282880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    void onDraw(int loops, SkCanvas* canvas) override {
229c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com        SkISize dim = canvas->getDeviceSize();
230ef77ec210416733e38072175cc948dcbdb831685reed@google.com        if (fFlags & kScale_Flag) {
231c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com            const SkScalar x = SkIntToScalar(dim.fWidth) / 2;
232c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com            const SkScalar y = SkIntToScalar(dim.fHeight) / 2;
233fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
234c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com            canvas->translate(x, y);
235c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com            // just enough so we can't take the sprite case
236c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com            canvas->scale(SK_Scalar1 * 99/100, SK_Scalar1 * 99/100);
237c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com            canvas->translate(-x, -y);
238c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com        }
239ef77ec210416733e38072175cc948dcbdb831685reed@google.com        if (fFlags & kRotate_Flag) {
240c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com            const SkScalar x = SkIntToScalar(dim.fWidth) / 2;
241c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com            const SkScalar y = SkIntToScalar(dim.fHeight) / 2;
242fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
243c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com            canvas->translate(x, y);
244c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com            canvas->rotate(SkIntToScalar(35));
245c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com            canvas->translate(-x, -y);
246c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com        }
2473361471a3504ecd0351ff70f4c42d8d6fee963d4commit-bot@chromium.org        INHERITED::onDraw(loops, canvas);
2489cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com    }
249c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com
25036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void setupPaint(SkPaint* paint) override {
2519cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com        this->INHERITED::setupPaint(paint);
2529cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com
2539cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com        int index = 0;
254ef77ec210416733e38072175cc948dcbdb831685reed@google.com        if (fFlags & kBilerp_Flag) {
2559cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com            index |= 1;
256ef77ec210416733e38072175cc948dcbdb831685reed@google.com        }
257ef77ec210416733e38072175cc948dcbdb831685reed@google.com        if (fFlags & kBicubic_Flag) {
2589cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com            index |= 2;
259ef77ec210416733e38072175cc948dcbdb831685reed@google.com        }
26093a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed        static const SkFilterQuality gQualitys[] = {
26193a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed            kNone_SkFilterQuality,
26293a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed            kLow_SkFilterQuality,
26393a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed            kMedium_SkFilterQuality,
26493a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed            kHigh_SkFilterQuality
2659cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com        };
26693a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed        paint->setFilterQuality(gQualitys[index]);
2679cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com}
268c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com
269c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.comprivate:
270c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com    typedef BitmapBench INHERITED;
271c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com};
272c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com
273c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com/** Verify optimizations that test source alpha values. */
274c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com
275c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.comclass SourceAlphaBitmapBench : public BitmapBench {
276c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.compublic:
277c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com    enum SourceAlpha { kOpaque_SourceAlpha, kTransparent_SourceAlpha,
278c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com                       kTwoStripes_SourceAlpha, kThreeStripes_SourceAlpha};
279c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.comprivate:
280c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com    SkString    fFullName;
281c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com    SourceAlpha fSourceAlpha;
282c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.compublic:
2836c22573edb234ad14df947278cfed010669a39a7reed    SourceAlphaBitmapBench(SourceAlpha alpha, SkColorType ct,
284ef77ec210416733e38072175cc948dcbdb831685reed@google.com                bool forceUpdate = false, bool bitmapVolatile = false)
28514e4d392d4ffa50c0ddf359a426668d1718d7f92mtklein        : INHERITED(ct, kPremul_SkAlphaType, forceUpdate, bitmapVolatile, false)
286c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        , fSourceAlpha(alpha) {
287c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com    }
288c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com
289c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.comprotected:
290f059900f75639f1b1a03f2c25333ef9aa22d58b8mtklein    const char* onGetName() override {
291c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        fFullName.set(INHERITED::onGetName());
292c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com
293c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        if (fSourceAlpha == kOpaque_SourceAlpha) {
294c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com                fFullName.append("_source_opaque");
295c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        } else if (fSourceAlpha == kTransparent_SourceAlpha) {
296c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com                fFullName.append("_source_transparent");
297c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        } else if (fSourceAlpha == kTwoStripes_SourceAlpha) {
298c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com                fFullName.append("_source_stripes_two");
299c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        } else if (fSourceAlpha == kThreeStripes_SourceAlpha) {
300c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com                fFullName.append("_source_stripes_three");
301c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        }
302c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com
303c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        return fFullName.c_str();
304c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com    }
305c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com
30636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onDrawIntoBitmap(const SkBitmap& bm) override {
307c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        const int w = bm.width();
308c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        const int h = bm.height();
309c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com
310c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        if (kOpaque_SourceAlpha == fSourceAlpha) {
311c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com            bm.eraseColor(SK_ColorBLACK);
312c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        } else if (kTransparent_SourceAlpha == fSourceAlpha) {
313c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com            bm.eraseColor(0);
314c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        } else if (kTwoStripes_SourceAlpha == fSourceAlpha) {
315c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com            bm.eraseColor(0);
316c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com
317c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com            SkCanvas canvas(bm);
318c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com            SkPaint p;
319c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com            p.setAntiAlias(false);
320c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com            p.setStyle(SkPaint::kFill_Style);
321c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com            p.setColor(SK_ColorRED);
322c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com
323c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com            // Draw red vertical stripes on transparent background
324c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com            SkRect r;
325c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com            for (int x = 0; x < w; x+=2)
326c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com            {
327c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com                r.set(SkIntToScalar(x), 0, SkIntToScalar(x+1), SkIntToScalar(h));
328c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com                canvas.drawRect(r, p);
329c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com            }
330c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com
331c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        } else if (kThreeStripes_SourceAlpha == fSourceAlpha) {
332c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com            bm.eraseColor(0);
333c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com
334c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com            SkCanvas canvas(bm);
335c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com            SkPaint p;
336c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com            p.setAntiAlias(false);
337c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com            p.setStyle(SkPaint::kFill_Style);
338c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com
339c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com            // Draw vertical stripes on transparent background with a pattern
340c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com            // where the first pixel is fully transparent, the next is semi-transparent
341c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com            // and the third is fully opaque.
342c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com            SkRect r;
343c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com            for (int x = 0; x < w; x++)
344c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com            {
345c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com                if (x % 3 == 0) {
346c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com                    continue; // Keep transparent
347c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com                } else if (x % 3 == 1) {
348c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com                    p.setColor(SkColorSetARGB(127, 127, 127, 127)); // Semi-transparent
349c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com                } else if (x % 3 == 2) {
350c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com                    p.setColor(SK_ColorRED); // Opaque
351c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com                }
352c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com                r.set(SkIntToScalar(x), 0, SkIntToScalar(x+1), SkIntToScalar(h));
353c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com                canvas.drawRect(r, p);
354c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com            }
355c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com        }
356c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com    }
357c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com
358c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.comprivate:
359c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com    typedef BitmapBench INHERITED;
360c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com};
3612ece28707338dacfe55e951ed7f2c30725f1e906reed@google.com
36214e4d392d4ffa50c0ddf359a426668d1718d7f92mtkleinDEF_BENCH( return new BitmapBench(kN32_SkColorType, kPremul_SkAlphaType, false, false, false); )
36314e4d392d4ffa50c0ddf359a426668d1718d7f92mtkleinDEF_BENCH( return new BitmapBench(kN32_SkColorType, kOpaque_SkAlphaType, false, false, false); )
36414e4d392d4ffa50c0ddf359a426668d1718d7f92mtkleinDEF_BENCH( return new BitmapBench(kN32_SkColorType, kOpaque_SkAlphaType, false, false, true); )
36514e4d392d4ffa50c0ddf359a426668d1718d7f92mtkleinDEF_BENCH( return new BitmapBench(kRGB_565_SkColorType, kOpaque_SkAlphaType, false, false, false); )
36614e4d392d4ffa50c0ddf359a426668d1718d7f92mtkleinDEF_BENCH( return new BitmapBench(kIndex_8_SkColorType, kPremul_SkAlphaType, false, false, false); )
36714e4d392d4ffa50c0ddf359a426668d1718d7f92mtkleinDEF_BENCH( return new BitmapBench(kIndex_8_SkColorType, kOpaque_SkAlphaType, false, false, false); )
36814e4d392d4ffa50c0ddf359a426668d1718d7f92mtkleinDEF_BENCH( return new BitmapBench(kN32_SkColorType, kOpaque_SkAlphaType, true, true, false); )
36914e4d392d4ffa50c0ddf359a426668d1718d7f92mtkleinDEF_BENCH( return new BitmapBench(kN32_SkColorType, kOpaque_SkAlphaType, true, false, false); )
370f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com
371fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com// scale filter -> S32_opaque_D32_filter_DX_{SSE2,SSSE3} and Fact9 is also for S32_D16_filter_DX_SSE2
3726c22573edb234ad14df947278cfed010669a39a7reedDEF_BENCH( return new FilterBitmapBench(kN32_SkColorType, kPremul_SkAlphaType, false, false, kScale_Flag | kBilerp_Flag); )
3736c22573edb234ad14df947278cfed010669a39a7reedDEF_BENCH( return new FilterBitmapBench(kN32_SkColorType, kOpaque_SkAlphaType, false, false, kScale_Flag | kBilerp_Flag); )
3746c22573edb234ad14df947278cfed010669a39a7reedDEF_BENCH( return new FilterBitmapBench(kN32_SkColorType, kOpaque_SkAlphaType, true, true, kScale_Flag | kBilerp_Flag); )
3756c22573edb234ad14df947278cfed010669a39a7reedDEF_BENCH( return new FilterBitmapBench(kN32_SkColorType, kOpaque_SkAlphaType, true, false, kScale_Flag | kBilerp_Flag); )
376c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com
377c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com// scale rotate filter -> S32_opaque_D32_filter_DXDY_{SSE2,SSSE3}
3786c22573edb234ad14df947278cfed010669a39a7reedDEF_BENCH( return new FilterBitmapBench(kN32_SkColorType, kPremul_SkAlphaType, false, false, kScale_Flag | kRotate_Flag | kBilerp_Flag); )
3796c22573edb234ad14df947278cfed010669a39a7reedDEF_BENCH( return new FilterBitmapBench(kN32_SkColorType, kOpaque_SkAlphaType, false, false, kScale_Flag | kRotate_Flag | kBilerp_Flag); )
3806c22573edb234ad14df947278cfed010669a39a7reedDEF_BENCH( return new FilterBitmapBench(kN32_SkColorType, kOpaque_SkAlphaType, true, true, kScale_Flag | kRotate_Flag | kBilerp_Flag); )
3816c22573edb234ad14df947278cfed010669a39a7reedDEF_BENCH( return new FilterBitmapBench(kN32_SkColorType, kOpaque_SkAlphaType, true, false, kScale_Flag | kRotate_Flag | kBilerp_Flag); )
382ef77ec210416733e38072175cc948dcbdb831685reed@google.com
3836c22573edb234ad14df947278cfed010669a39a7reedDEF_BENCH( return new FilterBitmapBench(kN32_SkColorType, kPremul_SkAlphaType, false, false, kScale_Flag | kBilerp_Flag | kBicubic_Flag); )
3846c22573edb234ad14df947278cfed010669a39a7reedDEF_BENCH( return new FilterBitmapBench(kN32_SkColorType, kPremul_SkAlphaType, false, false, kScale_Flag | kRotate_Flag | kBilerp_Flag | kBicubic_Flag); )
385c3be34d4dbd5a9c58689e5d36fd2eda7c823b5f7tomhudson@google.com
386c2532dd0b89e03ed158229872cb1ee06ae7f10fedjsollen@google.com// source alpha tests -> S32A_Opaque_BlitRow32_{arm,neon}
3876c22573edb234ad14df947278cfed010669a39a7reedDEF_BENCH( return new SourceAlphaBitmapBench(SourceAlphaBitmapBench::kOpaque_SourceAlpha, kN32_SkColorType); )
3886c22573edb234ad14df947278cfed010669a39a7reedDEF_BENCH( return new SourceAlphaBitmapBench(SourceAlphaBitmapBench::kTransparent_SourceAlpha, kN32_SkColorType); )
3896c22573edb234ad14df947278cfed010669a39a7reedDEF_BENCH( return new SourceAlphaBitmapBench(SourceAlphaBitmapBench::kTwoStripes_SourceAlpha, kN32_SkColorType); )
3906c22573edb234ad14df947278cfed010669a39a7reedDEF_BENCH( return new SourceAlphaBitmapBench(SourceAlphaBitmapBench::kThreeStripes_SourceAlpha, kN32_SkColorType); )
391