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