xref: /aosp_15_r20/external/skia/bench/PathTextBench.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2017 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/SkCanvas.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFont.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPath.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkRandom.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkStrike.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkStrikeCache.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkStrikeSpec.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "tools/ToolUtils.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "tools/fonts/FontToolUtils.h"
19*c8dee2aaSAndroid Build Coastguard Worker 
20*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kScreenWidth = 1500;
21*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kScreenHeight = 1500;
22*c8dee2aaSAndroid Build Coastguard Worker 
23*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kNumDraws = 2000;
24*c8dee2aaSAndroid Build Coastguard Worker 
25*c8dee2aaSAndroid Build Coastguard Worker // I and l are rects on OS X.
26*c8dee2aaSAndroid Build Coastguard Worker static constexpr char kGlyphs[] =  "ABCDEFGH7JKLMNOPQRSTUVWXYZabcdefghijk1mnopqrstuvwxyz";
27*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kNumGlyphs = sizeof(kGlyphs) - 1;
28*c8dee2aaSAndroid Build Coastguard Worker static_assert(52 == kNumGlyphs, "expected 52 glyphs");
29*c8dee2aaSAndroid Build Coastguard Worker 
30*c8dee2aaSAndroid Build Coastguard Worker /*
31*c8dee2aaSAndroid Build Coastguard Worker  * This class benchmarks drawing many glyphs at random scales and rotations.
32*c8dee2aaSAndroid Build Coastguard Worker  */
33*c8dee2aaSAndroid Build Coastguard Worker class PathTextBench : public Benchmark {
34*c8dee2aaSAndroid Build Coastguard Worker public:
PathTextBench(bool clipped,bool uncached)35*c8dee2aaSAndroid Build Coastguard Worker     PathTextBench(bool clipped, bool uncached) : fClipped(clipped), fUncached(uncached) {}
36*c8dee2aaSAndroid Build Coastguard Worker 
37*c8dee2aaSAndroid Build Coastguard Worker private:
onGetName()38*c8dee2aaSAndroid Build Coastguard Worker     const char* onGetName() override {
39*c8dee2aaSAndroid Build Coastguard Worker         fName = "path_text";
40*c8dee2aaSAndroid Build Coastguard Worker         if (fClipped) {
41*c8dee2aaSAndroid Build Coastguard Worker             fName.append("_clipped");
42*c8dee2aaSAndroid Build Coastguard Worker         }
43*c8dee2aaSAndroid Build Coastguard Worker         if (fUncached) {
44*c8dee2aaSAndroid Build Coastguard Worker             fName.append("_uncached");
45*c8dee2aaSAndroid Build Coastguard Worker         }
46*c8dee2aaSAndroid Build Coastguard Worker         return fName.c_str();
47*c8dee2aaSAndroid Build Coastguard Worker     }
onGetSize()48*c8dee2aaSAndroid Build Coastguard Worker     SkISize onGetSize() override { return SkISize::Make(kScreenWidth, kScreenHeight); }
49*c8dee2aaSAndroid Build Coastguard Worker 
onDelayedSetup()50*c8dee2aaSAndroid Build Coastguard Worker     void onDelayedSetup() override {
51*c8dee2aaSAndroid Build Coastguard Worker         SkFont defaultFont = ToolUtils::DefaultFont();
52*c8dee2aaSAndroid Build Coastguard Worker         SkStrikeSpec strikeSpec = SkStrikeSpec::MakeWithNoDevice(defaultFont);
53*c8dee2aaSAndroid Build Coastguard Worker         SkBulkGlyphMetricsAndPaths pathMaker{strikeSpec};
54*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < kNumGlyphs; ++i) {
55*c8dee2aaSAndroid Build Coastguard Worker             SkGlyphID id(defaultFont.unicharToGlyph(kGlyphs[i]));
56*c8dee2aaSAndroid Build Coastguard Worker             const SkGlyph* glyph = pathMaker.glyph(id);
57*c8dee2aaSAndroid Build Coastguard Worker             if (glyph->path()) {
58*c8dee2aaSAndroid Build Coastguard Worker                 fGlyphs[i] = *glyph->path();
59*c8dee2aaSAndroid Build Coastguard Worker             }
60*c8dee2aaSAndroid Build Coastguard Worker             fGlyphs[i].setIsVolatile(fUncached);
61*c8dee2aaSAndroid Build Coastguard Worker         }
62*c8dee2aaSAndroid Build Coastguard Worker 
63*c8dee2aaSAndroid Build Coastguard Worker         SkRandom rand;
64*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < kNumDraws; ++i) {
65*c8dee2aaSAndroid Build Coastguard Worker             const SkPath& glyph = fGlyphs[i % kNumGlyphs];
66*c8dee2aaSAndroid Build Coastguard Worker             const SkRect& bounds = glyph.getBounds();
67*c8dee2aaSAndroid Build Coastguard Worker             float glyphSize = std::max(bounds.width(), bounds.height());
68*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(glyphSize > 0);
69*c8dee2aaSAndroid Build Coastguard Worker 
70*c8dee2aaSAndroid Build Coastguard Worker             float t0 = pow(rand.nextF(), 100);
71*c8dee2aaSAndroid Build Coastguard Worker             float size = (1 - t0) * std::min(kScreenWidth, kScreenHeight) / 50 +
72*c8dee2aaSAndroid Build Coastguard Worker                          t0 * std::min(kScreenWidth, kScreenHeight) / 3;
73*c8dee2aaSAndroid Build Coastguard Worker             float scale = size / glyphSize;
74*c8dee2aaSAndroid Build Coastguard Worker             float t1 = rand.nextF(), t2 = rand.nextF();
75*c8dee2aaSAndroid Build Coastguard Worker             fXforms[i].setTranslate((1 - t1) * sqrt(2) * scale/2 * glyphSize +
76*c8dee2aaSAndroid Build Coastguard Worker                                      t1 * (kScreenWidth - sqrt(2) * scale/2 * glyphSize),
77*c8dee2aaSAndroid Build Coastguard Worker                                      (1 - t2) * sqrt(2) * scale/2 * glyphSize +
78*c8dee2aaSAndroid Build Coastguard Worker                                      t2 * (kScreenHeight - sqrt(2) * scale/2 * glyphSize));
79*c8dee2aaSAndroid Build Coastguard Worker             fXforms[i].preRotate(rand.nextF() * 360);
80*c8dee2aaSAndroid Build Coastguard Worker             fXforms[i].preTranslate(-scale/2 * bounds.width(), -scale/2 * bounds.height());
81*c8dee2aaSAndroid Build Coastguard Worker             fXforms[i].preScale(scale, scale);
82*c8dee2aaSAndroid Build Coastguard Worker             fPaints[i].setAntiAlias(true);
83*c8dee2aaSAndroid Build Coastguard Worker             fPaints[i].setColor(rand.nextU() | 0x80808080);
84*c8dee2aaSAndroid Build Coastguard Worker         }
85*c8dee2aaSAndroid Build Coastguard Worker 
86*c8dee2aaSAndroid Build Coastguard Worker         if (fClipped) {
87*c8dee2aaSAndroid Build Coastguard Worker             fClipPath = ToolUtils::make_star(SkRect::MakeIWH(kScreenWidth, kScreenHeight), 11, 3);
88*c8dee2aaSAndroid Build Coastguard Worker             fClipPath.setIsVolatile(fUncached);
89*c8dee2aaSAndroid Build Coastguard Worker         }
90*c8dee2aaSAndroid Build Coastguard Worker     }
91*c8dee2aaSAndroid Build Coastguard Worker 
onDraw(int loops,SkCanvas * canvas)92*c8dee2aaSAndroid Build Coastguard Worker     void onDraw(int loops, SkCanvas* canvas) override {
93*c8dee2aaSAndroid Build Coastguard Worker         SkAutoCanvasRestore acr(canvas, true);
94*c8dee2aaSAndroid Build Coastguard Worker         if (fClipped) {
95*c8dee2aaSAndroid Build Coastguard Worker             canvas->clipPath(fClipPath, SkClipOp::kIntersect, true);
96*c8dee2aaSAndroid Build Coastguard Worker         }
97*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < kNumDraws; ++i) {
98*c8dee2aaSAndroid Build Coastguard Worker             const SkPath& glyph = fGlyphs[i % kNumGlyphs];
99*c8dee2aaSAndroid Build Coastguard Worker             canvas->setMatrix(fXforms[i]);
100*c8dee2aaSAndroid Build Coastguard Worker             canvas->drawPath(glyph, fPaints[i]);
101*c8dee2aaSAndroid Build Coastguard Worker         }
102*c8dee2aaSAndroid Build Coastguard Worker     }
103*c8dee2aaSAndroid Build Coastguard Worker 
104*c8dee2aaSAndroid Build Coastguard Worker     const bool fClipped;
105*c8dee2aaSAndroid Build Coastguard Worker     const bool fUncached;
106*c8dee2aaSAndroid Build Coastguard Worker     SkString fName;
107*c8dee2aaSAndroid Build Coastguard Worker     SkPath fGlyphs[kNumGlyphs];
108*c8dee2aaSAndroid Build Coastguard Worker     SkPaint fPaints[kNumDraws];
109*c8dee2aaSAndroid Build Coastguard Worker     SkMatrix fXforms[kNumDraws];
110*c8dee2aaSAndroid Build Coastguard Worker     SkPath fClipPath;
111*c8dee2aaSAndroid Build Coastguard Worker 
112*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = Benchmark;
113*c8dee2aaSAndroid Build Coastguard Worker };
114*c8dee2aaSAndroid Build Coastguard Worker 
115*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH(return new PathTextBench(false, false);)
116*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH(return new PathTextBench(false, true);)
117*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH(return new PathTextBench(true, true);)
118