blob: 783bf519402ca6a1981bd8ff58c21851d2a2d35a [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() {
tomhudson@google.coma20416b2011-06-03 20:32:58 +000099 const float* a = mya;
100 const float* b = myb;
101 float* r = myr;
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000102 muladdmul(a[0], b[0], a[1], b[3], &r[0]);
103 muladdmul(a[0], b[1], a[1], b[4], &r[1]);
104 muladdmul(a[0], b[2], a[1], b[5], &r[2]);
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000105 r[2] += a[2];
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000106 muladdmul(a[3], b[0], a[4], b[3], &r[3]);
107 muladdmul(a[3], b[1], a[4], b[4], &r[4]);
108 muladdmul(a[3], b[2], a[4], b[5], &r[5]);
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000109 r[5] += a[5];
110 r[6] = r[7] = 0.0f;
111 r[8] = 1.0f;
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000112 }
113private:
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000114 float mya [9];
115 float myb [9];
116 float myr [9];
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000117 typedef MatrixBench INHERITED;
118};
119
120static inline float SkDoubleToFloat(double x) {
121 return static_cast<float>(x);
122}
123
124// Test the performance of setConcat() non-perspective case:
125// using floating point precision but casting up to float for
126// intermediate results during computations.
127class FloatDoubleConcatMatrixBench : public MatrixBench {
128public:
129 FloatDoubleConcatMatrixBench(void* param)
130 : INHERITED(param, "concat_floatdouble") {
131 }
132protected:
133 static inline void muladdmul(float a, float b, float c, float d,
134 float* result) {
135 *result = SkDoubleToFloat((double)a * b + (double)c * d);
136 }
137 virtual void performTest() {
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000138 const float* a = mya;
139 const float* b = myb;
140 float* r = myr;
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000141 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]);
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000144 r[2] += a[2];
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000145 muladdmul(a[3], b[0], a[4], b[3], &r[3]);
146 muladdmul(a[3], b[1], a[4], b[4], &r[4]);
147 muladdmul(a[3], b[2], a[4], b[5], &r[5]);
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000148 r[5] += a[5];
149 r[6] = r[7] = 0.0f;
150 r[8] = 1.0f;
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000151 }
152private:
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000153 float mya [9];
154 float myb [9];
155 float myr [9];
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000156 typedef MatrixBench INHERITED;
157};
158
159// Test the performance of setConcat() non-perspective case:
160// using double precision only.
161class DoubleConcatMatrixBench : public MatrixBench {
162public:
163 DoubleConcatMatrixBench(void* param)
164 : INHERITED(param, "concat_double") {
165 }
166protected:
167 static inline void muladdmul(double a, double b, double c, double d,
168 double* result) {
169 *result = a * b + c * d;
170 }
171 virtual void performTest() {
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000172 const double* a = mya;
173 const double* b = myb;
174 double* r = myr;
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000175 muladdmul(a[0], b[0], a[1], b[3], &r[0]);
176 muladdmul(a[0], b[1], a[1], b[4], &r[1]);
177 muladdmul(a[0], b[2], a[1], b[5], &r[2]);
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000178 r[2] += a[2];
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000179 muladdmul(a[3], b[0], a[4], b[3], &r[3]);
180 muladdmul(a[3], b[1], a[4], b[4], &r[4]);
181 muladdmul(a[3], b[2], a[4], b[5], &r[5]);
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000182 r[5] += a[5];
183 r[6] = r[7] = 0.0;
184 r[8] = 1.0;
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000185 }
186private:
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000187 double mya [9];
188 double myb [9];
189 double myr [9];
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000190 typedef MatrixBench INHERITED;
191};
192
193
reed@google.com3fb51872011-06-01 15:11:22 +0000194static SkBenchmark* M0(void* p) { return new EqualsMatrixBench(p); }
195static SkBenchmark* M1(void* p) { return new ScaleMatrixBench(p); }
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000196static SkBenchmark* M2(void* p) { return new FloatConcatMatrixBench(p); }
197static SkBenchmark* M3(void* p) { return new FloatDoubleConcatMatrixBench(p); }
198static SkBenchmark* M4(void* p) { return new DoubleConcatMatrixBench(p); }
reed@google.com3fb51872011-06-01 15:11:22 +0000199
200static BenchRegistry gReg0(M0);
201static BenchRegistry gReg1(M1);
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000202static BenchRegistry gReg2(M2);
203static BenchRegistry gReg3(M3);
204static BenchRegistry gReg4(M4);