• 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 "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