1
2 /*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8 #include "Benchmark.h"
9 #include "SkFloatBits.h"
10 #include "SkRandom.h"
11 #include "SkRect.h"
12 #include "SkString.h"
13
14 class ScalarBench : public Benchmark {
15 SkString fName;
16 public:
ScalarBench(const char name[])17 ScalarBench(const char name[]) {
18 fName.printf("scalar_%s", name);
19 }
20
isSuitableFor(Backend backend)21 virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
22 return backend == kNonRendering_Backend;
23 }
24
25 virtual void performTest() = 0;
26
27 protected:
mulLoopCount() const28 virtual int mulLoopCount() const { return 1; }
29
onGetName()30 virtual const char* onGetName() SK_OVERRIDE {
31 return fName.c_str();
32 }
33
onDraw(const int loops,SkCanvas * canvas)34 virtual void onDraw(const int loops, SkCanvas* canvas) {
35 for (int i = 0; i < loops; i++) {
36 this->performTest();
37 }
38 }
39
40 private:
41 typedef Benchmark INHERITED;
42 };
43
44 // having unknown values in our arrays can throw off the timing a lot, perhaps
45 // handling NaN values is a lot slower. Anyway, this guy is just meant to put
46 // reasonable values in our arrays.
init9(T array[9])47 template <typename T> void init9(T array[9]) {
48 SkRandom rand;
49 for (int i = 0; i < 9; i++) {
50 array[i] = rand.nextSScalar1();
51 }
52 }
53
54 class FloatComparisonBench : public ScalarBench {
55 public:
FloatComparisonBench()56 FloatComparisonBench() : INHERITED("compare_float") {
57 init9(fArray);
58 }
59 protected:
mulLoopCount() const60 virtual int mulLoopCount() const { return 4; }
performTest()61 virtual void performTest() {
62 // xoring into a volatile prevents the compiler from optimizing these checks away.
63 volatile bool junk = false;
64 junk ^= (fArray[6] != 0.0f || fArray[7] != 0.0f || fArray[8] != 1.0f);
65 junk ^= (fArray[2] != 0.0f || fArray[5] != 0.0f);
66 }
67 private:
68 float fArray[9];
69 typedef ScalarBench INHERITED;
70 };
71
72 class ForcedIntComparisonBench : public ScalarBench {
73 public:
ForcedIntComparisonBench()74 ForcedIntComparisonBench()
75 : INHERITED("compare_forced_int") {
76 init9(fArray);
77 }
78 protected:
mulLoopCount() const79 virtual int mulLoopCount() const { return 4; }
performTest()80 virtual void performTest() {
81 // xoring into a volatile prevents the compiler from optimizing these checks away.
82 volatile int32_t junk = 0;
83 junk ^= (SkScalarAs2sCompliment(fArray[6]) |
84 SkScalarAs2sCompliment(fArray[7]) |
85 (SkScalarAs2sCompliment(fArray[8]) - kPersp1Int));
86 junk ^= (SkScalarAs2sCompliment(fArray[2]) |
87 SkScalarAs2sCompliment(fArray[5]));
88 }
89 private:
90 static const int32_t kPersp1Int = 0x3f800000;
91 SkScalar fArray[9];
92 typedef ScalarBench INHERITED;
93 };
94
95 class IsFiniteScalarBench : public ScalarBench {
96 public:
IsFiniteScalarBench()97 IsFiniteScalarBench() : INHERITED("isfinite") {
98 SkRandom rand;
99 for (size_t i = 0; i < ARRAY_N; ++i) {
100 fArray[i] = rand.nextSScalar1();
101 }
102 }
103 protected:
mulLoopCount() const104 virtual int mulLoopCount() const { return 1; }
performTest()105 virtual void performTest() SK_OVERRIDE {
106 int sum = 0;
107 for (size_t i = 0; i < ARRAY_N; ++i) {
108 // We pass -fArray[i], so the compiler can't cheat and treat the
109 // value as an int (even though we tell it that it is a float)
110 sum += SkScalarIsFinite(-fArray[i]);
111 }
112 // we do this so the compiler won't optimize our loop away...
113 this->doSomething(fArray, sum);
114 }
115
doSomething(SkScalar array[],int sum)116 virtual void doSomething(SkScalar array[], int sum) {}
117 private:
118 enum {
119 ARRAY_N = 64
120 };
121 SkScalar fArray[ARRAY_N];
122
123 typedef ScalarBench INHERITED;
124 };
125
126 ///////////////////////////////////////////////////////////////////////////////
127
128 class RectBoundsBench : public Benchmark {
129 enum {
130 PTS = 100,
131 };
132 SkPoint fPts[PTS];
133
134 public:
RectBoundsBench()135 RectBoundsBench() {
136 SkRandom rand;
137 for (int i = 0; i < PTS; ++i) {
138 fPts[i].fX = rand.nextSScalar1();
139 fPts[i].fY = rand.nextSScalar1();
140 }
141 }
142
isSuitableFor(Backend backend)143 virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
144 return backend == kNonRendering_Backend;
145 }
146
147 protected:
onGetName()148 virtual const char* onGetName() SK_OVERRIDE {
149 return "rect_bounds";
150 }
151
onDraw(const int loops,SkCanvas * canvas)152 virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
153 SkRect r;
154 for (int i = 0; i < loops; ++i) {
155 r.set(fPts, PTS);
156 }
157 }
158
159 private:
160 typedef Benchmark INHERITED;
161 };
162
163 ///////////////////////////////////////////////////////////////////////////////
164
165 DEF_BENCH( return new FloatComparisonBench(); )
166 DEF_BENCH( return new ForcedIntComparisonBench(); )
167 DEF_BENCH( return new RectBoundsBench(); )
168 DEF_BENCH( return new IsFiniteScalarBench(); )
169