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 "bench/Benchmark.h" 9 #include "include/core/SkMatrix44.h" 10 #include "include/core/SkString.h" 11 #include "include/core/SkM44.h" 12 #include "include/utils/SkRandom.h" 13 14 class Matrix44Bench : public Benchmark { 15 SkString fName; 16 public: Matrix44Bench(const char name[])17 Matrix44Bench(const char name[]) { 18 fName.printf("matrix44_%s", name); 19 } 20 isSuitableFor(Backend backend)21 bool isSuitableFor(Backend backend) override { 22 return backend == kNonRendering_Backend; 23 } 24 25 virtual void performTest() = 0; 26 27 protected: mulLoopCount() const28 virtual int mulLoopCount() const { return 1; } 29 onGetName()30 const char* onGetName() override { 31 return fName.c_str(); 32 } 33 onDraw(int loops,SkCanvas *)34 void onDraw(int loops, SkCanvas*) override { 35 for (int i = 0; i < loops; i++) { 36 this->performTest(); 37 } 38 } 39 40 private: 41 typedef Benchmark INHERITED; 42 }; 43 44 class EqualsMatrix44Bench : public Matrix44Bench { 45 public: EqualsMatrix44Bench()46 EqualsMatrix44Bench() 47 : INHERITED("equals") 48 { 49 fM1.set(0, 0, 0); 50 fM2.set(3, 3, 0); 51 } 52 protected: performTest()53 void performTest() override { 54 for (int i = 0; i < 10; ++i) { 55 (void) (fM0 == fM1); 56 (void) (fM1 == fM2); 57 (void) (fM2 == fM0); 58 } 59 } 60 private: 61 SkMatrix44 fM0, fM1, fM2; 62 typedef Matrix44Bench INHERITED; 63 }; 64 65 class SetIdentityMatrix44Bench : public Matrix44Bench { 66 public: SetIdentityMatrix44Bench()67 SetIdentityMatrix44Bench() 68 : INHERITED("setidentity") 69 { 70 double rowMajor[16] = 71 { 1, 2, 3, 4, 72 5, 6, 7, 8, 73 9, 10, 11, 12, 74 13, 14, 15, 16}; 75 mat.setRowMajord(rowMajor); 76 } 77 protected: performTest()78 void performTest() override { 79 for (int i = 0; i < 10; ++i) { 80 mat.setIdentity(); 81 } 82 } 83 private: 84 SkMatrix44 mat; 85 typedef Matrix44Bench INHERITED; 86 }; 87 88 class PreScaleMatrix44Bench : public Matrix44Bench { 89 public: PreScaleMatrix44Bench()90 PreScaleMatrix44Bench() 91 : INHERITED("prescale") 92 { 93 fX = fY = fZ = 1.5f; 94 } 95 protected: performTest()96 void performTest() override { 97 fM0.reset(); 98 for (int i = 0; i < 10; ++i) { 99 fM0.preScale(fX, fY, fZ); 100 } 101 } 102 private: 103 SkMatrix44 fM0; 104 SkScalar fX, fY, fZ; 105 typedef Matrix44Bench INHERITED; 106 }; 107 108 class InvertMatrix44Bench : public Matrix44Bench { 109 public: InvertMatrix44Bench()110 InvertMatrix44Bench() 111 : INHERITED("invert") 112 { 113 fM0.setDouble(0, 0, -1.1); 114 fM0.setDouble(0, 1, 2.1); 115 fM0.setDouble(0, 2, -3.1); 116 fM0.setDouble(0, 3, 4.1); 117 fM0.setDouble(1, 0, 5.1); 118 fM0.setDouble(1, 1, -6.1); 119 fM0.setDouble(1, 2, 7.1); 120 fM0.setDouble(1, 3, 8.1); 121 fM0.setDouble(2, 0, -9.1); 122 fM0.setDouble(2, 1, 10.1); 123 fM0.setDouble(2, 2, 11.1); 124 fM0.setDouble(2, 3, -12.1); 125 fM0.setDouble(3, 0, -13.1); 126 fM0.setDouble(3, 1, 14.1); 127 fM0.setDouble(3, 2, -15.1); 128 fM0.setDouble(3, 3, 16.1); 129 } 130 protected: performTest()131 void performTest() override { 132 for (int i = 0; i < 10; ++i) { 133 fM0.invert(&fM1); 134 } 135 } 136 private: 137 SkMatrix44 fM0, fM1; 138 typedef Matrix44Bench INHERITED; 139 }; 140 141 class InvertAffineMatrix44Bench : public Matrix44Bench { 142 public: InvertAffineMatrix44Bench()143 InvertAffineMatrix44Bench() 144 : INHERITED("invertaffine") 145 { 146 fM0.setDouble(0, 0, -1.1); 147 fM0.setDouble(0, 1, 2.1); 148 fM0.setDouble(0, 2, -3.1); 149 fM0.setDouble(0, 3, 4.1); 150 fM0.setDouble(1, 0, 5.1); 151 fM0.setDouble(1, 1, -6.1); 152 fM0.setDouble(1, 2, 7.1); 153 fM0.setDouble(1, 3, 8.1); 154 fM0.setDouble(2, 0, -9.1); 155 fM0.setDouble(2, 1, 10.1); 156 fM0.setDouble(2, 2, 11.1); 157 fM0.setDouble(2, 3, -12.1); 158 // bottom row (perspective component) remains (0, 0, 0, 1). 159 } 160 protected: performTest()161 void performTest() override { 162 for (int i = 0; i < 10; ++i) { 163 fM0.invert(&fM1); 164 } 165 } 166 private: 167 SkMatrix44 fM0, fM1; 168 typedef Matrix44Bench INHERITED; 169 }; 170 171 class InvertScaleTranslateMatrix44Bench : public Matrix44Bench { 172 public: InvertScaleTranslateMatrix44Bench()173 InvertScaleTranslateMatrix44Bench() 174 : INHERITED("invertscaletranslate") 175 { 176 fM0.setDouble(0, 0, -1.1); 177 fM0.setDouble(0, 3, 4.1); 178 179 fM0.setDouble(1, 1, -6.1); 180 fM0.setDouble(1, 3, 8.1); 181 182 fM0.setDouble(2, 2, 11.1); 183 fM0.setDouble(2, 3, -12.1); 184 } 185 protected: performTest()186 void performTest() override { 187 for (int i = 0; i < 10; ++i) { 188 fM0.invert(&fM1); 189 } 190 } 191 private: 192 SkMatrix44 fM0, fM1; 193 typedef Matrix44Bench INHERITED; 194 }; 195 196 class InvertTranslateMatrix44Bench : public Matrix44Bench { 197 public: InvertTranslateMatrix44Bench()198 InvertTranslateMatrix44Bench() 199 : INHERITED("inverttranslate") 200 { 201 fM0.setDouble(0, 3, 4.1); 202 fM0.setDouble(1, 3, 8.1); 203 fM0.setDouble(2, 3, -12.1); 204 } 205 protected: performTest()206 void performTest() override { 207 for (int i = 0; i < 10; ++i) { 208 fM0.invert(&fM1); 209 } 210 } 211 private: 212 SkMatrix44 fM0, fM1; 213 typedef Matrix44Bench INHERITED; 214 }; 215 216 class PostScaleMatrix44Bench : public Matrix44Bench { 217 public: PostScaleMatrix44Bench()218 PostScaleMatrix44Bench() 219 : INHERITED("postscale") 220 { 221 fX = fY = fZ = 1.5f; 222 } 223 protected: performTest()224 void performTest() override { 225 fM0.reset(); 226 for (int i = 0; i < 10; ++i) { 227 fM0.postScale(fX, fY, fZ); 228 } 229 } 230 private: 231 SkMatrix44 fM0; 232 SkScalar fX, fY, fZ; 233 typedef Matrix44Bench INHERITED; 234 }; 235 236 class SetConcatMatrix44Bench : public Matrix44Bench { 237 public: 238 // SkMatrix44::setConcat() has a fast path for matrices that are at most scale+translate. SetConcatMatrix44Bench(bool fastPath)239 SetConcatMatrix44Bench(bool fastPath) 240 : INHERITED(fastPath ? "setconcat_fast" : "setconcat_general") 241 { 242 if (fastPath) { 243 const SkScalar v = 1.5f; 244 fM1.setScale(v,v,v); 245 fM2.setTranslate(v,v,v); 246 } else { 247 SkRandom rand; 248 for (int x = 0; x < 4; x++) { 249 for (int y = 0; y < 4; y++) { 250 fM1.setFloat(x,y, rand.nextF()); 251 fM2.setFloat(x,y, rand.nextF()); 252 }} 253 } 254 } 255 protected: performTest()256 void performTest() override { 257 fM0.reset(); // just to normalize this test with prescale/postscale 258 for (int i = 0; i < 10000; ++i) { 259 fM0.setConcat(fM1, fM2); 260 } 261 } 262 private: 263 SkMatrix44 fM0, fM1, fM2; 264 typedef Matrix44Bench INHERITED; 265 }; 266 267 class GetTypeMatrix44Bench : public Matrix44Bench { 268 public: GetTypeMatrix44Bench()269 GetTypeMatrix44Bench() 270 : INHERITED("gettype") 271 {} 272 protected: 273 // Putting random generation of the matrix inside performTest() 274 // would help us avoid anomalous runs, but takes up 25% or 275 // more of the function time. performTest()276 void performTest() override { 277 for (int i = 0; i < 20; ++i) { 278 fMatrix.set(1, 2, 1); // to invalidate the type-cache 279 fMatrix.getType(); 280 } 281 } 282 private: 283 SkMatrix44 fMatrix; 284 typedef Matrix44Bench INHERITED; 285 }; 286 287 DEF_BENCH( return new SetIdentityMatrix44Bench(); ) 288 DEF_BENCH( return new EqualsMatrix44Bench(); ) 289 DEF_BENCH( return new PreScaleMatrix44Bench(); ) 290 DEF_BENCH( return new PostScaleMatrix44Bench(); ) 291 DEF_BENCH( return new InvertMatrix44Bench(); ) 292 DEF_BENCH( return new InvertAffineMatrix44Bench(); ) 293 DEF_BENCH( return new InvertScaleTranslateMatrix44Bench(); ) 294 DEF_BENCH( return new InvertTranslateMatrix44Bench(); ) 295 DEF_BENCH( return new SetConcatMatrix44Bench(true); ) 296 DEF_BENCH( return new SetConcatMatrix44Bench(false); ) 297 DEF_BENCH( return new GetTypeMatrix44Bench(); ) 298 299 ///////////////////////////////////////////////////////////////////////////////////////////////// 300 301 class M4Bench : public Benchmark { 302 SkString fName; 303 public: M4Bench(const char name[])304 M4Bench(const char name[]) { 305 fName.printf("m4_%s", name); 306 307 SkRandom rand; 308 float value[32]; 309 for (auto& v : value) { 310 v = rand.nextF(); 311 } 312 fM1.setColMajor(value + 0); 313 fM2.setColMajor(value + 16); 314 } 315 isSuitableFor(Backend backend)316 bool isSuitableFor(Backend backend) override { 317 return backend == kNonRendering_Backend; 318 } 319 320 virtual void performTest() = 0; 321 322 protected: 323 SkM44 fM0, fM1, fM2; 324 mulLoopCount() const325 virtual int mulLoopCount() const { return 1; } 326 onGetName()327 const char* onGetName() override { 328 return fName.c_str(); 329 } 330 onDraw(int loops,SkCanvas *)331 void onDraw(int loops, SkCanvas*) override { 332 for (int i = 0; i < loops; i++) { 333 this->performTest(); 334 } 335 } 336 337 private: 338 typedef Benchmark INHERITED; 339 }; 340 341 class M4NEQ : public M4Bench { 342 public: M4NEQ()343 M4NEQ() : INHERITED("neq") {} 344 protected: performTest()345 void performTest() override { 346 for (int i = 0; i < 10000; ++i) { 347 fEQ = (fM2 == fM1); // should always be false 348 } 349 } 350 private: 351 bool fEQ; 352 typedef M4Bench INHERITED; 353 }; 354 355 class M4EQ : public M4Bench { 356 public: M4EQ()357 M4EQ() : INHERITED("eq") {} 358 protected: performTest()359 void performTest() override { 360 fM2 = fM1; 361 for (int i = 0; i < 10000; ++i) { 362 fEQ = (fM2 == fM1); // should always be true 363 } 364 } 365 private: 366 bool fEQ; 367 typedef M4Bench INHERITED; 368 }; 369 370 class M4Concat : public M4Bench { 371 public: M4Concat()372 M4Concat() : INHERITED("op_concat") {} 373 protected: performTest()374 void performTest() override { 375 for (int i = 0; i < 10000; ++i) { 376 fM0 = SkM44(fM1, fM2); 377 } 378 } 379 private: 380 typedef M4Bench INHERITED; 381 }; 382 383 class M4SetConcat : public M4Bench { 384 public: M4SetConcat()385 M4SetConcat() : INHERITED("set_concat") {} 386 protected: performTest()387 void performTest() override { 388 for (int i = 0; i < 10000; ++i) { 389 fM0.setConcat(fM1, fM2); 390 } 391 } 392 private: 393 typedef M4Bench INHERITED; 394 }; 395 396 DEF_BENCH( return new M4EQ(); ) 397 DEF_BENCH( return new M4NEQ(); ) 398 DEF_BENCH( return new M4Concat(); ) 399 DEF_BENCH( return new M4SetConcat(); ) 400 401 class M4_map4 : public M4Bench { 402 public: M4_map4()403 M4_map4() : INHERITED("map4") {} 404 protected: performTest()405 void performTest() override { 406 SkV4 v = {1, 2, 3, 4}; 407 for (int i = 0; i < 100000; ++i) { 408 fV = fM0 * v; 409 } 410 } 411 private: 412 SkV4 fV; 413 typedef M4Bench INHERITED; 414 }; 415 DEF_BENCH( return new M4_map4(); ) 416 417 class M4_map2 : public M4Bench { 418 public: M4_map2()419 M4_map2() : INHERITED("map2") {} 420 protected: performTest()421 void performTest() override { 422 SkMatrix m; 423 m.setRotate(1); 424 for (int i = 0; i < 100000; ++i) { 425 fV = m.mapXY(5, 6); 426 } 427 } 428 private: 429 SkPoint fV; 430 typedef M4Bench INHERITED; 431 }; 432 DEF_BENCH( return new M4_map2(); ) 433