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/SkM44.h" 10 #include "include/core/SkString.h" 11 #include "include/utils/SkRandom.h" 12 #include "src/core/SkMatrixPriv.h" 13 14 class M4Bench : public Benchmark { 15 SkString fName; 16 public: M4Bench(const char name[])17 M4Bench(const char name[]) { 18 fName.printf("m4_%s", name); 19 20 SkRandom rand; 21 float value[32]; 22 for (auto& v : value) { 23 v = rand.nextF(); 24 } 25 fM1 = SkM44::ColMajor(value + 0); 26 fM2 = SkM44::ColMajor(value + 16); 27 } 28 isSuitableFor(Backend backend)29 bool isSuitableFor(Backend backend) override { 30 return backend == kNonRendering_Backend; 31 } 32 33 virtual void performTest() = 0; 34 35 protected: 36 SkM44 fM0, fM1, fM2; 37 mulLoopCount() const38 virtual int mulLoopCount() const { return 1; } 39 onGetName()40 const char* onGetName() override { 41 return fName.c_str(); 42 } 43 onDraw(int loops,SkCanvas *)44 void onDraw(int loops, SkCanvas*) override { 45 for (int i = 0; i < loops; i++) { 46 this->performTest(); 47 } 48 } 49 50 private: 51 using INHERITED = Benchmark; 52 }; 53 54 class M4NEQ : public M4Bench { 55 public: M4NEQ()56 M4NEQ() : INHERITED("neq") {} 57 protected: performTest()58 void performTest() override { 59 for (int i = 0; i < 10000; ++i) { 60 fEQ = (fM2 == fM1); // should always be false 61 } 62 } 63 private: 64 bool fEQ; 65 using INHERITED = M4Bench; 66 }; 67 68 class M4EQ : public M4Bench { 69 public: M4EQ()70 M4EQ() : INHERITED("eq") {} 71 protected: performTest()72 void performTest() override { 73 fM2 = fM1; 74 for (int i = 0; i < 10000; ++i) { 75 fEQ = (fM2 == fM1); // should always be true 76 } 77 } 78 private: 79 bool fEQ; 80 using INHERITED = M4Bench; 81 }; 82 83 class M4Concat : public M4Bench { 84 public: M4Concat()85 M4Concat() : INHERITED("op_concat") {} 86 protected: performTest()87 void performTest() override { 88 for (int i = 0; i < 10000; ++i) { 89 fM0 = SkM44(fM1, fM2); 90 } 91 } 92 private: 93 using INHERITED = M4Bench; 94 }; 95 96 class M4SetConcat : public M4Bench { 97 public: M4SetConcat()98 M4SetConcat() : INHERITED("set_concat") {} 99 protected: performTest()100 void performTest() override { 101 for (int i = 0; i < 10000; ++i) { 102 fM0.setConcat(fM1, fM2); 103 } 104 } 105 private: 106 using INHERITED = M4Bench; 107 }; 108 109 DEF_BENCH( return new M4EQ(); ) 110 DEF_BENCH( return new M4NEQ(); ) 111 DEF_BENCH( return new M4Concat(); ) 112 DEF_BENCH( return new M4SetConcat(); ) 113 114 class M4_map4 : public M4Bench { 115 public: M4_map4()116 M4_map4() : INHERITED("map4") {} 117 protected: performTest()118 void performTest() override { 119 SkV4 v = {1, 2, 3, 4}; 120 for (int i = 0; i < 100000; ++i) { 121 fV = fM0 * v; 122 } 123 } 124 private: 125 SkV4 fV; 126 using INHERITED = M4Bench; 127 }; 128 DEF_BENCH( return new M4_map4(); ) 129 130 class M4_map2 : public M4Bench { 131 public: M4_map2()132 M4_map2() : INHERITED("map2") {} 133 protected: performTest()134 void performTest() override { 135 SkMatrix m; 136 m.setRotate(1); 137 for (int i = 0; i < 100000; ++i) { 138 fV = m.mapXY(5, 6); 139 } 140 } 141 private: 142 SkPoint fV; 143 using INHERITED = M4Bench; 144 }; 145 DEF_BENCH( return new M4_map2(); ) 146 147 148 enum class MapMatrixType { 149 kTranslateOnly, 150 kScaleTranslate, 151 kRotate, 152 kPerspective, 153 kPerspectiveClipped 154 }; 155 class MapRectBench : public Benchmark { 156 SkString fName; 157 158 public: MapRectBench(MapMatrixType type,const char name[])159 MapRectBench(MapMatrixType type, const char name[]) { 160 SkRandom rand; 161 const char* typeName; 162 switch(type) { 163 case MapMatrixType::kTranslateOnly: 164 typeName = "t"; 165 fM = SkM44::Translate(rand.nextF(), rand.nextF()); 166 break; 167 case MapMatrixType::kScaleTranslate: 168 typeName = "s+t"; 169 fM = SkM44::Scale(rand.nextF(), rand.nextF()); 170 fM.postTranslate(rand.nextF(), rand.nextF()); 171 break; 172 case MapMatrixType::kRotate: 173 typeName = "r"; 174 fM = SkM44::Rotate({0.f, 0.f, 1.f}, SkDegreesToRadians(45.f)); 175 break; 176 case MapMatrixType::kPerspective: 177 typeName = "p"; 178 // Hand chosen to have all corners with w > 0 and w != 1 179 fM = SkM44::Perspective(0.01f, 10.f, SK_ScalarPI / 3.f); 180 fM.preTranslate(0.f, 5.f, -0.1f); 181 fM.preConcat(SkM44::Rotate({0.f, 1.f, 0.f}, 0.008f /* radians */)); 182 break; 183 case MapMatrixType::kPerspectiveClipped: 184 typeName = "pc"; 185 // Hand chosen to have some corners with w > 0 and some with w < 0 186 fM = SkM44(); 187 fM.setRow(3, {-.2f, -.6f, 0.f, 8.f}); 188 break; 189 } 190 fS = SkRect::MakeXYWH(10.f * rand.nextF(), 10.f * rand.nextF(), 191 150.f * rand.nextF(), 150.f * rand.nextF()); 192 193 fName.printf("mapRect_%s_%s", name, typeName); 194 } 195 isSuitableFor(Backend backend)196 bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; } 197 198 virtual void performTest() = 0; 199 200 protected: 201 SkM44 fM; 202 SkRect fS, fD; 203 mulLoopCount() const204 virtual int mulLoopCount() const { return 1; } 205 onGetName()206 const char* onGetName() override { return fName.c_str(); } 207 onDraw(int loops,SkCanvas *)208 void onDraw(int loops, SkCanvas*) override { 209 for (int i = 0; i < loops; i++) { 210 this->performTest(); 211 } 212 } 213 214 private: 215 using INHERITED = Benchmark; 216 }; 217 218 class M4_mapRectBench : public MapRectBench { 219 public: M4_mapRectBench(MapMatrixType type)220 M4_mapRectBench(MapMatrixType type) : INHERITED(type, "m4") {} 221 222 protected: performTest()223 void performTest() override { 224 for (int i = 0; i < 100000; ++i) { 225 fD = SkMatrixPriv::MapRect(fM, fS); 226 } 227 } 228 229 private: 230 using INHERITED = MapRectBench; 231 }; 232 DEF_BENCH(return new M4_mapRectBench(MapMatrixType::kTranslateOnly);) 233 DEF_BENCH(return new M4_mapRectBench(MapMatrixType::kScaleTranslate);) 234 DEF_BENCH(return new M4_mapRectBench(MapMatrixType::kRotate);) 235 DEF_BENCH(return new M4_mapRectBench(MapMatrixType::kPerspective);) 236 DEF_BENCH(return new M4_mapRectBench(MapMatrixType::kPerspectiveClipped);) 237 238 class M33_mapRectBench : public MapRectBench { 239 public: M33_mapRectBench(MapMatrixType type)240 M33_mapRectBench(MapMatrixType type) : INHERITED(type, "m33") { 241 fM33 = fM.asM33(); 242 } 243 244 protected: performTest()245 void performTest() override { 246 for (int i = 0; i < 100000; ++i) { 247 fD = fM33.mapRect(fS); 248 } 249 } 250 private: 251 SkMatrix fM33; 252 using INHERITED = MapRectBench; 253 }; 254 255 DEF_BENCH(return new M33_mapRectBench(MapMatrixType::kTranslateOnly);) 256 DEF_BENCH(return new M33_mapRectBench(MapMatrixType::kScaleTranslate);) 257 DEF_BENCH(return new M33_mapRectBench(MapMatrixType::kRotate);) 258 DEF_BENCH(return new M33_mapRectBench(MapMatrixType::kPerspective);) 259 DEF_BENCH(return new M33_mapRectBench(MapMatrixType::kPerspectiveClipped);) 260