blob: eb7d39f5dbe9a7a92bd142070dca48f3d2a6294f [file] [log] [blame]
reed@google.com3fb51872011-06-01 15:11:22 +00001#include "SkBenchmark.h"
2#include "SkMatrix.h"
tomhudson@google.com7b4e1072011-06-03 19:16:56 +00003#include "SkRandom.h"
reed@google.com3fb51872011-06-01 15:11:22 +00004#include "SkString.h"
5
6class MatrixBench : public SkBenchmark {
7 SkString fName;
8 enum { N = 100000 };
9public:
10 MatrixBench(void* param, const char name[]) : INHERITED(param) {
11 fName.printf("matrix_%s", name);
12 }
13
14 virtual void performTest() = 0;
15
16protected:
17 virtual const char* onGetName() {
18 return fName.c_str();
19 }
20
21 virtual void onDraw(SkCanvas* canvas) {
22 for (int i = 0; i < N; i++) {
23 this->performTest();
24 }
25 }
26
27private:
28 typedef SkBenchmark INHERITED;
29};
30
31// we want to stop the compiler from eliminating code that it thinks is a no-op
32// so we have a non-static global we increment, hoping that will convince the
33// compiler to execute everything
34int gMatrixBench_NonStaticGlobal;
35
36#define always_do(pred) \
37 do { \
38 if (pred) { \
39 ++gMatrixBench_NonStaticGlobal; \
40 } \
41 } while (0)
42
43class EqualsMatrixBench : public MatrixBench {
44public:
45 EqualsMatrixBench(void* param) : INHERITED(param, "equals") {}
46protected:
47 virtual void performTest() {
48 SkMatrix m0, m1, m2;
tomhudson@google.com7b4e1072011-06-03 19:16:56 +000049
reed@google.com3fb51872011-06-01 15:11:22 +000050 m0.reset();
51 m1.reset();
52 m2.reset();
53 always_do(m0 == m1);
54 always_do(m1 == m2);
55 always_do(m2 == m0);
56 always_do(m0.getType());
57 always_do(m1.getType());
58 always_do(m2.getType());
59 }
60private:
61 typedef MatrixBench INHERITED;
62};
63
64class ScaleMatrixBench : public MatrixBench {
65public:
66 ScaleMatrixBench(void* param) : INHERITED(param, "scale") {
tomhudson@google.com7b4e1072011-06-03 19:16:56 +000067
reed@google.com3fb51872011-06-01 15:11:22 +000068 fM0.reset();
69 fM1.setScale(fSX, fSY);
70 fM2.setTranslate(fSX, fSY);
71 fSX = fSY = SkFloatToScalar(1.5f);
72 }
73protected:
74 virtual void performTest() {
75 SkMatrix m;
76 m = fM0; m.preScale(fSX, fSY);
77 m = fM1; m.preScale(fSX, fSY);
78 m = fM2; m.preScale(fSX, fSY);
79 }
80private:
81 SkMatrix fM0, fM1, fM2;
82 SkScalar fSX, fSY;
83 typedef MatrixBench INHERITED;
84};
85
reed@google.come0dcde72011-06-06 13:20:29 +000086// having unknown values in our arrays can throw off the timing a lot, perhaps
87// handling NaN values is a lot slower. Anyway, this guy is just meant to put
88// reasonable values in our arrays.
89template <typename T> void init9(T array[9]) {
90 SkRandom rand;
91 for (int i = 0; i < 9; i++) {
92 array[i] = rand.nextSScalar1();
93 }
94}
95
tomhudson@google.com7b4e1072011-06-03 19:16:56 +000096// Test the performance of setConcat() non-perspective case:
97// using floating point precision only.
98class FloatConcatMatrixBench : public MatrixBench {
99public:
reed@google.come0dcde72011-06-06 13:20:29 +0000100 FloatConcatMatrixBench(void* p) : INHERITED(p, "concat_floatfloat") {
101 init9(mya);
102 init9(myb);
103 init9(myr);
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000104 }
105protected:
106 static inline void muladdmul(float a, float b, float c, float d,
107 float* result) {
108 *result = a * b + c * d;
109 }
110 virtual void performTest() {
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000111 const float* a = mya;
112 const float* b = myb;
113 float* r = myr;
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000114 muladdmul(a[0], b[0], a[1], b[3], &r[0]);
115 muladdmul(a[0], b[1], a[1], b[4], &r[1]);
116 muladdmul(a[0], b[2], a[1], b[5], &r[2]);
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000117 r[2] += a[2];
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000118 muladdmul(a[3], b[0], a[4], b[3], &r[3]);
119 muladdmul(a[3], b[1], a[4], b[4], &r[4]);
120 muladdmul(a[3], b[2], a[4], b[5], &r[5]);
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000121 r[5] += a[5];
122 r[6] = r[7] = 0.0f;
123 r[8] = 1.0f;
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000124 }
125private:
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000126 float mya [9];
127 float myb [9];
128 float myr [9];
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000129 typedef MatrixBench INHERITED;
130};
131
132static inline float SkDoubleToFloat(double x) {
133 return static_cast<float>(x);
134}
135
136// Test the performance of setConcat() non-perspective case:
137// using floating point precision but casting up to float for
138// intermediate results during computations.
139class FloatDoubleConcatMatrixBench : public MatrixBench {
140public:
reed@google.come0dcde72011-06-06 13:20:29 +0000141 FloatDoubleConcatMatrixBench(void* p) : INHERITED(p, "concat_floatdouble") {
142 init9(mya);
143 init9(myb);
144 init9(myr);
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000145 }
146protected:
147 static inline void muladdmul(float a, float b, float c, float d,
148 float* result) {
149 *result = SkDoubleToFloat((double)a * b + (double)c * d);
150 }
151 virtual void performTest() {
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000152 const float* a = mya;
153 const float* b = myb;
154 float* r = myr;
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000155 muladdmul(a[0], b[0], a[1], b[3], &r[0]);
156 muladdmul(a[0], b[1], a[1], b[4], &r[1]);
157 muladdmul(a[0], b[2], a[1], b[5], &r[2]);
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000158 r[2] += a[2];
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000159 muladdmul(a[3], b[0], a[4], b[3], &r[3]);
160 muladdmul(a[3], b[1], a[4], b[4], &r[4]);
161 muladdmul(a[3], b[2], a[4], b[5], &r[5]);
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000162 r[5] += a[5];
163 r[6] = r[7] = 0.0f;
164 r[8] = 1.0f;
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000165 }
166private:
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000167 float mya [9];
168 float myb [9];
169 float myr [9];
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000170 typedef MatrixBench INHERITED;
171};
172
173// Test the performance of setConcat() non-perspective case:
174// using double precision only.
175class DoubleConcatMatrixBench : public MatrixBench {
176public:
reed@google.come0dcde72011-06-06 13:20:29 +0000177 DoubleConcatMatrixBench(void* p) : INHERITED(p, "concat_double") {
178 init9(mya);
179 init9(myb);
180 init9(myr);
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000181 }
182protected:
183 static inline void muladdmul(double a, double b, double c, double d,
184 double* result) {
185 *result = a * b + c * d;
186 }
187 virtual void performTest() {
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000188 const double* a = mya;
189 const double* b = myb;
190 double* r = myr;
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000191 muladdmul(a[0], b[0], a[1], b[3], &r[0]);
192 muladdmul(a[0], b[1], a[1], b[4], &r[1]);
193 muladdmul(a[0], b[2], a[1], b[5], &r[2]);
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000194 r[2] += a[2];
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000195 muladdmul(a[3], b[0], a[4], b[3], &r[3]);
196 muladdmul(a[3], b[1], a[4], b[4], &r[4]);
197 muladdmul(a[3], b[2], a[4], b[5], &r[5]);
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000198 r[5] += a[5];
199 r[6] = r[7] = 0.0;
200 r[8] = 1.0;
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000201 }
202private:
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000203 double mya [9];
204 double myb [9];
205 double myr [9];
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000206 typedef MatrixBench INHERITED;
207};
208
209
reed@google.com3fb51872011-06-01 15:11:22 +0000210static SkBenchmark* M0(void* p) { return new EqualsMatrixBench(p); }
211static SkBenchmark* M1(void* p) { return new ScaleMatrixBench(p); }
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000212static SkBenchmark* M2(void* p) { return new FloatConcatMatrixBench(p); }
213static SkBenchmark* M3(void* p) { return new FloatDoubleConcatMatrixBench(p); }
214static SkBenchmark* M4(void* p) { return new DoubleConcatMatrixBench(p); }
reed@google.com3fb51872011-06-01 15:11:22 +0000215
216static BenchRegistry gReg0(M0);
217static BenchRegistry gReg1(M1);
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000218static BenchRegistry gReg2(M2);
219static BenchRegistry gReg3(M3);
220static BenchRegistry gReg4(M4);