• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "SkBenchmark.h"
9 #include "SkFloatBits.h"
10 #include "SkRandom.h"
11 #include "SkRect.h"
12 #include "SkString.h"
13 
14 class ScalarBench : public SkBenchmark {
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 SkBenchmark INHERITED;
42 };
43 
44 // we want to stop the compiler from eliminating code that it thinks is a no-op
45 // so we have a non-static global we increment, hoping that will convince the
46 // compiler to execute everything
47 int gScalarBench_NonStaticGlobal;
48 
49 #define always_do(pred)                     \
50     do {                                    \
51         if (pred) {                         \
52             ++gScalarBench_NonStaticGlobal; \
53         }                                   \
54     } while (0)
55 
56 // having unknown values in our arrays can throw off the timing a lot, perhaps
57 // handling NaN values is a lot slower. Anyway, this guy is just meant to put
58 // reasonable values in our arrays.
init9(T array[9])59 template <typename T> void init9(T array[9]) {
60     SkRandom rand;
61     for (int i = 0; i < 9; i++) {
62         array[i] = rand.nextSScalar1();
63     }
64 }
65 
66 class FloatComparisonBench : public ScalarBench {
67 public:
FloatComparisonBench()68     FloatComparisonBench() : INHERITED("compare_float") {
69         init9(fArray);
70     }
71 protected:
mulLoopCount() const72     virtual int mulLoopCount() const { return 4; }
performTest()73     virtual void performTest() {
74         always_do(fArray[6] != 0.0f || fArray[7] != 0.0f || fArray[8] != 1.0f);
75         always_do(fArray[2] != 0.0f || fArray[5] != 0.0f);
76     }
77 private:
78     float fArray[9];
79     typedef ScalarBench INHERITED;
80 };
81 
82 class ForcedIntComparisonBench : public ScalarBench {
83 public:
ForcedIntComparisonBench()84     ForcedIntComparisonBench()
85     : INHERITED("compare_forced_int") {
86         init9(fArray);
87     }
88 protected:
mulLoopCount() const89     virtual int mulLoopCount() const { return 4; }
performTest()90     virtual void performTest() {
91         always_do(SkScalarAs2sCompliment(fArray[6]) |
92                   SkScalarAs2sCompliment(fArray[7]) |
93                   (SkScalarAs2sCompliment(fArray[8]) - kPersp1Int));
94         always_do(SkScalarAs2sCompliment(fArray[2]) |
95                   SkScalarAs2sCompliment(fArray[5]));
96     }
97 private:
98     static const int32_t kPersp1Int = 0x3f800000;
99     SkScalar fArray[9];
100     typedef ScalarBench INHERITED;
101 };
102 
103 class IsFiniteScalarBench : public ScalarBench {
104 public:
IsFiniteScalarBench()105     IsFiniteScalarBench() : INHERITED("isfinite") {
106         SkRandom rand;
107         for (size_t i = 0; i < ARRAY_N; ++i) {
108             fArray[i] = rand.nextSScalar1();
109         }
110     }
111 protected:
mulLoopCount() const112     virtual int mulLoopCount() const { return 1; }
performTest()113     virtual void performTest() SK_OVERRIDE {
114         int sum = 0;
115         for (size_t i = 0; i < ARRAY_N; ++i) {
116             // We pass -fArray[i], so the compiler can't cheat and treat the
117             // value as an int (even though we tell it that it is a float)
118             sum += SkScalarIsFinite(-fArray[i]);
119         }
120         // we do this so the compiler won't optimize our loop away...
121         this->doSomething(fArray, sum);
122     }
123 
doSomething(SkScalar array[],int sum)124     virtual void doSomething(SkScalar array[], int sum) {}
125 private:
126     enum {
127         ARRAY_N = 64
128     };
129     SkScalar fArray[ARRAY_N];
130 
131     typedef ScalarBench INHERITED;
132 };
133 
134 ///////////////////////////////////////////////////////////////////////////////
135 
136 class RectBoundsBench : public SkBenchmark {
137     enum {
138         PTS = 100,
139     };
140     SkPoint fPts[PTS];
141 
142 public:
RectBoundsBench()143     RectBoundsBench() {
144         SkRandom rand;
145         for (int i = 0; i < PTS; ++i) {
146             fPts[i].fX = rand.nextSScalar1();
147             fPts[i].fY = rand.nextSScalar1();
148         }
149     }
150 
isSuitableFor(Backend backend)151     virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
152         return backend == kNonRendering_Backend;
153     }
154 
155 protected:
onGetName()156     virtual const char* onGetName() SK_OVERRIDE {
157         return "rect_bounds";
158     }
159 
onDraw(const int loops,SkCanvas * canvas)160     virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
161         SkRect r;
162         for (int i = 0; i < loops; ++i) {
163             r.set(fPts, PTS);
164         }
165     }
166 
167 private:
168     typedef SkBenchmark INHERITED;
169 };
170 
171 ///////////////////////////////////////////////////////////////////////////////
172 
173 DEF_BENCH( return new FloatComparisonBench(); )
174 DEF_BENCH( return new ForcedIntComparisonBench(); )
175 DEF_BENCH( return new RectBoundsBench(); )
176 DEF_BENCH( return new IsFiniteScalarBench(); )
177