blob: 75736aa1432bb29ff166a93aeb185dad768f6478 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
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 */
tfarinaf168b862014-06-19 12:32:29 -07008#include "Benchmark.h"
reed@google.com3fb51872011-06-01 15:11:22 +00009#include "SkMatrix.h"
commit-bot@chromium.org5b2e2642013-09-03 19:08:14 +000010#include "SkMatrixUtils.h"
tomhudson@google.com7b4e1072011-06-03 19:16:56 +000011#include "SkRandom.h"
reed@google.com3fb51872011-06-01 15:11:22 +000012#include "SkString.h"
13
tfarinaf168b862014-06-19 12:32:29 -070014class MatrixBench : public Benchmark {
reed@google.com3fb51872011-06-01 15:11:22 +000015 SkString fName;
reed@google.com3fb51872011-06-01 15:11:22 +000016public:
mtklein@google.com410e6e82013-09-13 19:52:27 +000017 MatrixBench(const char name[]) {
reed@google.com3fb51872011-06-01 15:11:22 +000018 fName.printf("matrix_%s", name);
commit-bot@chromium.org644629c2013-11-21 06:21:58 +000019 }
20
mtklein36352bf2015-03-25 18:17:31 -070021 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +000022 return backend == kNonRendering_Backend;
reed@google.com3fb51872011-06-01 15:11:22 +000023 }
24
25 virtual void performTest() = 0;
26
27protected:
reed@google.comcbefd7d2011-06-06 13:31:30 +000028 virtual int mulLoopCount() const { return 1; }
29
mtkleinf0599002015-07-13 06:18:39 -070030 const char* onGetName() override {
reed@google.com3fb51872011-06-01 15:11:22 +000031 return fName.c_str();
32 }
33
mtkleinf0599002015-07-13 06:18:39 -070034 void onDraw(const int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +000035 for (int i = 0; i < loops; i++) {
reed@google.com3fb51872011-06-01 15:11:22 +000036 this->performTest();
37 }
38 }
39
40private:
tfarinaf168b862014-06-19 12:32:29 -070041 typedef Benchmark INHERITED;
reed@google.com3fb51872011-06-01 15:11:22 +000042};
43
reed@google.com3fb51872011-06-01 15:11:22 +000044
45class EqualsMatrixBench : public MatrixBench {
46public:
mtklein@google.com410e6e82013-09-13 19:52:27 +000047 EqualsMatrixBench() : INHERITED("equals") {}
reed@google.com3fb51872011-06-01 15:11:22 +000048protected:
mtkleinf0599002015-07-13 06:18:39 -070049 void performTest() override {
reed@google.com3fb51872011-06-01 15:11:22 +000050 SkMatrix m0, m1, m2;
tomhudson@google.com7b4e1072011-06-03 19:16:56 +000051
reed@google.com3fb51872011-06-01 15:11:22 +000052 m0.reset();
53 m1.reset();
54 m2.reset();
mtkleincf44feb2014-06-02 18:22:12 -070055
56 // xor into a volatile prevents these comparisons from being optimized away.
57 volatile bool junk = false;
58 junk ^= (m0 == m1);
59 junk ^= (m1 == m2);
60 junk ^= (m2 == m0);
reed@google.com3fb51872011-06-01 15:11:22 +000061 }
62private:
63 typedef MatrixBench INHERITED;
64};
65
66class ScaleMatrixBench : public MatrixBench {
67public:
mtklein@google.com410e6e82013-09-13 19:52:27 +000068 ScaleMatrixBench() : INHERITED("scale") {
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +000069 fSX = fSY = 1.5f;
reed@google.com3fb51872011-06-01 15:11:22 +000070 fM0.reset();
71 fM1.setScale(fSX, fSY);
72 fM2.setTranslate(fSX, fSY);
reed@google.com3fb51872011-06-01 15:11:22 +000073 }
74protected:
mtkleinf0599002015-07-13 06:18:39 -070075 void performTest() override {
reed@google.com3fb51872011-06-01 15:11:22 +000076 SkMatrix m;
77 m = fM0; m.preScale(fSX, fSY);
78 m = fM1; m.preScale(fSX, fSY);
79 m = fM2; m.preScale(fSX, fSY);
80 }
81private:
82 SkMatrix fM0, fM1, fM2;
83 SkScalar fSX, fSY;
84 typedef MatrixBench INHERITED;
85};
86
reed@google.come0dcde72011-06-06 13:20:29 +000087// having unknown values in our arrays can throw off the timing a lot, perhaps
88// handling NaN values is a lot slower. Anyway, this guy is just meant to put
89// reasonable values in our arrays.
90template <typename T> void init9(T array[9]) {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +000091 SkRandom rand;
reed@google.come0dcde72011-06-06 13:20:29 +000092 for (int i = 0; i < 9; i++) {
93 array[i] = rand.nextSScalar1();
94 }
95}
96
tomhudson@google.com317d5402011-06-24 18:30:49 +000097class GetTypeMatrixBench : public MatrixBench {
98public:
mtklein@google.com410e6e82013-09-13 19:52:27 +000099 GetTypeMatrixBench()
100 : INHERITED("gettype") {
bsalomon@google.com820e80a2011-10-24 21:09:40 +0000101 fArray[0] = (float) fRnd.nextS();
102 fArray[1] = (float) fRnd.nextS();
103 fArray[2] = (float) fRnd.nextS();
104 fArray[3] = (float) fRnd.nextS();
105 fArray[4] = (float) fRnd.nextS();
106 fArray[5] = (float) fRnd.nextS();
107 fArray[6] = (float) fRnd.nextS();
108 fArray[7] = (float) fRnd.nextS();
109 fArray[8] = (float) fRnd.nextS();
tomhudson@google.com317d5402011-06-24 18:30:49 +0000110 }
111protected:
112 // Putting random generation of the matrix inside performTest()
113 // would help us avoid anomalous runs, but takes up 25% or
114 // more of the function time.
mtkleinf0599002015-07-13 06:18:39 -0700115 void performTest() override {
tomhudson@google.com317d5402011-06-24 18:30:49 +0000116 fMatrix.setAll(fArray[0], fArray[1], fArray[2],
117 fArray[3], fArray[4], fArray[5],
118 fArray[6], fArray[7], fArray[8]);
mtkleincf44feb2014-06-02 18:22:12 -0700119 // xoring into a volatile prevents the compiler from optimizing these away
120 volatile int junk = 0;
121 junk ^= (fMatrix.getType());
tomhudson@google.com317d5402011-06-24 18:30:49 +0000122 fMatrix.dirtyMatrixTypeCache();
mtkleincf44feb2014-06-02 18:22:12 -0700123 junk ^= (fMatrix.getType());
tomhudson@google.com317d5402011-06-24 18:30:49 +0000124 fMatrix.dirtyMatrixTypeCache();
mtkleincf44feb2014-06-02 18:22:12 -0700125 junk ^= (fMatrix.getType());
tomhudson@google.com317d5402011-06-24 18:30:49 +0000126 fMatrix.dirtyMatrixTypeCache();
mtkleincf44feb2014-06-02 18:22:12 -0700127 junk ^= (fMatrix.getType());
tomhudson@google.com317d5402011-06-24 18:30:49 +0000128 fMatrix.dirtyMatrixTypeCache();
mtkleincf44feb2014-06-02 18:22:12 -0700129 junk ^= (fMatrix.getType());
tomhudson@google.com317d5402011-06-24 18:30:49 +0000130 fMatrix.dirtyMatrixTypeCache();
mtkleincf44feb2014-06-02 18:22:12 -0700131 junk ^= (fMatrix.getType());
tomhudson@google.com317d5402011-06-24 18:30:49 +0000132 fMatrix.dirtyMatrixTypeCache();
mtkleincf44feb2014-06-02 18:22:12 -0700133 junk ^= (fMatrix.getType());
tomhudson@google.com317d5402011-06-24 18:30:49 +0000134 fMatrix.dirtyMatrixTypeCache();
mtkleincf44feb2014-06-02 18:22:12 -0700135 junk ^= (fMatrix.getType());
tomhudson@google.com317d5402011-06-24 18:30:49 +0000136 }
137private:
138 SkMatrix fMatrix;
139 float fArray[9];
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000140 SkRandom fRnd;
tomhudson@google.com317d5402011-06-24 18:30:49 +0000141 typedef MatrixBench INHERITED;
142};
143
commit-bot@chromium.org5b2e2642013-09-03 19:08:14 +0000144class DecomposeMatrixBench : public MatrixBench {
145public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000146 DecomposeMatrixBench() : INHERITED("decompose") {}
commit-bot@chromium.org5b2e2642013-09-03 19:08:14 +0000147
148protected:
mtkleinf0599002015-07-13 06:18:39 -0700149 void onPreDraw() override {
commit-bot@chromium.org5b2e2642013-09-03 19:08:14 +0000150 for (int i = 0; i < 10; ++i) {
151 SkScalar rot0 = (fRandom.nextBool()) ? fRandom.nextRangeF(-180, 180) : 0.0f;
152 SkScalar sx = fRandom.nextRangeF(-3000.f, 3000.f);
153 SkScalar sy = (fRandom.nextBool()) ? fRandom.nextRangeF(-3000.f, 3000.f) : sx;
154 SkScalar rot1 = fRandom.nextRangeF(-180, 180);
155 fMatrix[i].setRotate(rot0);
156 fMatrix[i].postScale(sx, sy);
157 fMatrix[i].postRotate(rot1);
158 }
159 }
mtkleinf0599002015-07-13 06:18:39 -0700160 void performTest() override {
commit-bot@chromium.org5b2e2642013-09-03 19:08:14 +0000161 SkPoint rotation1, scale, rotation2;
162 for (int i = 0; i < 10; ++i) {
163 (void) SkDecomposeUpper2x2(fMatrix[i], &rotation1, &scale, &rotation2);
164 }
165 }
166private:
167 SkMatrix fMatrix[10];
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000168 SkRandom fRandom;
commit-bot@chromium.org5b2e2642013-09-03 19:08:14 +0000169 typedef MatrixBench INHERITED;
170};
171
junov@chromium.org6fc56992012-07-12 14:01:32 +0000172class InvertMapRectMatrixBench : public MatrixBench {
173public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000174 InvertMapRectMatrixBench(const char* name, int flags)
175 : INHERITED(name)
junov@chromium.org6fc56992012-07-12 14:01:32 +0000176 , fFlags(flags) {
177 fMatrix.reset();
178 fIteration = 0;
179 if (flags & kScale_Flag) {
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +0000180 fMatrix.postScale(1.5f, 2.5f);
junov@chromium.org6fc56992012-07-12 14:01:32 +0000181 }
182 if (flags & kTranslate_Flag) {
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +0000183 fMatrix.postTranslate(1.5f, 2.5f);
junov@chromium.org6fc56992012-07-12 14:01:32 +0000184 }
185 if (flags & kRotate_Flag) {
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +0000186 fMatrix.postRotate(45.0f);
junov@chromium.org6fc56992012-07-12 14:01:32 +0000187 }
188 if (flags & kPerspective_Flag) {
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +0000189 fMatrix.setPerspX(1.5f);
190 fMatrix.setPerspY(2.5f);
junov@chromium.org6fc56992012-07-12 14:01:32 +0000191 }
192 if (0 == (flags & kUncachedTypeMask_Flag)) {
193 fMatrix.getType();
194 }
195 }
196 enum Flag {
197 kScale_Flag = 0x01,
198 kTranslate_Flag = 0x02,
199 kRotate_Flag = 0x04,
200 kPerspective_Flag = 0x08,
201 kUncachedTypeMask_Flag = 0x10,
202 };
203protected:
mtkleinf0599002015-07-13 06:18:39 -0700204 void performTest() override {
junov@chromium.org6fc56992012-07-12 14:01:32 +0000205 if (fFlags & kUncachedTypeMask_Flag) {
206 // This will invalidate the typemask without
207 // changing the matrix.
208 fMatrix.setPerspX(fMatrix.getPerspX());
209 }
210 SkMatrix inv;
robertphillips@google.com31f8f732012-09-17 13:36:47 +0000211 bool invertible = fMatrix.invert(&inv);
junov@chromium.org6fc56992012-07-12 14:01:32 +0000212 SkASSERT(invertible);
213 SkRect transformedRect;
robertphillips@google.com31f8f732012-09-17 13:36:47 +0000214 // an arbitrary, small, non-zero rect to transform
215 SkRect srcRect = SkRect::MakeWH(SkIntToScalar(10), SkIntToScalar(10));
junov@chromium.org6fc56992012-07-12 14:01:32 +0000216 if (invertible) {
robertphillips@google.com31f8f732012-09-17 13:36:47 +0000217 inv.mapRect(&transformedRect, srcRect);
junov@chromium.org6fc56992012-07-12 14:01:32 +0000218 }
219 }
220private:
221 SkMatrix fMatrix;
junov@chromium.org6fc56992012-07-12 14:01:32 +0000222 int fFlags;
223 unsigned fIteration;
224 typedef MatrixBench INHERITED;
225};
tomhudson@google.com288ff332011-06-07 14:31:38 +0000226
reed@google.com82bf8bb2013-01-04 14:04:08 +0000227///////////////////////////////////////////////////////////////////////////////
tomhudson@google.com288ff332011-06-07 14:31:38 +0000228
mtklein@google.com410e6e82013-09-13 19:52:27 +0000229DEF_BENCH( return new EqualsMatrixBench(); )
230DEF_BENCH( return new ScaleMatrixBench(); )
mtklein@google.com410e6e82013-09-13 19:52:27 +0000231DEF_BENCH( return new GetTypeMatrixBench(); )
232DEF_BENCH( return new DecomposeMatrixBench(); )
commit-bot@chromium.org5b2e2642013-09-03 19:08:14 +0000233
mtklein@google.com410e6e82013-09-13 19:52:27 +0000234DEF_BENCH( return new InvertMapRectMatrixBench("invert_maprect_identity", 0); )
tomhudson@google.com288ff332011-06-07 14:31:38 +0000235
mtklein@google.com410e6e82013-09-13 19:52:27 +0000236DEF_BENCH(return new InvertMapRectMatrixBench(
reed@google.com90533be2013-01-04 15:46:42 +0000237 "invert_maprect_rectstaysrect",
238 InvertMapRectMatrixBench::kScale_Flag |
239 InvertMapRectMatrixBench::kTranslate_Flag); )
240
mtklein@google.com410e6e82013-09-13 19:52:27 +0000241DEF_BENCH(return new InvertMapRectMatrixBench(
reed@google.com90533be2013-01-04 15:46:42 +0000242 "invert_maprect_translate",
243 InvertMapRectMatrixBench::kTranslate_Flag); )
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000244
mtklein@google.com410e6e82013-09-13 19:52:27 +0000245DEF_BENCH(return new InvertMapRectMatrixBench(
reed@google.com82bf8bb2013-01-04 14:04:08 +0000246 "invert_maprect_nonpersp",
247 InvertMapRectMatrixBench::kScale_Flag |
248 InvertMapRectMatrixBench::kRotate_Flag |
249 InvertMapRectMatrixBench::kTranslate_Flag); )
reed@google.com3fb51872011-06-01 15:11:22 +0000250
mtklein@google.com410e6e82013-09-13 19:52:27 +0000251DEF_BENCH( return new InvertMapRectMatrixBench(
reed@google.com82bf8bb2013-01-04 14:04:08 +0000252 "invert_maprect_persp",
253 InvertMapRectMatrixBench::kPerspective_Flag); )
tomhudson@google.com288ff332011-06-07 14:31:38 +0000254
mtklein@google.com410e6e82013-09-13 19:52:27 +0000255DEF_BENCH( return new InvertMapRectMatrixBench(
reed@google.com82bf8bb2013-01-04 14:04:08 +0000256 "invert_maprect_typemask_rectstaysrect",
257 InvertMapRectMatrixBench::kUncachedTypeMask_Flag |
258 InvertMapRectMatrixBench::kScale_Flag |
259 InvertMapRectMatrixBench::kTranslate_Flag); )
260
mtklein@google.com410e6e82013-09-13 19:52:27 +0000261DEF_BENCH( return new InvertMapRectMatrixBench(
reed@google.com82bf8bb2013-01-04 14:04:08 +0000262 "invert_maprect_typemask_nonpersp",
263 InvertMapRectMatrixBench::kUncachedTypeMask_Flag |
264 InvertMapRectMatrixBench::kScale_Flag |
265 InvertMapRectMatrixBench::kRotate_Flag |
266 InvertMapRectMatrixBench::kTranslate_Flag); )
267
reed80106322015-03-23 08:15:14 -0700268///////////////////////////////////////////////////////////////////////////////
269
reedd8b34c22015-03-27 14:00:41 -0700270static SkMatrix make_trans() { return SkMatrix::MakeTrans(2, 3); }
reed80106322015-03-23 08:15:14 -0700271static SkMatrix make_scale() { SkMatrix m(make_trans()); m.postScale(1.5f, 0.5f); return m; }
272static SkMatrix make_afine() { SkMatrix m(make_trans()); m.postRotate(15); return m; }
273
274class MapPointsMatrixBench : public MatrixBench {
275protected:
276 SkMatrix fM;
277 enum {
278 N = 32
279 };
280 SkPoint fSrc[N], fDst[N];
reed80106322015-03-23 08:15:14 -0700281public:
reed7da19012015-03-29 11:58:48 -0700282 MapPointsMatrixBench(const char name[], const SkMatrix& m)
283 : MatrixBench(name), fM(m)
reed80106322015-03-23 08:15:14 -0700284 {
285 SkRandom rand;
286 for (int i = 0; i < N; ++i) {
287 fSrc[i].set(rand.nextSScalar1(), rand.nextSScalar1());
288 }
289 }
290
mtklein36352bf2015-03-25 18:17:31 -0700291 void performTest() override {
reed7da19012015-03-29 11:58:48 -0700292 for (int i = 0; i < 1000000; ++i) {
293 fM.mapPoints(fDst, fSrc, N);
reed80106322015-03-23 08:15:14 -0700294 }
295 }
296};
reed7da19012015-03-29 11:58:48 -0700297DEF_BENCH( return new MapPointsMatrixBench("mappoints_identity", SkMatrix::I()); )
298DEF_BENCH( return new MapPointsMatrixBench("mappoints_trans", make_trans()); )
299DEF_BENCH( return new MapPointsMatrixBench("mappoints_scale", make_scale()); )
300DEF_BENCH( return new MapPointsMatrixBench("mappoints_affine", make_afine()); )
reed80106322015-03-23 08:15:14 -0700301