| /* | |
| * Copyright 2012 Google Inc. | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "bench/Benchmark.h" | |
| #include "include/core/SkM44.h" | |
| #include "include/core/SkString.h" | |
| #include "src/core/SkMatrixPriv.h" | |
| #include "src/core/SkRandom.h" | |
| class M4Bench : public Benchmark { | |
| SkString fName; | |
| public: | |
| M4Bench(const char name[]) { | |
| fName.printf("m4_%s", name); | |
| SkRandom rand; | |
| float value[32]; | |
| for (auto& v : value) { | |
| v = rand.nextF(); | |
| } | |
| fM1 = SkM44::ColMajor(value + 0); | |
| fM2 = SkM44::ColMajor(value + 16); | |
| } | |
| bool isSuitableFor(Backend backend) override { | |
| return backend == Backend::kNonRendering; | |
| } | |
| virtual void performTest() = 0; | |
| protected: | |
| SkM44 fM0, fM1, fM2; | |
| virtual int mulLoopCount() const { return 1; } | |
| const char* onGetName() override { | |
| return fName.c_str(); | |
| } | |
| void onDraw(int loops, SkCanvas*) override { | |
| for (int i = 0; i < loops; i++) { | |
| this->performTest(); | |
| } | |
| } | |
| private: | |
| using INHERITED = Benchmark; | |
| }; | |
| class M4NEQ : public M4Bench { | |
| public: | |
| M4NEQ() : INHERITED("neq") {} | |
| protected: | |
| void performTest() override { | |
| for (int i = 0; i < 10000; ++i) { | |
| fEQ = (fM2 == fM1); // should always be false | |
| } | |
| } | |
| private: | |
| bool fEQ; | |
| using INHERITED = M4Bench; | |
| }; | |
| class M4EQ : public M4Bench { | |
| public: | |
| M4EQ() : INHERITED("eq") {} | |
| protected: | |
| void performTest() override { | |
| fM2 = fM1; | |
| for (int i = 0; i < 10000; ++i) { | |
| fEQ = (fM2 == fM1); // should always be true | |
| } | |
| } | |
| private: | |
| bool fEQ; | |
| using INHERITED = M4Bench; | |
| }; | |
| class M4Concat : public M4Bench { | |
| public: | |
| M4Concat() : INHERITED("op_concat") {} | |
| protected: | |
| void performTest() override { | |
| for (int i = 0; i < 10000; ++i) { | |
| fM0 = SkM44(fM1, fM2); | |
| } | |
| } | |
| private: | |
| using INHERITED = M4Bench; | |
| }; | |
| class M4SetConcat : public M4Bench { | |
| public: | |
| M4SetConcat() : INHERITED("set_concat") {} | |
| protected: | |
| void performTest() override { | |
| for (int i = 0; i < 10000; ++i) { | |
| fM0.setConcat(fM1, fM2); | |
| } | |
| } | |
| private: | |
| using INHERITED = M4Bench; | |
| }; | |
| DEF_BENCH( return new M4EQ(); ) | |
| DEF_BENCH( return new M4NEQ(); ) | |
| DEF_BENCH( return new M4Concat(); ) | |
| DEF_BENCH( return new M4SetConcat(); ) | |
| class M4_map4 : public M4Bench { | |
| public: | |
| M4_map4() : INHERITED("map4") {} | |
| protected: | |
| void performTest() override { | |
| SkV4 v = {1, 2, 3, 4}; | |
| for (int i = 0; i < 100000; ++i) { | |
| fV = fM0 * v; | |
| } | |
| } | |
| private: | |
| SkV4 fV; | |
| using INHERITED = M4Bench; | |
| }; | |
| DEF_BENCH( return new M4_map4(); ) | |
| class M4_map2 : public M4Bench { | |
| public: | |
| M4_map2() : INHERITED("map2") {} | |
| protected: | |
| void performTest() override { | |
| SkMatrix m; | |
| m.setRotate(1); | |
| for (int i = 0; i < 100000; ++i) { | |
| fV = m.mapPoint({5, 6}); | |
| } | |
| } | |
| private: | |
| SkPoint fV; | |
| using INHERITED = M4Bench; | |
| }; | |
| DEF_BENCH( return new M4_map2(); ) | |
| enum class MapMatrixType { | |
| kTranslateOnly, | |
| kScaleTranslate, | |
| kRotate, | |
| kPerspective, | |
| kPerspectiveClipped | |
| }; | |
| class MapRectBench : public Benchmark { | |
| SkString fName; | |
| public: | |
| MapRectBench(MapMatrixType type, const char name[]) { | |
| SkRandom rand; | |
| const char* typeName; | |
| switch(type) { | |
| case MapMatrixType::kTranslateOnly: | |
| typeName = "t"; | |
| fM = SkM44::Translate(rand.nextF(), rand.nextF()); | |
| break; | |
| case MapMatrixType::kScaleTranslate: | |
| typeName = "s+t"; | |
| fM = SkM44::Scale(rand.nextF(), rand.nextF()); | |
| fM.postTranslate(rand.nextF(), rand.nextF()); | |
| break; | |
| case MapMatrixType::kRotate: | |
| typeName = "r"; | |
| fM = SkM44::Rotate({0.f, 0.f, 1.f}, SkDegreesToRadians(45.f)); | |
| break; | |
| case MapMatrixType::kPerspective: | |
| typeName = "p"; | |
| // Hand chosen to have all corners with w > 0 and w != 1 | |
| fM = SkM44::Perspective(0.01f, 10.f, SK_ScalarPI / 3.f); | |
| fM.preTranslate(0.f, 5.f, -0.1f); | |
| fM.preConcat(SkM44::Rotate({0.f, 1.f, 0.f}, 0.008f /* radians */)); | |
| break; | |
| case MapMatrixType::kPerspectiveClipped: | |
| typeName = "pc"; | |
| // Hand chosen to have some corners with w > 0 and some with w < 0 | |
| fM = SkM44(); | |
| fM.setRow(3, {-.2f, -.6f, 0.f, 8.f}); | |
| break; | |
| } | |
| fS = SkRect::MakeXYWH(10.f * rand.nextF(), 10.f * rand.nextF(), | |
| 150.f * rand.nextF(), 150.f * rand.nextF()); | |
| fName.printf("mapRect_%s_%s", name, typeName); | |
| } | |
| bool isSuitableFor(Backend backend) override { return backend == Backend::kNonRendering; } | |
| virtual void performTest() = 0; | |
| protected: | |
| SkM44 fM; | |
| SkRect fS, fD; | |
| virtual int mulLoopCount() const { return 1; } | |
| const char* onGetName() override { return fName.c_str(); } | |
| void onDraw(int loops, SkCanvas*) override { | |
| for (int i = 0; i < loops; i++) { | |
| this->performTest(); | |
| } | |
| } | |
| private: | |
| using INHERITED = Benchmark; | |
| }; | |
| class M4_mapRectBench : public MapRectBench { | |
| public: | |
| M4_mapRectBench(MapMatrixType type) : INHERITED(type, "m4") {} | |
| protected: | |
| void performTest() override { | |
| for (int i = 0; i < 100000; ++i) { | |
| fD = SkMatrixPriv::MapRect(fM, fS); | |
| } | |
| } | |
| private: | |
| using INHERITED = MapRectBench; | |
| }; | |
| DEF_BENCH(return new M4_mapRectBench(MapMatrixType::kTranslateOnly);) | |
| DEF_BENCH(return new M4_mapRectBench(MapMatrixType::kScaleTranslate);) | |
| DEF_BENCH(return new M4_mapRectBench(MapMatrixType::kRotate);) | |
| DEF_BENCH(return new M4_mapRectBench(MapMatrixType::kPerspective);) | |
| DEF_BENCH(return new M4_mapRectBench(MapMatrixType::kPerspectiveClipped);) | |
| class M33_mapRectBench : public MapRectBench { | |
| public: | |
| M33_mapRectBench(MapMatrixType type) : INHERITED(type, "m33") { | |
| fM33 = fM.asM33(); | |
| } | |
| protected: | |
| void performTest() override { | |
| for (int i = 0; i < 100000; ++i) { | |
| fD = fM33.mapRect(fS); | |
| } | |
| } | |
| private: | |
| SkMatrix fM33; | |
| using INHERITED = MapRectBench; | |
| }; | |
| DEF_BENCH(return new M33_mapRectBench(MapMatrixType::kTranslateOnly);) | |
| DEF_BENCH(return new M33_mapRectBench(MapMatrixType::kScaleTranslate);) | |
| DEF_BENCH(return new M33_mapRectBench(MapMatrixType::kRotate);) | |
| DEF_BENCH(return new M33_mapRectBench(MapMatrixType::kPerspective);) | |
| DEF_BENCH(return new M33_mapRectBench(MapMatrixType::kPerspectiveClipped);) |