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 */
7f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina#include "Benchmark.h"
825583a381252921f2e9d0dc4a30c3834ef677530tomhudson@google.com#include "SkFloatBits.h"
9f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com#include "SkRandom.h"
1063c57613b8b53d142be6d44aed4ef9e3b9d7cf11reed@google.com#include "SkRect.h"
11f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com#include "SkString.h"
12f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com
13f168b86d7fafc5c20c87bebc6fd393cb17e120catfarinaclass ScalarBench : public Benchmark {
14f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com    SkString    fName;
15f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.compublic:
16410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.com    ScalarBench(const char name[])  {
17f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com        fName.printf("scalar_%s", name);
18644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org    }
19644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org
2036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    bool isSuitableFor(Backend backend) override {
21644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org        return backend == kNonRendering_Backend;
22f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com    }
23f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com
24f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com    virtual void performTest() = 0;
25f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com
26f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.comprotected:
27f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com    virtual int mulLoopCount() const { return 1; }
28f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com
2936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    const char* onGetName() override {
30f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com        return fName.c_str();
31f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com    }
32f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com
33a1ebeb25e9acfcd801e089e063311d716b83b8a5mtklein    void onDraw(int loops, SkCanvas* canvas) override {
343361471a3504ecd0351ff70f4c42d8d6fee963d4commit-bot@chromium.org        for (int i = 0; i < loops; i++) {
35f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com            this->performTest();
36f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com        }
37f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com    }
38f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com
39f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.comprivate:
40f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina    typedef Benchmark INHERITED;
41f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com};
42f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com
43f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com// having unknown values in our arrays can throw off the timing a lot, perhaps
44f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com// handling NaN values is a lot slower. Anyway, this guy is just meant to put
45f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com// reasonable values in our arrays.
46f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.comtemplate <typename T> void init9(T array[9]) {
47e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org    SkRandom rand;
48f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com    for (int i = 0; i < 9; i++) {
49f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com        array[i] = rand.nextSScalar1();
50f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com    }
51f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com}
52f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com
53f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.comclass FloatComparisonBench : public ScalarBench {
54f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.compublic:
55410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.com    FloatComparisonBench() : INHERITED("compare_float") {
56f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com        init9(fArray);
57f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com    }
58f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.comprotected:
59f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com    virtual int mulLoopCount() const { return 4; }
60f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com    virtual void performTest() {
6180f709a0d7f2f1d0d35a292c0c3189d3a50b4993mtklein        // xoring into a volatile prevents the compiler from optimizing these checks away.
6280f709a0d7f2f1d0d35a292c0c3189d3a50b4993mtklein        volatile bool junk = false;
6380f709a0d7f2f1d0d35a292c0c3189d3a50b4993mtklein        junk ^= (fArray[6] != 0.0f || fArray[7] != 0.0f || fArray[8] != 1.0f);
6480f709a0d7f2f1d0d35a292c0c3189d3a50b4993mtklein        junk ^= (fArray[2] != 0.0f || fArray[5] != 0.0f);
65f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com    }
66f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.comprivate:
67f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com    float fArray[9];
68f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com    typedef ScalarBench INHERITED;
69f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com};
70f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com
71f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.comclass ForcedIntComparisonBench : public ScalarBench {
72f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.compublic:
73410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.com    ForcedIntComparisonBench()
74410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.com    : INHERITED("compare_forced_int") {
75f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com        init9(fArray);
76f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com    }
77f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.comprotected:
78f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com    virtual int mulLoopCount() const { return 4; }
79f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com    virtual void performTest() {
8080f709a0d7f2f1d0d35a292c0c3189d3a50b4993mtklein        // xoring into a volatile prevents the compiler from optimizing these checks away.
8180f709a0d7f2f1d0d35a292c0c3189d3a50b4993mtklein        volatile int32_t junk = 0;
8280f709a0d7f2f1d0d35a292c0c3189d3a50b4993mtklein        junk ^= (SkScalarAs2sCompliment(fArray[6]) |
8380f709a0d7f2f1d0d35a292c0c3189d3a50b4993mtklein                 SkScalarAs2sCompliment(fArray[7]) |
8480f709a0d7f2f1d0d35a292c0c3189d3a50b4993mtklein                (SkScalarAs2sCompliment(fArray[8]) - kPersp1Int));
8580f709a0d7f2f1d0d35a292c0c3189d3a50b4993mtklein        junk ^= (SkScalarAs2sCompliment(fArray[2]) |
8680f709a0d7f2f1d0d35a292c0c3189d3a50b4993mtklein                 SkScalarAs2sCompliment(fArray[5]));
87f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com    }
88f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.comprivate:
89f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com    static const int32_t kPersp1Int = 0x3f800000;
9025583a381252921f2e9d0dc4a30c3834ef677530tomhudson@google.com    SkScalar fArray[9];
91f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com    typedef ScalarBench INHERITED;
92f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com};
93f910b36e45b3211ac46ad964b221d6251dda2cf7tomhudson@google.com
94357818cb76d9f8a6a74d1b2f9c91fb4c0b7a288creed@google.comclass IsFiniteScalarBench : public ScalarBench {
95357818cb76d9f8a6a74d1b2f9c91fb4c0b7a288creed@google.compublic:
96410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.com    IsFiniteScalarBench() : INHERITED("isfinite") {
97e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org        SkRandom rand;
98357818cb76d9f8a6a74d1b2f9c91fb4c0b7a288creed@google.com        for (size_t i = 0; i < ARRAY_N; ++i) {
99357818cb76d9f8a6a74d1b2f9c91fb4c0b7a288creed@google.com            fArray[i] = rand.nextSScalar1();
100357818cb76d9f8a6a74d1b2f9c91fb4c0b7a288creed@google.com        }
101357818cb76d9f8a6a74d1b2f9c91fb4c0b7a288creed@google.com    }
102357818cb76d9f8a6a74d1b2f9c91fb4c0b7a288creed@google.comprotected:
10336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    int mulLoopCount() const override { return 1; }
10436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void performTest() override {
105357818cb76d9f8a6a74d1b2f9c91fb4c0b7a288creed@google.com        int sum = 0;
106357818cb76d9f8a6a74d1b2f9c91fb4c0b7a288creed@google.com        for (size_t i = 0; i < ARRAY_N; ++i) {
107357818cb76d9f8a6a74d1b2f9c91fb4c0b7a288creed@google.com            // We pass -fArray[i], so the compiler can't cheat and treat the
108357818cb76d9f8a6a74d1b2f9c91fb4c0b7a288creed@google.com            // value as an int (even though we tell it that it is a float)
109357818cb76d9f8a6a74d1b2f9c91fb4c0b7a288creed@google.com            sum += SkScalarIsFinite(-fArray[i]);
110357818cb76d9f8a6a74d1b2f9c91fb4c0b7a288creed@google.com        }
111357818cb76d9f8a6a74d1b2f9c91fb4c0b7a288creed@google.com        // we do this so the compiler won't optimize our loop away...
112357818cb76d9f8a6a74d1b2f9c91fb4c0b7a288creed@google.com        this->doSomething(fArray, sum);
113357818cb76d9f8a6a74d1b2f9c91fb4c0b7a288creed@google.com    }
114357818cb76d9f8a6a74d1b2f9c91fb4c0b7a288creed@google.com
115357818cb76d9f8a6a74d1b2f9c91fb4c0b7a288creed@google.com    virtual void doSomething(SkScalar array[], int sum) {}
116357818cb76d9f8a6a74d1b2f9c91fb4c0b7a288creed@google.comprivate:
117357818cb76d9f8a6a74d1b2f9c91fb4c0b7a288creed@google.com    enum {
118357818cb76d9f8a6a74d1b2f9c91fb4c0b7a288creed@google.com        ARRAY_N = 64
119357818cb76d9f8a6a74d1b2f9c91fb4c0b7a288creed@google.com    };
120357818cb76d9f8a6a74d1b2f9c91fb4c0b7a288creed@google.com    SkScalar fArray[ARRAY_N];
121357818cb76d9f8a6a74d1b2f9c91fb4c0b7a288creed@google.com
122357818cb76d9f8a6a74d1b2f9c91fb4c0b7a288creed@google.com    typedef ScalarBench INHERITED;
123357818cb76d9f8a6a74d1b2f9c91fb4c0b7a288creed@google.com};
124357818cb76d9f8a6a74d1b2f9c91fb4c0b7a288creed@google.com
12563c57613b8b53d142be6d44aed4ef9e3b9d7cf11reed@google.com///////////////////////////////////////////////////////////////////////////////
12663c57613b8b53d142be6d44aed4ef9e3b9d7cf11reed@google.com
127f168b86d7fafc5c20c87bebc6fd393cb17e120catfarinaclass RectBoundsBench : public Benchmark {
12863c57613b8b53d142be6d44aed4ef9e3b9d7cf11reed@google.com    enum {
12963c57613b8b53d142be6d44aed4ef9e3b9d7cf11reed@google.com        PTS = 100,
13063c57613b8b53d142be6d44aed4ef9e3b9d7cf11reed@google.com    };
13163c57613b8b53d142be6d44aed4ef9e3b9d7cf11reed@google.com    SkPoint fPts[PTS];
13263c57613b8b53d142be6d44aed4ef9e3b9d7cf11reed@google.com
13363c57613b8b53d142be6d44aed4ef9e3b9d7cf11reed@google.compublic:
134410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.com    RectBoundsBench() {
135e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org        SkRandom rand;
13663c57613b8b53d142be6d44aed4ef9e3b9d7cf11reed@google.com        for (int i = 0; i < PTS; ++i) {
13763c57613b8b53d142be6d44aed4ef9e3b9d7cf11reed@google.com            fPts[i].fX = rand.nextSScalar1();
13863c57613b8b53d142be6d44aed4ef9e3b9d7cf11reed@google.com            fPts[i].fY = rand.nextSScalar1();
13963c57613b8b53d142be6d44aed4ef9e3b9d7cf11reed@google.com        }
140644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org    }
141644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org
14236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    bool isSuitableFor(Backend backend) override {
143644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org        return backend == kNonRendering_Backend;
14463c57613b8b53d142be6d44aed4ef9e3b9d7cf11reed@google.com    }
14563c57613b8b53d142be6d44aed4ef9e3b9d7cf11reed@google.com
14663c57613b8b53d142be6d44aed4ef9e3b9d7cf11reed@google.comprotected:
14736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    const char* onGetName() override {
14863c57613b8b53d142be6d44aed4ef9e3b9d7cf11reed@google.com        return "rect_bounds";
14963c57613b8b53d142be6d44aed4ef9e3b9d7cf11reed@google.com    }
15063c57613b8b53d142be6d44aed4ef9e3b9d7cf11reed@google.com
151a1ebeb25e9acfcd801e089e063311d716b83b8a5mtklein    void onDraw(int loops, SkCanvas* canvas) override {
15263c57613b8b53d142be6d44aed4ef9e3b9d7cf11reed@google.com        SkRect r;
1533361471a3504ecd0351ff70f4c42d8d6fee963d4commit-bot@chromium.org        for (int i = 0; i < loops; ++i) {
154b25a83bd8802b7c3c5746c319e781f45337fe207reed            for (int i = 0; i < 1000; ++i) {
155b25a83bd8802b7c3c5746c319e781f45337fe207reed                r.set(fPts, PTS);
156b25a83bd8802b7c3c5746c319e781f45337fe207reed            }
15763c57613b8b53d142be6d44aed4ef9e3b9d7cf11reed@google.com        }
15863c57613b8b53d142be6d44aed4ef9e3b9d7cf11reed@google.com    }
15963c57613b8b53d142be6d44aed4ef9e3b9d7cf11reed@google.com
16063c57613b8b53d142be6d44aed4ef9e3b9d7cf11reed@google.comprivate:
161f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina    typedef Benchmark INHERITED;
16263c57613b8b53d142be6d44aed4ef9e3b9d7cf11reed@google.com};
16363c57613b8b53d142be6d44aed4ef9e3b9d7cf11reed@google.com
16463c57613b8b53d142be6d44aed4ef9e3b9d7cf11reed@google.com///////////////////////////////////////////////////////////////////////////////
16563c57613b8b53d142be6d44aed4ef9e3b9d7cf11reed@google.com
166410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return new FloatComparisonBench(); )
167410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return new ForcedIntComparisonBench(); )
168410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return new RectBoundsBench(); )
169410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return new IsFiniteScalarBench(); )
170