blob: 72dfe8b7a7979f215e1af83418d530aecf566728 [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
tomhudson@google.com7b4e1072011-06-03 19:16:56 +000086// Test the performance of setConcat() non-perspective case:
87// using floating point precision only.
88class FloatConcatMatrixBench : public MatrixBench {
89public:
90 FloatConcatMatrixBench(void* param)
91 : INHERITED(param, "concat_float") {
92 }
93protected:
94 static inline void muladdmul(float a, float b, float c, float d,
95 float* result) {
96 *result = a * b + c * d;
97 }
98 virtual void performTest() {
99 float a[9];
100 float b[9];
101 float r[9];
102 a[0] = rnd.nextS();
103 a[3] = rnd.nextS();
104 muladdmul(a[0], b[0], a[1], b[3], &r[0]);
105 muladdmul(a[0], b[1], a[1], b[4], &r[1]);
106 muladdmul(a[0], b[2], a[1], b[5], &r[2]);
107 muladdmul(a[3], b[0], a[4], b[3], &r[3]);
108 muladdmul(a[3], b[1], a[4], b[4], &r[4]);
109 muladdmul(a[3], b[2], a[4], b[5], &r[5]);
110 always_do(r[0] + r[1] + r[2] + r[3] + r[4] + r[5] +
111 r[6] + r[7] + r[8] > 0.0f);
112 }
113private:
114 SkRandom rnd;
115 typedef MatrixBench INHERITED;
116};
117
118static inline float SkDoubleToFloat(double x) {
119 return static_cast<float>(x);
120}
121
122// Test the performance of setConcat() non-perspective case:
123// using floating point precision but casting up to float for
124// intermediate results during computations.
125class FloatDoubleConcatMatrixBench : public MatrixBench {
126public:
127 FloatDoubleConcatMatrixBench(void* param)
128 : INHERITED(param, "concat_floatdouble") {
129 }
130protected:
131 static inline void muladdmul(float a, float b, float c, float d,
132 float* result) {
133 *result = SkDoubleToFloat((double)a * b + (double)c * d);
134 }
135 virtual void performTest() {
136 float a[9];
137 float b[9];
138 float r[9];
139 a[0] = rnd.nextS();
140 a[3] = rnd.nextS();
141 muladdmul(a[0], b[0], a[1], b[3], &r[0]);
142 muladdmul(a[0], b[1], a[1], b[4], &r[1]);
143 muladdmul(a[0], b[2], a[1], b[5], &r[2]);
144 muladdmul(a[3], b[0], a[4], b[3], &r[3]);
145 muladdmul(a[3], b[1], a[4], b[4], &r[4]);
146 muladdmul(a[3], b[2], a[4], b[5], &r[5]);
147 always_do(r[0] + r[1] + r[2] + r[3] + r[4] + r[5] +
148 r[6] + r[7] + r[8] > 0.0f);
149 }
150private:
151 SkRandom rnd;
152 typedef MatrixBench INHERITED;
153};
154
155// Test the performance of setConcat() non-perspective case:
156// using double precision only.
157class DoubleConcatMatrixBench : public MatrixBench {
158public:
159 DoubleConcatMatrixBench(void* param)
160 : INHERITED(param, "concat_double") {
161 }
162protected:
163 static inline void muladdmul(double a, double b, double c, double d,
164 double* result) {
165 *result = a * b + c * d;
166 }
167 virtual void performTest() {
168 double a[9];
169 double b[9];
170 double r[9];
171 a[0] = rnd.nextS();
172 a[3] = rnd.nextS();
173 muladdmul(a[0], b[0], a[1], b[3], &r[0]);
174 muladdmul(a[0], b[1], a[1], b[4], &r[1]);
175 muladdmul(a[0], b[2], a[1], b[5], &r[2]);
176 muladdmul(a[3], b[0], a[4], b[3], &r[3]);
177 muladdmul(a[3], b[1], a[4], b[4], &r[4]);
178 muladdmul(a[3], b[2], a[4], b[5], &r[5]);
179 always_do(r[0] + r[1] + r[2] + r[3] + r[4] + r[5] +
180 r[6] + r[7] + r[8] > 0.0f);
181 }
182private:
183 SkRandom rnd;
184 typedef MatrixBench INHERITED;
185};
186
187
reed@google.com3fb51872011-06-01 15:11:22 +0000188static SkBenchmark* M0(void* p) { return new EqualsMatrixBench(p); }
189static SkBenchmark* M1(void* p) { return new ScaleMatrixBench(p); }
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000190static SkBenchmark* M2(void* p) { return new FloatConcatMatrixBench(p); }
191static SkBenchmark* M3(void* p) { return new FloatDoubleConcatMatrixBench(p); }
192static SkBenchmark* M4(void* p) { return new DoubleConcatMatrixBench(p); }
reed@google.com3fb51872011-06-01 15:11:22 +0000193
194static BenchRegistry gReg0(M0);
195static BenchRegistry gReg1(M1);
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000196static BenchRegistry gReg2(M2);
197static BenchRegistry gReg3(M3);
198static BenchRegistry gReg4(M4);