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