blob: 873613df39afbbb7663274388f430326090c036b [file] [log] [blame]
joshualitteef5b3e2015-04-03 08:07:26 -07001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#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"
joshualitteef5b3e2015-04-03 08:07:26 -070019
Mike Kleinc0bd9f92019-04-23 12:05:21 -050020#include "tools/ToolUtils.h"
joshualitteef5b3e2015-04-03 08:07:26 -070021
22/*
23 * A trivial test which benchmarks the performance of a textblob with a single run.
24 */
Herb Derby430424b2018-08-07 13:29:41 -040025class SkTextBlobBench : public Benchmark {
joshualitteef5b3e2015-04-03 08:07:26 -070026public:
Herb Derby430424b2018-08-07 13:29:41 -040027 SkTextBlobBench() {}
kkinnunenb4a797f2015-05-21 06:15:28 -070028
joshualitt8a6697a2015-09-30 12:11:07 -070029 void onDelayedSetup() override {
Mike Kleinea3f0142019-03-20 11:12:10 -050030 fFont.setTypeface(ToolUtils::create_portable_typeface("serif", SkFontStyle()));
Mike Reed2ed78202018-11-21 15:10:08 -050031 fFont.setSubpixel(true);
joshualitteef5b3e2015-04-03 08:07:26 -070032
Herb Derby430424b2018-08-07 13:29:41 -040033 // This text seems representative in both length and letter frequency.
34 const char* text = "Keep your sentences short, but not overly so.";
joshualitteef5b3e2015-04-03 08:07:26 -070035
Ben Wagner51e15a62019-05-07 15:38:46 -040036 fGlyphs.setCount(fFont.countText(text, strlen(text), SkTextEncoding::kUTF8));
Mike Reeded33af42018-12-05 14:15:25 -050037 fXPos.setCount(fGlyphs.count());
38
Ben Wagner51e15a62019-05-07 15:38:46 -040039 fFont.textToGlyphs(text, strlen(text), SkTextEncoding::kUTF8, fGlyphs.begin(), fGlyphs.count());
Mike Reeded33af42018-12-05 14:15:25 -050040 fFont.getXPos(&fGlyphs[0], fGlyphs.count(), fXPos.begin());
joshualitteef5b3e2015-04-03 08:07:26 -070041 }
42
Herb Derby430424b2018-08-07 13:29:41 -040043 sk_sp<SkTextBlob> makeBlob() {
44 const SkTextBlobBuilder::RunBuffer& run =
Mike Reed2ed78202018-11-21 15:10:08 -050045 fBuilder.allocRunPosH(fFont, fGlyphs.count(), 10, nullptr);
Mike Reedc16abee2018-11-24 13:27:27 -050046 memcpy(run.glyphs, &fGlyphs[0], fGlyphs.count() * sizeof(uint16_t));
Mike Reeded33af42018-12-05 14:15:25 -050047 memcpy(run.pos, &fXPos[0], fXPos.count() * sizeof(SkScalar));
Herb Derby430424b2018-08-07 13:29:41 -040048 return fBuilder.make();
49 }
50
51private:
Mike Reed2ed78202018-11-21 15:10:08 -050052 SkTextBlobBuilder fBuilder;
53 SkFont fFont;
54 SkTDArray<uint16_t> fGlyphs;
Mike Reeded33af42018-12-05 14:15:25 -050055 SkTDArray<SkScalar> fXPos;
Herb Derby430424b2018-08-07 13:29:41 -040056
John Stiles7571f9e2020-09-02 22:42:33 -040057 using INHERITED = Benchmark;
Herb Derby430424b2018-08-07 13:29:41 -040058};
59
60class TextBlobCachedBench : public SkTextBlobBench {
mtkleinf0599002015-07-13 06:18:39 -070061 const char* onGetName() override {
Herb Derby430424b2018-08-07 13:29:41 -040062 return "TextBlobCachedBench";
joshualitteef5b3e2015-04-03 08:07:26 -070063 }
64
mtkleina1ebeb22015-10-01 09:43:39 -070065 void onDraw(int loops, SkCanvas* canvas) override {
joshualitteef5b3e2015-04-03 08:07:26 -070066 SkPaint paint;
67
Herb Derby430424b2018-08-07 13:29:41 -040068 auto blob = this->makeBlob();
Herb Derby55bc0512018-10-08 14:06:09 -040069 auto bigLoops = loops * 100;
Herb Derby434377a2018-10-02 16:48:17 -040070 for (int i = 0; i < bigLoops; i++) {
Herb Derby430424b2018-08-07 13:29:41 -040071 // To ensure maximum caching, we just redraw the blob at the same place everytime
72 canvas->drawTextBlob(blob, 0, 0, paint);
joshualitteef5b3e2015-04-03 08:07:26 -070073 }
74 }
joshualitteef5b3e2015-04-03 08:07:26 -070075};
Mike Reeded33af42018-12-05 14:15:25 -050076DEF_BENCH( return new TextBlobCachedBench(); )
joshualitteef5b3e2015-04-03 08:07:26 -070077
Herb Derby430424b2018-08-07 13:29:41 -040078class TextBlobFirstTimeBench : public SkTextBlobBench {
79 const char* onGetName() override {
80 return "TextBlobFirstTimeBench";
81 }
82
83 void onDraw(int loops, SkCanvas* canvas) override {
84 SkPaint paint;
85
Herb Derby55bc0512018-10-08 14:06:09 -040086 auto bigLoops = loops * 100;
Herb Derby434377a2018-10-02 16:48:17 -040087 for (int i = 0; i < bigLoops; i++) {
Herb Derby430424b2018-08-07 13:29:41 -040088 canvas->drawTextBlob(this->makeBlob(), 0, 0, paint);
89 }
90 }
91};
Herb Derby430424b2018-08-07 13:29:41 -040092DEF_BENCH( return new TextBlobFirstTimeBench(); )
Mike Reeded33af42018-12-05 14:15:25 -050093
94class TextBlobMakeBench : public SkTextBlobBench {
95 const char* onGetName() override {
96 return "TextBlobMakeBench";
97 }
98
99 bool isSuitableFor(Backend backend) override {
100 return backend == kNonRendering_Backend;
101 }
102
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};
111DEF_BENCH( return new TextBlobMakeBench(); )