1/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "Benchmark.h"
9#include "SkMatrix44.h"
10#include "SkRandom.h"
11#include "SkString.h"
12
13class Matrix44Bench : public Benchmark {
14    SkString    fName;
15public:
16    Matrix44Bench(const char name[]) {
17        fName.printf("matrix44_%s", name);
18    }
19
20    virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
21        return backend == kNonRendering_Backend;
22    }
23
24    virtual void performTest() = 0;
25
26protected:
27    virtual int mulLoopCount() const { return 1; }
28
29    virtual const char* onGetName() {
30        return fName.c_str();
31    }
32
33    virtual void onDraw(const int loops, SkCanvas*) {
34        for (int i = 0; i < loops; i++) {
35            this->performTest();
36        }
37    }
38
39private:
40    typedef Benchmark INHERITED;
41};
42
43class EqualsMatrix44Bench : public Matrix44Bench {
44public:
45    EqualsMatrix44Bench()
46        : INHERITED("equals")
47        , fM0(SkMatrix44::kIdentity_Constructor)
48        , fM1(SkMatrix44::kIdentity_Constructor)
49        , fM2(SkMatrix44::kIdentity_Constructor)
50    {
51        fM1.set(0, 0, 0);
52        fM2.set(3, 3, 0);
53    }
54protected:
55    virtual void performTest() {
56        for (int i = 0; i < 10; ++i) {
57            (void) (fM0 == fM1);
58            (void) (fM1 == fM2);
59            (void) (fM2 == fM0);
60        }
61    }
62private:
63    SkMatrix44 fM0, fM1, fM2;
64    typedef Matrix44Bench INHERITED;
65};
66
67class SetIdentityMatrix44Bench : public Matrix44Bench {
68public:
69    SetIdentityMatrix44Bench()
70        : INHERITED("setidentity")
71        , mat(SkMatrix44::kIdentity_Constructor)
72    {
73        double rowMajor[16] =
74                { 1, 2, 3, 4,
75                  5, 6, 7, 8,
76                  9, 10, 11, 12,
77                  13, 14, 15, 16};
78        mat.setRowMajord(rowMajor);
79    }
80protected:
81    virtual void performTest() {
82        for (int i = 0; i < 10; ++i) {
83            mat.setIdentity();
84        }
85    }
86private:
87    SkMatrix44 mat;
88    typedef Matrix44Bench INHERITED;
89};
90
91class PreScaleMatrix44Bench : public Matrix44Bench {
92public:
93    PreScaleMatrix44Bench()
94        : INHERITED("prescale")
95        , fM0(SkMatrix44::kUninitialized_Constructor)
96    {
97        fX = fY = fZ = SkDoubleToMScalar(1.5);
98    }
99protected:
100    virtual void performTest() {
101        fM0.reset();
102        for (int i = 0; i < 10; ++i) {
103            fM0.preScale(fX, fY, fZ);
104        }
105    }
106private:
107    SkMatrix44 fM0;
108    SkMScalar  fX, fY, fZ;
109    typedef Matrix44Bench INHERITED;
110};
111
112class InvertMatrix44Bench : public Matrix44Bench {
113public:
114    InvertMatrix44Bench()
115        : INHERITED("invert")
116        , fM0(SkMatrix44::kUninitialized_Constructor)
117        , fM1(SkMatrix44::kUninitialized_Constructor)
118    {
119        fM0.set(0, 0, -1.1);
120        fM0.set(0, 1, 2.1);
121        fM0.set(0, 2, -3.1);
122        fM0.set(0, 3, 4.1);
123        fM0.set(1, 0, 5.1);
124        fM0.set(1, 1, -6.1);
125        fM0.set(1, 2, 7.1);
126        fM0.set(1, 3, 8.1);
127        fM0.set(2, 0, -9.1);
128        fM0.set(2, 1, 10.1);
129        fM0.set(2, 2, 11.1);
130        fM0.set(2, 3, -12.1);
131        fM0.set(3, 0, -13.1);
132        fM0.set(3, 1, 14.1);
133        fM0.set(3, 2, -15.1);
134        fM0.set(3, 3, 16.1);
135    }
136protected:
137    virtual void performTest() {
138        for (int i = 0; i < 10; ++i) {
139            fM0.invert(&fM1);
140        }
141    }
142private:
143    SkMatrix44 fM0, fM1;
144    typedef Matrix44Bench INHERITED;
145};
146
147class InvertAffineMatrix44Bench : public Matrix44Bench {
148public:
149    InvertAffineMatrix44Bench()
150        : INHERITED("invertaffine")
151        , fM0(SkMatrix44::kIdentity_Constructor)
152        , fM1(SkMatrix44::kUninitialized_Constructor)
153    {
154        fM0.set(0, 0, -1.1);
155        fM0.set(0, 1, 2.1);
156        fM0.set(0, 2, -3.1);
157        fM0.set(0, 3, 4.1);
158        fM0.set(1, 0, 5.1);
159        fM0.set(1, 1, -6.1);
160        fM0.set(1, 2, 7.1);
161        fM0.set(1, 3, 8.1);
162        fM0.set(2, 0, -9.1);
163        fM0.set(2, 1, 10.1);
164        fM0.set(2, 2, 11.1);
165        fM0.set(2, 3, -12.1);
166        // bottom row (perspective component) remains (0, 0, 0, 1).
167    }
168protected:
169    virtual void performTest() {
170        for (int i = 0; i < 10; ++i) {
171            fM0.invert(&fM1);
172        }
173    }
174private:
175    SkMatrix44 fM0, fM1;
176    typedef Matrix44Bench INHERITED;
177};
178
179class InvertScaleTranslateMatrix44Bench : public Matrix44Bench {
180public:
181    InvertScaleTranslateMatrix44Bench()
182        : INHERITED("invertscaletranslate")
183        , fM0(SkMatrix44::kIdentity_Constructor)
184        , fM1(SkMatrix44::kUninitialized_Constructor)
185    {
186        fM0.set(0, 0, -1.1);
187        fM0.set(0, 3, 4.1);
188
189        fM0.set(1, 1, -6.1);
190        fM0.set(1, 3, 8.1);
191
192        fM0.set(2, 2, 11.1);
193        fM0.set(2, 3, -12.1);
194    }
195protected:
196    virtual void performTest() {
197        for (int i = 0; i < 10; ++i) {
198            fM0.invert(&fM1);
199        }
200    }
201private:
202    SkMatrix44 fM0, fM1;
203    typedef Matrix44Bench INHERITED;
204};
205
206class InvertTranslateMatrix44Bench : public Matrix44Bench {
207public:
208    InvertTranslateMatrix44Bench()
209        : INHERITED("inverttranslate")
210        , fM0(SkMatrix44::kIdentity_Constructor)
211        , fM1(SkMatrix44::kUninitialized_Constructor)
212    {
213        fM0.set(0, 3, 4.1);
214        fM0.set(1, 3, 8.1);
215        fM0.set(2, 3, -12.1);
216    }
217protected:
218    virtual void performTest() {
219        for (int i = 0; i < 10; ++i) {
220            fM0.invert(&fM1);
221        }
222    }
223private:
224    SkMatrix44 fM0, fM1;
225    typedef Matrix44Bench INHERITED;
226};
227
228class PostScaleMatrix44Bench : public Matrix44Bench {
229public:
230    PostScaleMatrix44Bench()
231        : INHERITED("postscale")
232        , fM0(SkMatrix44::kUninitialized_Constructor)
233    {
234        fX = fY = fZ = SkDoubleToMScalar(1.5);
235    }
236protected:
237    virtual void performTest() {
238        fM0.reset();
239        for (int i = 0; i < 10; ++i) {
240            fM0.postScale(fX, fY, fZ);
241        }
242    }
243private:
244    SkMatrix44 fM0;
245    SkMScalar  fX, fY, fZ;
246    typedef Matrix44Bench INHERITED;
247};
248
249class SetConcatMatrix44Bench : public Matrix44Bench {
250public:
251    SetConcatMatrix44Bench()
252        : INHERITED("setconcat")
253        , fM0(SkMatrix44::kUninitialized_Constructor)
254        , fM1(SkMatrix44::kUninitialized_Constructor)
255        , fM2(SkMatrix44::kUninitialized_Constructor)
256{
257        fX = fY = fZ = SkDoubleToMScalar(1.5);
258        fM1.setScale(fX, fY, fZ);
259        fM2.setTranslate(fX, fY, fZ);
260    }
261protected:
262    virtual void performTest() {
263        fM0.reset();    // just to normalize this test with prescale/postscale
264        for (int i = 0; i < 10; ++i) {
265            fM0.setConcat(fM1, fM2);
266        }
267    }
268private:
269    SkMatrix44 fM0, fM1, fM2;
270    SkMScalar  fX, fY, fZ;
271    typedef Matrix44Bench INHERITED;
272};
273
274class GetTypeMatrix44Bench : public Matrix44Bench {
275public:
276    GetTypeMatrix44Bench()
277        : INHERITED("gettype")
278        , fMatrix(SkMatrix44::kIdentity_Constructor)
279    {}
280protected:
281    // Putting random generation of the matrix inside performTest()
282    // would help us avoid anomalous runs, but takes up 25% or
283    // more of the function time.
284    virtual void performTest() {
285        for (int i = 0; i < 20; ++i) {
286            fMatrix.set(1, 2, 1);   // to invalidate the type-cache
287            fMatrix.getType();
288        }
289    }
290private:
291    SkMatrix44 fMatrix;
292    typedef Matrix44Bench INHERITED;
293};
294
295DEF_BENCH( return new SetIdentityMatrix44Bench(); )
296DEF_BENCH( return new EqualsMatrix44Bench(); )
297DEF_BENCH( return new PreScaleMatrix44Bench(); )
298DEF_BENCH( return new PostScaleMatrix44Bench(); )
299DEF_BENCH( return new InvertMatrix44Bench(); )
300DEF_BENCH( return new InvertAffineMatrix44Bench(); )
301DEF_BENCH( return new InvertScaleTranslateMatrix44Bench(); )
302DEF_BENCH( return new InvertTranslateMatrix44Bench(); )
303DEF_BENCH( return new SetConcatMatrix44Bench(); )
304DEF_BENCH( return new GetTypeMatrix44Bench(); )
305