• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 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/SkCanvas.h"
10 #include "include/core/SkFont.h"
11 #include "include/core/SkPaint.h"
12 #include "include/core/SkStream.h"
13 #include "include/core/SkString.h"
14 #include "include/core/SkTextBlob.h"
15 #include "include/core/SkTypeface.h"
16 #include "include/private/SkTemplates.h"
17 #include "include/utils/SkRandom.h"
18 #include "tools/Resources.h"
19 
20 #include "tools/ToolUtils.h"
21 
22 /*
23  * A trivial test which benchmarks the performance of a textblob with a single run.
24  */
25 class SkTextBlobBench : public Benchmark {
26 public:
SkTextBlobBench()27     SkTextBlobBench() {}
28 
onDelayedSetup()29     void onDelayedSetup() override {
30         fFont.setTypeface(ToolUtils::create_portable_typeface("serif", SkFontStyle()));
31         fFont.setSubpixel(true);
32 
33         // This text seems representative in both length and letter frequency.
34         const char* text = "Keep your sentences short, but not overly so.";
35 
36         fGlyphs.setCount(fFont.countText(text, strlen(text), SkTextEncoding::kUTF8));
37         fXPos.setCount(fGlyphs.count());
38 
39         fFont.textToGlyphs(text, strlen(text), SkTextEncoding::kUTF8, fGlyphs.begin(), fGlyphs.count());
40         fFont.getXPos(&fGlyphs[0], fGlyphs.count(), fXPos.begin());
41     }
42 
makeBlob()43     sk_sp<SkTextBlob> makeBlob() {
44         const SkTextBlobBuilder::RunBuffer& run =
45             fBuilder.allocRunPosH(fFont, fGlyphs.count(), 10, nullptr);
46         memcpy(run.glyphs, &fGlyphs[0], fGlyphs.count() * sizeof(uint16_t));
47         memcpy(run.pos, &fXPos[0], fXPos.count() * sizeof(SkScalar));
48         return fBuilder.make();
49     }
50 
51 private:
52     SkTextBlobBuilder   fBuilder;
53     SkFont              fFont;
54     SkTDArray<uint16_t> fGlyphs;
55     SkTDArray<SkScalar> fXPos;
56 
57     using INHERITED = Benchmark;
58 };
59 
60 class TextBlobCachedBench : public SkTextBlobBench {
onGetName()61     const char* onGetName() override {
62         return "TextBlobCachedBench";
63     }
64 
onDraw(int loops,SkCanvas * canvas)65     void onDraw(int loops, SkCanvas* canvas) override {
66         SkPaint paint;
67 
68         auto blob = this->makeBlob();
69         auto bigLoops = loops * 100;
70         for (int i = 0; i < bigLoops; i++) {
71             // To ensure maximum caching, we just redraw the blob at the same place everytime
72             canvas->drawTextBlob(blob, 0, 0, paint);
73         }
74     }
75 };
76 DEF_BENCH( return new TextBlobCachedBench(); )
77 
78 class TextBlobFirstTimeBench : public SkTextBlobBench {
onGetName()79     const char* onGetName() override {
80         return "TextBlobFirstTimeBench";
81     }
82 
onDraw(int loops,SkCanvas * canvas)83     void onDraw(int loops, SkCanvas* canvas) override {
84         SkPaint paint;
85 
86         auto bigLoops = loops * 100;
87         for (int i = 0; i < bigLoops; i++) {
88             canvas->drawTextBlob(this->makeBlob(), 0, 0, paint);
89         }
90     }
91 };
92 DEF_BENCH( return new TextBlobFirstTimeBench(); )
93 
94 class TextBlobMakeBench : public SkTextBlobBench {
onGetName()95     const char* onGetName() override {
96         return "TextBlobMakeBench";
97     }
98 
isSuitableFor(Backend backend)99     bool isSuitableFor(Backend backend) override {
100         return backend == kNonRendering_Backend;
101     }
102 
onDraw(int loops,SkCanvas *)103     void onDraw(int loops, SkCanvas*) override {
104         for (int i = 0; i < loops; i++) {
105             for (int inner = 0; inner < 1000; ++inner) {
106                 this->makeBlob();
107             }
108         }
109     }
110 };
111 DEF_BENCH( return new TextBlobMakeBench(); )
112