blob: b4715ba2cfbdd528705c1e914aae27a79b141349 [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 */
reed@google.com3fb51872011-06-01 15:11:22 +00008#include "SkBenchmark.h"
9#include "SkMatrix.h"
tomhudson@google.com7b4e1072011-06-03 19:16:56 +000010#include "SkRandom.h"
reed@google.com3fb51872011-06-01 15:11:22 +000011#include "SkString.h"
12
13class MatrixBench : public SkBenchmark {
14 SkString fName;
15 enum { N = 100000 };
16public:
17 MatrixBench(void* param, const char name[]) : INHERITED(param) {
18 fName.printf("matrix_%s", name);
tomhudson@google.com9dc27132012-09-13 15:50:24 +000019 fIsRendering = false;
reed@google.com3fb51872011-06-01 15:11:22 +000020 }
21
22 virtual void performTest() = 0;
23
24protected:
reed@google.comcbefd7d2011-06-06 13:31:30 +000025 virtual int mulLoopCount() const { return 1; }
26
reed@google.com3fb51872011-06-01 15:11:22 +000027 virtual const char* onGetName() {
28 return fName.c_str();
29 }
30
31 virtual void onDraw(SkCanvas* canvas) {
tomhudson@google.comca529d32011-10-28 15:34:49 +000032 int n = SkBENCHLOOP(N * this->mulLoopCount());
reed@google.comcbefd7d2011-06-06 13:31:30 +000033 for (int i = 0; i < n; i++) {
reed@google.com3fb51872011-06-01 15:11:22 +000034 this->performTest();
35 }
36 }
37
38private:
39 typedef SkBenchmark INHERITED;
40};
41
42// we want to stop the compiler from eliminating code that it thinks is a no-op
43// so we have a non-static global we increment, hoping that will convince the
44// compiler to execute everything
45int gMatrixBench_NonStaticGlobal;
46
47#define always_do(pred) \
48 do { \
49 if (pred) { \
50 ++gMatrixBench_NonStaticGlobal; \
51 } \
52 } while (0)
53
54class EqualsMatrixBench : public MatrixBench {
55public:
56 EqualsMatrixBench(void* param) : INHERITED(param, "equals") {}
57protected:
58 virtual void performTest() {
59 SkMatrix m0, m1, m2;
tomhudson@google.com7b4e1072011-06-03 19:16:56 +000060
reed@google.com3fb51872011-06-01 15:11:22 +000061 m0.reset();
62 m1.reset();
63 m2.reset();
64 always_do(m0 == m1);
65 always_do(m1 == m2);
66 always_do(m2 == m0);
reed@google.com3fb51872011-06-01 15:11:22 +000067 }
68private:
69 typedef MatrixBench INHERITED;
70};
71
72class ScaleMatrixBench : public MatrixBench {
73public:
74 ScaleMatrixBench(void* param) : INHERITED(param, "scale") {
bungeman@google.com20809002011-06-08 19:38:53 +000075 fSX = fSY = SkFloatToScalar(1.5f);
reed@google.com3fb51872011-06-01 15:11:22 +000076 fM0.reset();
77 fM1.setScale(fSX, fSY);
78 fM2.setTranslate(fSX, fSY);
reed@google.com3fb51872011-06-01 15:11:22 +000079 }
80protected:
81 virtual void performTest() {
82 SkMatrix m;
83 m = fM0; m.preScale(fSX, fSY);
84 m = fM1; m.preScale(fSX, fSY);
85 m = fM2; m.preScale(fSX, fSY);
86 }
87private:
88 SkMatrix fM0, fM1, fM2;
89 SkScalar fSX, fSY;
90 typedef MatrixBench INHERITED;
91};
92
reed@google.come0dcde72011-06-06 13:20:29 +000093// having unknown values in our arrays can throw off the timing a lot, perhaps
94// handling NaN values is a lot slower. Anyway, this guy is just meant to put
95// reasonable values in our arrays.
96template <typename T> void init9(T array[9]) {
97 SkRandom rand;
98 for (int i = 0; i < 9; i++) {
99 array[i] = rand.nextSScalar1();
100 }
101}
102
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000103// Test the performance of setConcat() non-perspective case:
104// using floating point precision only.
105class FloatConcatMatrixBench : public MatrixBench {
106public:
reed@google.come0dcde72011-06-06 13:20:29 +0000107 FloatConcatMatrixBench(void* p) : INHERITED(p, "concat_floatfloat") {
108 init9(mya);
109 init9(myb);
110 init9(myr);
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000111 }
112protected:
reed@google.comcbefd7d2011-06-06 13:31:30 +0000113 virtual int mulLoopCount() const { return 4; }
114
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000115 static inline void muladdmul(float a, float b, float c, float d,
116 float* result) {
117 *result = a * b + c * d;
118 }
119 virtual void performTest() {
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000120 const float* a = mya;
121 const float* b = myb;
122 float* r = myr;
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000123 muladdmul(a[0], b[0], a[1], b[3], &r[0]);
124 muladdmul(a[0], b[1], a[1], b[4], &r[1]);
125 muladdmul(a[0], b[2], a[1], b[5], &r[2]);
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000126 r[2] += a[2];
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000127 muladdmul(a[3], b[0], a[4], b[3], &r[3]);
128 muladdmul(a[3], b[1], a[4], b[4], &r[4]);
129 muladdmul(a[3], b[2], a[4], b[5], &r[5]);
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000130 r[5] += a[5];
131 r[6] = r[7] = 0.0f;
132 r[8] = 1.0f;
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000133 }
134private:
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000135 float mya [9];
136 float myb [9];
137 float myr [9];
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000138 typedef MatrixBench INHERITED;
139};
140
141static inline float SkDoubleToFloat(double x) {
142 return static_cast<float>(x);
143}
144
145// Test the performance of setConcat() non-perspective case:
146// using floating point precision but casting up to float for
147// intermediate results during computations.
148class FloatDoubleConcatMatrixBench : public MatrixBench {
149public:
reed@google.come0dcde72011-06-06 13:20:29 +0000150 FloatDoubleConcatMatrixBench(void* p) : INHERITED(p, "concat_floatdouble") {
151 init9(mya);
152 init9(myb);
153 init9(myr);
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000154 }
155protected:
reed@google.comcbefd7d2011-06-06 13:31:30 +0000156 virtual int mulLoopCount() const { return 4; }
157
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000158 static inline void muladdmul(float a, float b, float c, float d,
159 float* result) {
160 *result = SkDoubleToFloat((double)a * b + (double)c * d);
161 }
162 virtual void performTest() {
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000163 const float* a = mya;
164 const float* b = myb;
165 float* r = myr;
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000166 muladdmul(a[0], b[0], a[1], b[3], &r[0]);
167 muladdmul(a[0], b[1], a[1], b[4], &r[1]);
168 muladdmul(a[0], b[2], a[1], b[5], &r[2]);
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000169 r[2] += a[2];
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000170 muladdmul(a[3], b[0], a[4], b[3], &r[3]);
171 muladdmul(a[3], b[1], a[4], b[4], &r[4]);
172 muladdmul(a[3], b[2], a[4], b[5], &r[5]);
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000173 r[5] += a[5];
174 r[6] = r[7] = 0.0f;
175 r[8] = 1.0f;
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000176 }
177private:
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000178 float mya [9];
179 float myb [9];
180 float myr [9];
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000181 typedef MatrixBench INHERITED;
182};
183
184// Test the performance of setConcat() non-perspective case:
185// using double precision only.
186class DoubleConcatMatrixBench : public MatrixBench {
187public:
reed@google.come0dcde72011-06-06 13:20:29 +0000188 DoubleConcatMatrixBench(void* p) : INHERITED(p, "concat_double") {
189 init9(mya);
190 init9(myb);
191 init9(myr);
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000192 }
193protected:
reed@google.comcbefd7d2011-06-06 13:31:30 +0000194 virtual int mulLoopCount() const { return 4; }
195
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000196 static inline void muladdmul(double a, double b, double c, double d,
197 double* result) {
198 *result = a * b + c * d;
199 }
200 virtual void performTest() {
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000201 const double* a = mya;
202 const double* b = myb;
203 double* r = myr;
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000204 muladdmul(a[0], b[0], a[1], b[3], &r[0]);
205 muladdmul(a[0], b[1], a[1], b[4], &r[1]);
206 muladdmul(a[0], b[2], a[1], b[5], &r[2]);
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000207 r[2] += a[2];
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000208 muladdmul(a[3], b[0], a[4], b[3], &r[3]);
209 muladdmul(a[3], b[1], a[4], b[4], &r[4]);
210 muladdmul(a[3], b[2], a[4], b[5], &r[5]);
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000211 r[5] += a[5];
212 r[6] = r[7] = 0.0;
213 r[8] = 1.0;
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000214 }
215private:
tomhudson@google.coma20416b2011-06-03 20:32:58 +0000216 double mya [9];
217 double myb [9];
218 double myr [9];
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000219 typedef MatrixBench INHERITED;
220};
221
tomhudson@google.com317d5402011-06-24 18:30:49 +0000222class GetTypeMatrixBench : public MatrixBench {
223public:
224 GetTypeMatrixBench(void* param)
225 : INHERITED(param, "gettype") {
bsalomon@google.com820e80a2011-10-24 21:09:40 +0000226 fArray[0] = (float) fRnd.nextS();
227 fArray[1] = (float) fRnd.nextS();
228 fArray[2] = (float) fRnd.nextS();
229 fArray[3] = (float) fRnd.nextS();
230 fArray[4] = (float) fRnd.nextS();
231 fArray[5] = (float) fRnd.nextS();
232 fArray[6] = (float) fRnd.nextS();
233 fArray[7] = (float) fRnd.nextS();
234 fArray[8] = (float) fRnd.nextS();
tomhudson@google.com317d5402011-06-24 18:30:49 +0000235 }
236protected:
237 // Putting random generation of the matrix inside performTest()
238 // would help us avoid anomalous runs, but takes up 25% or
239 // more of the function time.
240 virtual void performTest() {
241 fMatrix.setAll(fArray[0], fArray[1], fArray[2],
242 fArray[3], fArray[4], fArray[5],
243 fArray[6], fArray[7], fArray[8]);
244 always_do(fMatrix.getType());
245 fMatrix.dirtyMatrixTypeCache();
246 always_do(fMatrix.getType());
247 fMatrix.dirtyMatrixTypeCache();
248 always_do(fMatrix.getType());
249 fMatrix.dirtyMatrixTypeCache();
250 always_do(fMatrix.getType());
251 fMatrix.dirtyMatrixTypeCache();
252 always_do(fMatrix.getType());
253 fMatrix.dirtyMatrixTypeCache();
254 always_do(fMatrix.getType());
255 fMatrix.dirtyMatrixTypeCache();
256 always_do(fMatrix.getType());
257 fMatrix.dirtyMatrixTypeCache();
258 always_do(fMatrix.getType());
259 }
260private:
261 SkMatrix fMatrix;
262 float fArray[9];
263 SkRandom fRnd;
264 typedef MatrixBench INHERITED;
265};
266
tomhudson@google.com288ff332011-06-07 14:31:38 +0000267#ifdef SK_SCALAR_IS_FLOAT
268class ScaleTransMixedMatrixBench : public MatrixBench {
269 public:
270 ScaleTransMixedMatrixBench(void* p) : INHERITED(p, "scaletrans_mixed"), fCount (16) {
bsalomon@google.com3d3dfe02011-11-10 13:50:19 +0000271 fMatrix.setAll(fRandom.nextSScalar1(), fRandom.nextSScalar1(), fRandom.nextSScalar1(),
272 fRandom.nextSScalar1(), fRandom.nextSScalar1(), fRandom.nextSScalar1(),
273 fRandom.nextSScalar1(), fRandom.nextSScalar1(), fRandom.nextSScalar1());
tomhudson@google.com288ff332011-06-07 14:31:38 +0000274 int i;
tomhudson@google.comca529d32011-10-28 15:34:49 +0000275 for (i = 0; i < SkBENCHLOOP(fCount); i++) {
bsalomon@google.com820e80a2011-10-24 21:09:40 +0000276 fSrc[i].fX = fRandom.nextSScalar1();
277 fSrc[i].fY = fRandom.nextSScalar1();
278 fDst[i].fX = fRandom.nextSScalar1();
279 fDst[i].fY = fRandom.nextSScalar1();
tomhudson@google.com288ff332011-06-07 14:31:38 +0000280 }
281 }
282 protected:
283 virtual void performTest() {
284 SkPoint* dst = fDst;
285 const SkPoint* src = fSrc;
tomhudson@google.comca529d32011-10-28 15:34:49 +0000286 int count = SkBENCHLOOP(fCount);
tomhudson@google.com288ff332011-06-07 14:31:38 +0000287 float mx = fMatrix[SkMatrix::kMScaleX];
288 float my = fMatrix[SkMatrix::kMScaleY];
289 float tx = fMatrix[SkMatrix::kMTransX];
290 float ty = fMatrix[SkMatrix::kMTransY];
291 do {
292 dst->fY = SkScalarMulAdd(src->fY, my, ty);
293 dst->fX = SkScalarMulAdd(src->fX, mx, tx);
294 src += 1;
295 dst += 1;
296 } while (--count);
297 }
298 private:
299 SkMatrix fMatrix;
300 SkPoint fSrc [16];
301 SkPoint fDst [16];
302 int fCount;
303 SkRandom fRandom;
304 typedef MatrixBench INHERITED;
305};
tomhudson@google.com288ff332011-06-07 14:31:38 +0000306
307class ScaleTransDoubleMatrixBench : public MatrixBench {
308 public:
309 ScaleTransDoubleMatrixBench(void* p) : INHERITED(p, "scaletrans_double"), fCount (16) {
310 init9(fMatrix);
311 int i;
tomhudson@google.comca529d32011-10-28 15:34:49 +0000312 for (i = 0; i < SkBENCHLOOP(fCount); i++) {
bsalomon@google.com820e80a2011-10-24 21:09:40 +0000313 fSrc[i].fX = fRandom.nextSScalar1();
314 fSrc[i].fY = fRandom.nextSScalar1();
315 fDst[i].fX = fRandom.nextSScalar1();
316 fDst[i].fY = fRandom.nextSScalar1();
tomhudson@google.com288ff332011-06-07 14:31:38 +0000317 }
318 }
319 protected:
320 virtual void performTest() {
321 SkPoint* dst = fDst;
322 const SkPoint* src = fSrc;
tomhudson@google.comca529d32011-10-28 15:34:49 +0000323 int count = SkBENCHLOOP(fCount);
tomhudson@google.com288ff332011-06-07 14:31:38 +0000324 // As doubles, on Z600 Linux systems this is 2.5x as expensive as mixed mode
bsalomon@google.com820e80a2011-10-24 21:09:40 +0000325 float mx = (float) fMatrix[SkMatrix::kMScaleX];
326 float my = (float) fMatrix[SkMatrix::kMScaleY];
327 float tx = (float) fMatrix[SkMatrix::kMTransX];
328 float ty = (float) fMatrix[SkMatrix::kMTransY];
tomhudson@google.com288ff332011-06-07 14:31:38 +0000329 do {
330 dst->fY = src->fY * my + ty;
331 dst->fX = src->fX * mx + tx;
332 src += 1;
333 dst += 1;
334 } while (--count);
335 }
336 private:
337 double fMatrix [9];
338 SkPoint fSrc [16];
339 SkPoint fDst [16];
340 int fCount;
341 SkRandom fRandom;
342 typedef MatrixBench INHERITED;
343};
344#endif
345
junov@chromium.org6fc56992012-07-12 14:01:32 +0000346class InvertMapRectMatrixBench : public MatrixBench {
347public:
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000348 InvertMapRectMatrixBench(void* param, const char* name, int flags)
junov@chromium.org6fc56992012-07-12 14:01:32 +0000349 : INHERITED(param, name)
350 , fFlags(flags) {
351 fMatrix.reset();
352 fIteration = 0;
353 if (flags & kScale_Flag) {
354 fMatrix.postScale(SkFloatToScalar(1.5f), SkFloatToScalar(2.5f));
355 }
356 if (flags & kTranslate_Flag) {
357 fMatrix.postTranslate(SkFloatToScalar(1.5f), SkFloatToScalar(2.5f));
358 }
359 if (flags & kRotate_Flag) {
360 fMatrix.postRotate(SkFloatToScalar(45.0f));
361 }
362 if (flags & kPerspective_Flag) {
363 fMatrix.setPerspX(SkFloatToScalar(1.5f));
364 fMatrix.setPerspY(SkFloatToScalar(2.5f));
365 }
366 if (0 == (flags & kUncachedTypeMask_Flag)) {
367 fMatrix.getType();
368 }
369 }
370 enum Flag {
371 kScale_Flag = 0x01,
372 kTranslate_Flag = 0x02,
373 kRotate_Flag = 0x04,
374 kPerspective_Flag = 0x08,
375 kUncachedTypeMask_Flag = 0x10,
376 };
377protected:
378 virtual void performTest() {
379 if (fFlags & kUncachedTypeMask_Flag) {
380 // This will invalidate the typemask without
381 // changing the matrix.
382 fMatrix.setPerspX(fMatrix.getPerspX());
383 }
384 SkMatrix inv;
robertphillips@google.com31f8f732012-09-17 13:36:47 +0000385 bool invertible = fMatrix.invert(&inv);
junov@chromium.org6fc56992012-07-12 14:01:32 +0000386 SkASSERT(invertible);
387 SkRect transformedRect;
robertphillips@google.com31f8f732012-09-17 13:36:47 +0000388 // an arbitrary, small, non-zero rect to transform
389 SkRect srcRect = SkRect::MakeWH(SkIntToScalar(10), SkIntToScalar(10));
junov@chromium.org6fc56992012-07-12 14:01:32 +0000390 if (invertible) {
robertphillips@google.com31f8f732012-09-17 13:36:47 +0000391 inv.mapRect(&transformedRect, srcRect);
junov@chromium.org6fc56992012-07-12 14:01:32 +0000392 }
393 }
394private:
395 SkMatrix fMatrix;
junov@chromium.org6fc56992012-07-12 14:01:32 +0000396 int fFlags;
397 unsigned fIteration;
398 typedef MatrixBench INHERITED;
399};
tomhudson@google.com288ff332011-06-07 14:31:38 +0000400
401
402
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000403
reed@google.com3fb51872011-06-01 15:11:22 +0000404static SkBenchmark* M0(void* p) { return new EqualsMatrixBench(p); }
405static SkBenchmark* M1(void* p) { return new ScaleMatrixBench(p); }
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000406static SkBenchmark* M2(void* p) { return new FloatConcatMatrixBench(p); }
407static SkBenchmark* M3(void* p) { return new FloatDoubleConcatMatrixBench(p); }
408static SkBenchmark* M4(void* p) { return new DoubleConcatMatrixBench(p); }
tomhudson@google.com317d5402011-06-24 18:30:49 +0000409static SkBenchmark* M5(void* p) { return new GetTypeMatrixBench(p); }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000410static SkBenchmark* M6(void* p) {
411 return new InvertMapRectMatrixBench(p,
junov@chromium.org6fc56992012-07-12 14:01:32 +0000412 "invert_maprect_identity", 0);
413}
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000414static SkBenchmark* M7(void* p) {
415 return new InvertMapRectMatrixBench(p,
416 "invert_maprect_rectstaysrect",
junov@chromium.org6fc56992012-07-12 14:01:32 +0000417 InvertMapRectMatrixBench::kScale_Flag |
418 InvertMapRectMatrixBench::kTranslate_Flag);
419}
420static SkBenchmark* M8(void* p) {
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000421 return new InvertMapRectMatrixBench(p,
422 "invert_maprect_nonpersp",
junov@chromium.org6fc56992012-07-12 14:01:32 +0000423 InvertMapRectMatrixBench::kScale_Flag |
424 InvertMapRectMatrixBench::kRotate_Flag |
425 InvertMapRectMatrixBench::kTranslate_Flag);
426}
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000427static SkBenchmark* M9(void* p) {
428 return new InvertMapRectMatrixBench(p,
429 "invert_maprect_persp",
junov@chromium.org6fc56992012-07-12 14:01:32 +0000430 InvertMapRectMatrixBench::kPerspective_Flag);
431}
432static SkBenchmark* M10(void* p) {
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000433 return new InvertMapRectMatrixBench(p,
junov@chromium.org6fc56992012-07-12 14:01:32 +0000434 "invert_maprect_typemask_rectstaysrect",
435 InvertMapRectMatrixBench::kUncachedTypeMask_Flag |
436 InvertMapRectMatrixBench::kScale_Flag |
437 InvertMapRectMatrixBench::kTranslate_Flag);
438}
439static SkBenchmark* M11(void* p) {
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000440 return new InvertMapRectMatrixBench(p,
junov@chromium.org6fc56992012-07-12 14:01:32 +0000441 "invert_maprect_typemask_nonpersp",
442 InvertMapRectMatrixBench::kUncachedTypeMask_Flag |
443 InvertMapRectMatrixBench::kScale_Flag |
444 InvertMapRectMatrixBench::kRotate_Flag |
445 InvertMapRectMatrixBench::kTranslate_Flag);
446}
reed@google.com3fb51872011-06-01 15:11:22 +0000447
448static BenchRegistry gReg0(M0);
449static BenchRegistry gReg1(M1);
tomhudson@google.com7b4e1072011-06-03 19:16:56 +0000450static BenchRegistry gReg2(M2);
451static BenchRegistry gReg3(M3);
452static BenchRegistry gReg4(M4);
tomhudson@google.com317d5402011-06-24 18:30:49 +0000453static BenchRegistry gReg5(M5);
junov@chromium.org6fc56992012-07-12 14:01:32 +0000454static BenchRegistry gReg6(M6);
455static BenchRegistry gReg7(M7);
456static BenchRegistry gReg8(M8);
457static BenchRegistry gReg9(M9);
458static BenchRegistry gReg10(M10);
459static BenchRegistry gReg11(M11);
tomhudson@google.com288ff332011-06-07 14:31:38 +0000460
461#ifdef SK_SCALAR_IS_FLOAT
462static SkBenchmark* FlM0(void* p) { return new ScaleTransMixedMatrixBench(p); }
463static SkBenchmark* FlM1(void* p) { return new ScaleTransDoubleMatrixBench(p); }
464static BenchRegistry gFlReg5(FlM0);
465static BenchRegistry gFlReg6(FlM1);
466#endif