Flutter Engine
skparagraph_benchmarks.cc
Go to the documentation of this file.
1 /*
2  * Copyright 2017 Google, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <sstream>
18 
19 #include "flutter/fml/command_line.h"
20 #include "flutter/fml/logging.h"
21 #include "flutter/third_party/txt/tests/txt_test_utils.h"
22 #include "third_party/benchmark/include/benchmark/benchmark_api.h"
23 #include "third_party/icu/source/common/unicode/unistr.h"
24 #include "third_party/skia/include/core/SkBitmap.h"
25 #include "third_party/skia/include/core/SkCanvas.h"
26 #include "third_party/skia/include/core/SkColor.h"
27 #include "third_party/skia/modules/skparagraph/include/Paragraph.h"
28 #include "third_party/skia/modules/skparagraph/include/ParagraphBuilder.h"
29 #include "third_party/skia/modules/skparagraph/include/TypefaceFontProvider.h"
30 #include "third_party/skia/modules/skparagraph/utils/TestFontCollection.h"
31 
32 namespace sktxt = skia::textlayout;
33 
34 class SkParagraphFixture : public benchmark::Fixture {
35  public:
36  void SetUp(const ::benchmark::State& state) {
37  font_collection_ = sk_make_sp<sktxt::TestFontCollection>(txt::GetFontDir());
38 
39  bitmap_ = std::make_unique<SkBitmap>();
40  bitmap_->allocN32Pixels(1000, 1000);
41  canvas_ = std::make_unique<SkCanvas>(*bitmap_);
42  canvas_->clear(SK_ColorWHITE);
43  }
44 
45  protected:
46  sk_sp<sktxt::TestFontCollection> font_collection_;
47  std::unique_ptr<SkCanvas> canvas_;
48  std::unique_ptr<SkBitmap> bitmap_;
49 };
50 
51 BENCHMARK_F(SkParagraphFixture, ShortLayout)(benchmark::State& state) {
52  const char* text = "Hello World";
53  sktxt::ParagraphStyle paragraph_style;
54  sktxt::TextStyle text_style;
55  text_style.setFontFamilies({SkString("Roboto")});
56  text_style.setColor(SK_ColorBLACK);
57  auto builder =
58  sktxt::ParagraphBuilder::make(paragraph_style, font_collection_);
59  builder->pushStyle(text_style);
60  builder->addText(text);
61  builder->pop();
62  auto paragraph = builder->Build();
63  while (state.KeepRunning()) {
64  paragraph->markDirty();
65  paragraph->layout(300);
66  }
67 }
68 
69 BENCHMARK_F(SkParagraphFixture, LongLayout)(benchmark::State& state) {
70  const char* text =
71  "This is a very long sentence to test if the text will properly wrap "
72  "around and go to the next line. Sometimes, short sentence. Longer "
73  "sentences are okay too because they are necessary. Very short. "
74  "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
75  "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
76  "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
77  "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
78  "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
79  "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
80  "mollit anim id est laborum. "
81  "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
82  "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
83  "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
84  "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
85  "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
86  "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
87  "mollit anim id est laborum.";
88  sktxt::ParagraphStyle paragraph_style;
89  sktxt::TextStyle text_style;
90  text_style.setFontFamilies({SkString("Roboto")});
91  text_style.setColor(SK_ColorBLACK);
92  auto builder =
93  sktxt::ParagraphBuilder::make(paragraph_style, font_collection_);
94  builder->pushStyle(text_style);
95  builder->addText(text);
96  builder->pop();
97  auto paragraph = builder->Build();
98  while (state.KeepRunning()) {
99  paragraph->markDirty();
100  paragraph->layout(300);
101  }
102 }
103 
104 BENCHMARK_F(SkParagraphFixture, JustifyLayout)(benchmark::State& state) {
105  const char* text =
106  "This is a very long sentence to test if the text will properly wrap "
107  "around and go to the next line. Sometimes, short sentence. Longer "
108  "sentences are okay too because they are necessary. Very short. "
109  "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
110  "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
111  "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
112  "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
113  "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
114  "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
115  "mollit anim id est laborum. "
116  "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
117  "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
118  "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
119  "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
120  "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
121  "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
122  "mollit anim id est laborum.";
123  sktxt::ParagraphStyle paragraph_style;
124  paragraph_style.setTextAlign(sktxt::TextAlign::kJustify);
125  sktxt::TextStyle text_style;
126  text_style.setFontFamilies({SkString("Roboto")});
127  text_style.setColor(SK_ColorBLACK);
128  auto builder =
129  sktxt::ParagraphBuilder::make(paragraph_style, font_collection_);
130  builder->pushStyle(text_style);
131  builder->addText(text);
132  builder->pop();
133  auto paragraph = builder->Build();
134  while (state.KeepRunning()) {
135  paragraph->markDirty();
136  paragraph->layout(300);
137  }
138 }
139 
140 BENCHMARK_F(SkParagraphFixture, ManyStylesLayout)(benchmark::State& state) {
141  const char* text = "-";
142  sktxt::ParagraphStyle paragraph_style;
143  sktxt::TextStyle text_style;
144  text_style.setFontFamilies({SkString("Roboto")});
145  text_style.setColor(SK_ColorBLACK);
146  auto builder =
147  sktxt::ParagraphBuilder::make(paragraph_style, font_collection_);
148  for (int i = 0; i < 1000; ++i) {
149  builder->pushStyle(text_style);
150  builder->addText(text);
151  }
152  auto paragraph = builder->Build();
153  while (state.KeepRunning()) {
154  paragraph->markDirty();
155  paragraph->layout(300);
156  }
157 }
158 
159 BENCHMARK_DEFINE_F(SkParagraphFixture, TextBigO)(benchmark::State& state) {
160  std::vector<uint16_t> text;
161  for (uint16_t i = 0; i < state.range(0); ++i) {
162  text.push_back(i % 5 == 0 ? ' ' : i);
163  }
164  std::u16string u16_text(text.data(), text.data() + text.size());
165  sktxt::ParagraphStyle paragraph_style;
166  sktxt::TextStyle text_style;
167  text_style.setFontFamilies({SkString("Roboto")});
168  text_style.setColor(SK_ColorBLACK);
169  auto builder =
170  sktxt::ParagraphBuilder::make(paragraph_style, font_collection_);
171  builder->pushStyle(text_style);
172  builder->addText(u16_text);
173  builder->pop();
174  auto paragraph = builder->Build();
175  while (state.KeepRunning()) {
176  paragraph->markDirty();
177  paragraph->layout(300);
178  }
179  state.SetComplexityN(state.range(0));
180 }
181 BENCHMARK_REGISTER_F(SkParagraphFixture, TextBigO)
182  ->RangeMultiplier(4)
183  ->Range(1 << 6, 1 << 14)
184  ->Complexity(benchmark::oN);
185 
186 BENCHMARK_DEFINE_F(SkParagraphFixture, StylesBigO)(benchmark::State& state) {
187  const char* text = "vry shrt ";
188  sktxt::ParagraphStyle paragraph_style;
189  sktxt::TextStyle text_style;
190  text_style.setFontFamilies({SkString("Roboto")});
191  text_style.setColor(SK_ColorBLACK);
192  auto builder = sktxt::ParagraphBuilder::make(
193  paragraph_style,
194  sk_make_sp<sktxt::TestFontCollection>(txt::GetFontDir()));
195  for (int i = 0; i < 1000; ++i) {
196  builder->pushStyle(text_style);
197  builder->addText(text);
198  }
199  auto paragraph = builder->Build();
200  while (state.KeepRunning()) {
201  paragraph->markDirty();
202  paragraph->layout(300);
203  }
204  state.SetComplexityN(state.range(0));
205 }
206 BENCHMARK_REGISTER_F(SkParagraphFixture, StylesBigO)
207  ->RangeMultiplier(4)
208  ->Range(1 << 3, 1 << 12)
209  ->Complexity(benchmark::oN);
210 
211 BENCHMARK_F(SkParagraphFixture, PaintSimple)(benchmark::State& state) {
212  const char* text = "This is a simple sentence to test drawing.";
213  sktxt::ParagraphStyle paragraph_style;
214  sktxt::TextStyle text_style;
215  text_style.setFontFamilies({SkString("Roboto")});
216  text_style.setColor(SK_ColorBLACK);
217  auto builder =
218  sktxt::ParagraphBuilder::make(paragraph_style, font_collection_);
219  builder->pushStyle(text_style);
220  builder->addText(text);
221  builder->pop();
222  auto paragraph = builder->Build();
223  paragraph->layout(300);
224  int offset = 0;
225  while (state.KeepRunning()) {
226  paragraph->paint(canvas_.get(), offset % 700, 10);
227  offset++;
228  }
229 }
230 
231 BENCHMARK_F(SkParagraphFixture, PaintLarge)(benchmark::State& state) {
232  const char* text =
233  "Hello world! This is a simple sentence to test drawing. Hello world! "
234  "This is a simple sentence to test drawing. Hello world! This is a "
235  "simple sentence to test drawing.Hello world! This is a simple sentence "
236  "to test drawing. Hello world! "
237  "This is a simple sentence to test drawing. Hello world! This is a "
238  "simple sentence to test drawing.Hello world! This is a simple sentence "
239  "to test drawing. Hello world! "
240  "This is a simple sentence to test drawing. Hello world! This is a "
241  "simple sentence to test drawing.Hello world! This is a simple sentence "
242  "to test drawing. Hello world! "
243  "This is a simple sentence to test drawing. Hello world! This is a "
244  "simple sentence to test drawing.Hello world! This is a simple sentence "
245  "to test drawing. Hello world! "
246  "This is a simple sentence to test drawing. Hello world! This is a "
247  "simple sentence to test drawing.Hello world! This is a simple sentence "
248  "to test drawing. Hello world! "
249  "This is a simple sentence to test drawing. Hello world! This is a "
250  "simple sentence to test drawing.";
251  sktxt::ParagraphStyle paragraph_style;
252  sktxt::TextStyle text_style;
253  text_style.setFontFamilies({SkString("Roboto")});
254  text_style.setColor(SK_ColorBLACK);
255  auto builder =
256  sktxt::ParagraphBuilder::make(paragraph_style, font_collection_);
257  builder->pushStyle(text_style);
258  builder->addText(text);
259  builder->pop();
260  auto paragraph = builder->Build();
261  paragraph->layout(300);
262  int offset = 0;
263  while (state.KeepRunning()) {
264  paragraph->paint(canvas_.get(), offset % 700, 10);
265  offset++;
266  }
267 }
268 
269 BENCHMARK_F(SkParagraphFixture, PaintDecoration)(benchmark::State& state) {
270  const char* text =
271  "Hello world! This is a simple sentence to test drawing. Hello world! "
272  "This is a simple sentence to test drawing.";
273  sktxt::ParagraphStyle paragraph_style;
274  sktxt::TextStyle text_style;
275  text_style.setFontFamilies({SkString("Roboto")});
276  text_style.setColor(SK_ColorBLACK);
277  text_style.setDecoration(static_cast<sktxt::TextDecoration>(
280  auto builder =
281  sktxt::ParagraphBuilder::make(paragraph_style, font_collection_);
282  text_style.setDecorationStyle(sktxt::TextDecorationStyle::kSolid);
283  builder->pushStyle(text_style);
284  builder->addText(text);
285 
286  text_style.setDecorationStyle(sktxt::TextDecorationStyle::kDotted);
287  builder->pushStyle(text_style);
288  builder->addText(text);
289 
290  text_style.setDecorationStyle(sktxt::TextDecorationStyle::kWavy);
291  builder->pushStyle(text_style);
292  builder->addText(text);
293 
294  auto paragraph = builder->Build();
295  paragraph->layout(300);
296  int offset = 0;
297  while (state.KeepRunning()) {
298  paragraph->paint(canvas_.get(), offset % 700, 10);
299  offset++;
300  }
301 }
void SetUp(const ::benchmark::State &state)
BENCHMARK_DEFINE_F(SkParagraphFixture, TextBigO)(benchmark
BENCHMARK_F(SkParagraphFixture, ShortLayout)(benchmark
std::unique_ptr< SkCanvas > canvas_
sk_sp< sktxt::TestFontCollection > font_collection_
const std::string & GetFontDir()
std::unique_ptr< SkBitmap > bitmap_