blob: d411cebd29c2528d3c0cc9160a3c0f9d9b613e51 [file] [log] [blame]
halcanary1abea462016-02-24 09:25:58 -08001/*
2 * Copyright 2016 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 "Benchmark.h"
Hal Canary43fb7a02016-12-30 13:09:03 -05009
halcanary1abea462016-02-24 09:25:58 -080010#include "Resources.h"
robertphillipsc5035e72016-03-17 06:58:39 -070011#include "SkAutoPixmapStorage.h"
halcanary1abea462016-02-24 09:25:58 -080012#include "SkData.h"
Hal Canary9a3f5542018-12-10 19:59:07 -050013#include "SkExecutor.h"
Hal Canary3c36ef62018-01-02 16:25:53 -050014#include "SkFloatToDecimal.h"
halcanaryd11c7262016-03-25 05:52:57 -070015#include "SkGradientShader.h"
halcanary1e440512016-02-24 15:17:19 -080016#include "SkImage.h"
Hal Canaryf34131a2018-12-18 15:11:03 -050017#include "SkPDFUnion.h"
halcanary1e440512016-02-24 15:17:19 -080018#include "SkPixmap.h"
halcanarycf430132016-03-09 10:49:23 -080019#include "SkRandom.h"
halcanarycbc060a2016-04-11 19:41:48 -070020#include "SkStream.h"
Hal Canaryc640d0d2018-06-13 09:59:02 -040021#include "SkTo.h"
halcanary1abea462016-02-24 09:25:58 -080022
23namespace {
Hal Canary43fb7a02016-12-30 13:09:03 -050024struct WStreamWriteTextBenchmark : public Benchmark {
25 std::unique_ptr<SkWStream> fWStream;
Mike Reed2a65cc02017-03-22 10:01:53 -040026 WStreamWriteTextBenchmark() : fWStream(new SkNullWStream) {}
Hal Canary43fb7a02016-12-30 13:09:03 -050027 const char* onGetName() override { return "WStreamWriteText"; }
28 bool isSuitableFor(Backend backend) override {
29 return backend == kNonRendering_Backend;
30 }
31 void onDraw(int loops, SkCanvas*) override {
32 while (loops-- > 0) {
33 for (int i = 1000; i-- > 0;) {
34 fWStream->writeText("HELLO SKIA!\n");
35 }
36 }
37 }
38};
39} // namespace
40
41DEF_BENCH(return new WStreamWriteTextBenchmark;)
42
Hal Canary3c36ef62018-01-02 16:25:53 -050043// Test speed of SkFloatToDecimal for typical floats that
44// might be found in a PDF document.
45struct PDFScalarBench : public Benchmark {
Hal Canaryb4a8a622018-02-21 15:49:41 -050046 PDFScalarBench(const char* n, float (*f)(SkRandom*)) : fName(n), fNextFloat(f) {}
47 const char* fName;
48 float (*fNextFloat)(SkRandom*);
Hal Canary3c36ef62018-01-02 16:25:53 -050049 bool isSuitableFor(Backend b) override {
50 return b == kNonRendering_Backend;
51 }
Hal Canaryb4a8a622018-02-21 15:49:41 -050052 const char* onGetName() override { return fName; }
Hal Canary3c36ef62018-01-02 16:25:53 -050053 void onDraw(int loops, SkCanvas*) override {
54 SkRandom random;
55 char dst[kMaximumSkFloatToDecimalLength];
56 while (loops-- > 0) {
Hal Canaryb4a8a622018-02-21 15:49:41 -050057 auto f = fNextFloat(&random);
Hal Canary3c36ef62018-01-02 16:25:53 -050058 (void)SkFloatToDecimal(f, dst);
59 }
60 }
61};
62
Hal Canaryb4a8a622018-02-21 15:49:41 -050063float next_common(SkRandom* random) {
64 return random->nextRangeF(-500.0f, 1500.0f);
65}
66float next_any(SkRandom* random) {
67 union { uint32_t u; float f; };
68 u = random->nextU();
69 static_assert(sizeof(float) == sizeof(uint32_t), "");
70 return f;
71}
72
73DEF_BENCH(return new PDFScalarBench("PDFScalar_common", next_common);)
74DEF_BENCH(return new PDFScalarBench("PDFScalar_random", next_any);)
Hal Canary3c36ef62018-01-02 16:25:53 -050075
Hal Canary43fb7a02016-12-30 13:09:03 -050076#ifdef SK_SUPPORT_PDF
77
78#include "SkPDFBitmap.h"
Hal Canary23564b92018-09-07 14:33:14 -040079#include "SkPDFDocumentPriv.h"
Hal Canary43fb7a02016-12-30 13:09:03 -050080#include "SkPDFShader.h"
Hal Canary23564b92018-09-07 14:33:14 -040081#include "SkPDFUtils.h"
Hal Canary43fb7a02016-12-30 13:09:03 -050082
83namespace {
halcanary1abea462016-02-24 09:25:58 -080084class PDFImageBench : public Benchmark {
85public:
86 PDFImageBench() {}
Brian Salomond3b65972017-03-22 12:05:03 -040087 ~PDFImageBench() override {}
halcanary1abea462016-02-24 09:25:58 -080088
89protected:
90 const char* onGetName() override { return "PDFImage"; }
91 bool isSuitableFor(Backend backend) override {
92 return backend == kNonRendering_Backend;
93 }
94 void onDelayedSetup() override {
Hal Canaryc465d132017-12-08 10:21:31 -050095 sk_sp<SkImage> img(GetResourceAsImage("images/color_wheel.png"));
halcanary1abea462016-02-24 09:25:58 -080096 if (img) {
97 // force decoding, throw away reference to encoded data.
98 SkAutoPixmapStorage pixmap;
99 pixmap.alloc(SkImageInfo::MakeN32Premul(img->dimensions()));
100 if (img->readPixels(pixmap, 0, 0)) {
reed9ce9d672016-03-17 10:51:11 -0700101 fImage = SkImage::MakeRasterCopy(pixmap);
halcanary1abea462016-02-24 09:25:58 -0800102 }
103 }
104 }
105 void onDraw(int loops, SkCanvas*) override {
106 if (!fImage) {
107 return;
108 }
109 while (loops-- > 0) {
Hal Canarya1211832018-11-13 16:45:14 -0500110 SkNullWStream nullStream;
111 SkPDFDocument doc(&nullStream, SkPDF::Metadata());
112 doc.beginPage(256, 256);
113 (void)SkPDFSerializeImage(fImage.get(), &doc);
halcanary1abea462016-02-24 09:25:58 -0800114 }
115 }
116
117private:
reed9ce9d672016-03-17 10:51:11 -0700118 sk_sp<SkImage> fImage;
halcanary1abea462016-02-24 09:25:58 -0800119};
120
121class PDFJpegImageBench : public Benchmark {
122public:
123 PDFJpegImageBench() {}
Brian Salomond3b65972017-03-22 12:05:03 -0400124 ~PDFJpegImageBench() override {}
halcanary1abea462016-02-24 09:25:58 -0800125
126protected:
127 const char* onGetName() override { return "PDFJpegImage"; }
128 bool isSuitableFor(Backend backend) override {
129 return backend == kNonRendering_Backend;
130 }
131 void onDelayedSetup() override {
Hal Canaryc465d132017-12-08 10:21:31 -0500132 sk_sp<SkImage> img(GetResourceAsImage("images/mandrill_512_q075.jpg"));
halcanary1abea462016-02-24 09:25:58 -0800133 if (!img) { return; }
Mike Reed6409f842017-07-11 16:03:13 -0400134 sk_sp<SkData> encoded = img->refEncodedData();
halcanary1abea462016-02-24 09:25:58 -0800135 SkASSERT(encoded);
136 if (!encoded) { return; }
reed9ce9d672016-03-17 10:51:11 -0700137 fImage = img;
halcanary1abea462016-02-24 09:25:58 -0800138 }
139 void onDraw(int loops, SkCanvas*) override {
140 if (!fImage) {
141 SkDEBUGFAIL("");
142 return;
143 }
144 while (loops-- > 0) {
Hal Canarya1211832018-11-13 16:45:14 -0500145 SkNullWStream nullStream;
146 SkPDFDocument doc(&nullStream, SkPDF::Metadata());
147 doc.beginPage(256, 256);
148 (void)SkPDFSerializeImage(fImage.get(), &doc);
halcanary1abea462016-02-24 09:25:58 -0800149 }
150 }
151
152private:
reed9ce9d672016-03-17 10:51:11 -0700153 sk_sp<SkImage> fImage;
halcanary1abea462016-02-24 09:25:58 -0800154};
155
halcanary1e440512016-02-24 15:17:19 -0800156/** Test calling DEFLATE on a 78k PDF command stream. Used for measuring
157 alternate zlib settings, usage, and library versions. */
158class PDFCompressionBench : public Benchmark {
159public:
160 PDFCompressionBench() {}
Brian Salomond3b65972017-03-22 12:05:03 -0400161 ~PDFCompressionBench() override {}
halcanary1e440512016-02-24 15:17:19 -0800162
163protected:
164 const char* onGetName() override { return "PDFCompression"; }
165 bool isSuitableFor(Backend backend) override {
166 return backend == kNonRendering_Backend;
167 }
168 void onDelayedSetup() override {
Mike Reed71f867c2017-07-23 13:14:10 -0400169 fAsset = GetResourceAsStream("pdf_command_stream.txt");
halcanary1e440512016-02-24 15:17:19 -0800170 }
171 void onDraw(int loops, SkCanvas*) override {
172 SkASSERT(fAsset);
173 if (!fAsset) { return; }
174 while (loops-- > 0) {
Hal Canary9a3f5542018-12-10 19:59:07 -0500175 SkNullWStream wStream;
176 SkPDFDocument doc(&wStream, SkPDF::Metadata());
177 doc.beginPage(256, 256);
178 (void)SkPDFStreamOut(nullptr, fAsset->duplicate(), &doc, true);
179 }
halcanary1e440512016-02-24 15:17:19 -0800180 }
181
182private:
Ben Wagner145dbcd2016-11-03 14:40:50 -0400183 std::unique_ptr<SkStreamAsset> fAsset;
halcanary1e440512016-02-24 15:17:19 -0800184};
185
halcanaryeb92cb32016-07-15 13:41:27 -0700186struct PDFColorComponentBench : public Benchmark {
187 bool isSuitableFor(Backend b) override {
188 return b == kNonRendering_Backend;
189 }
190 const char* onGetName() override { return "PDFColorComponent"; }
191 void onDraw(int loops, SkCanvas*) override {
192 char dst[5];
193 while (loops-- > 0) {
194 for (int i = 0; i < 256; ++i) {
195 (void)SkPDFUtils::ColorToDecimal(SkToU8(i), dst);
196 }
197 }
198 }
199};
200
halcanaryd11c7262016-03-25 05:52:57 -0700201struct PDFShaderBench : public Benchmark {
202 sk_sp<SkShader> fShader;
203 const char* onGetName() final { return "PDFShader"; }
204 bool isSuitableFor(Backend b) final { return b == kNonRendering_Backend; }
205 void onDelayedSetup() final {
206 const SkPoint pts[2] = {{0.0f, 0.0f}, {100.0f, 100.0f}};
207 const SkColor colors[] = {
208 SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE,
209 SK_ColorWHITE, SK_ColorBLACK,
210 };
211 fShader = SkGradientShader::MakeLinear(
212 pts, colors, nullptr, SK_ARRAY_COUNT(colors),
213 SkShader::kClamp_TileMode);
214 }
215 void onDraw(int loops, SkCanvas*) final {
216 SkASSERT(fShader);
217 while (loops-- > 0) {
Mike Reed2a65cc02017-03-22 10:01:53 -0400218 SkNullWStream nullStream;
Hal Canary23564b92018-09-07 14:33:14 -0400219 SkPDFDocument doc(&nullStream, SkPDF::Metadata());
Hal Canary9a3f5542018-12-10 19:59:07 -0500220 doc.beginPage(256, 256);
221 (void) SkPDFMakeShader(&doc, fShader.get(), SkMatrix::I(),
222 {0, 0, 400, 400}, SK_ColorBLACK);
halcanaryd11c7262016-03-25 05:52:57 -0700223 }
224 }
225};
226
halcanaryee41b752016-06-23 14:08:11 -0700227struct WritePDFTextBenchmark : public Benchmark {
228 std::unique_ptr<SkWStream> fWStream;
Mike Reed2a65cc02017-03-22 10:01:53 -0400229 WritePDFTextBenchmark() : fWStream(new SkNullWStream) {}
halcanaryee41b752016-06-23 14:08:11 -0700230 const char* onGetName() override { return "WritePDFText"; }
231 bool isSuitableFor(Backend backend) override {
232 return backend == kNonRendering_Backend;
233 }
234 void onDraw(int loops, SkCanvas*) override {
235 static const char kHello[] = "HELLO SKIA!\n";
236 static const char kBinary[] = "\001\002\003\004\005\006";
237 while (loops-- > 0) {
238 for (int i = 1000; i-- > 0;) {
Hal Canarye650b852018-09-12 09:12:36 -0400239 SkPDFWriteString(fWStream.get(), kHello, strlen(kHello));
240 SkPDFWriteString(fWStream.get(), kBinary, strlen(kBinary));
halcanaryee41b752016-06-23 14:08:11 -0700241 }
242 }
243 }
244};
245
halcanary1abea462016-02-24 09:25:58 -0800246} // namespace
247DEF_BENCH(return new PDFImageBench;)
248DEF_BENCH(return new PDFJpegImageBench;)
halcanary1e440512016-02-24 15:17:19 -0800249DEF_BENCH(return new PDFCompressionBench;)
halcanaryeb92cb32016-07-15 13:41:27 -0700250DEF_BENCH(return new PDFColorComponentBench;)
halcanaryd11c7262016-03-25 05:52:57 -0700251DEF_BENCH(return new PDFShaderBench;)
halcanaryee41b752016-06-23 14:08:11 -0700252DEF_BENCH(return new WritePDFTextBenchmark;)
Hal Canary43fb7a02016-12-30 13:09:03 -0500253
Hal Canary28db53d2019-01-09 15:32:35 -0500254#ifdef SK_PDF_ENABLE_SLOW_TESTS
Hal Canary9a3f5542018-12-10 19:59:07 -0500255#include "SkExecutor.h"
256namespace {
Hal Canary28db53d2019-01-09 15:32:35 -0500257void big_pdf_test(SkDocument* doc, const SkBitmap& background) {
Hal Canary9a3f5542018-12-10 19:59:07 -0500258 static const char* kText[] = {
259 "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do",
260 "eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad",
261 "minim veniam, quis nostrud exercitation ullamco laboris nisi ut",
262 "aliquip ex ea commodo consequat. Duis aute irure dolor in",
263 "reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla",
264 "pariatur. Excepteur sint occaecat cupidatat non proident, sunt in",
265 "culpa qui officia deserunt mollit anim id est laborum.",
266 "",
267 "Sed ut perspiciatis, unde omnis iste natus error sit voluptatem",
268 "accusantium doloremque laudantium, totam rem aperiam eaque ipsa, quae",
269 "ab illo inventore veritatis et quasi architecto beatae vitae dicta",
270 "sunt, explicabo. Nemo enim ipsam voluptatem, quia voluptas sit,",
271 "aspernatur aut odit aut fugit, sed quia consequuntur magni dolores",
272 "eos, qui ratione voluptatem sequi nesciunt, neque porro quisquam est,",
273 "qui dolorem ipsum, quia dolor sit amet consectetur adipiscing velit,",
274 "sed quia non numquam do eius modi tempora incididunt, ut labore et",
275 "dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam,",
276 "quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi",
277 "ut aliquid ex ea commodi consequatur? Quis autem vel eum iure",
278 "reprehenderit, qui in ea voluptate velit esse, quam nihil molestiae",
279 "consequatur, vel illum, qui dolorem eum fugiat, quo voluptas nulla",
280 "pariatur?",
281 "",
282 "At vero eos et accusamus et iusto odio dignissimos ducimus, qui",
283 "blanditiis praesentium voluptatum deleniti atque corrupti, quos",
284 "dolores et quas molestias excepturi sint, obcaecati cupiditate non",
285 "provident, similique sunt in culpa, qui officia deserunt mollitia",
286 "animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis",
287 "est et expedita distinctio. Nam libero tempore, cum soluta nobis est",
288 "eligendi optio, cumque nihil impedit, quo minus id, quod maxime",
289 "placeat, facere possimus, omnis voluptas assumenda est, omnis dolor",
290 "repellendus. Temporibus autem quibusdam et aut officiis debitis aut",
291 "rerum necessitatibus saepe eveniet, ut et voluptates repudiandae sint",
292 "et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente",
293 "delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut",
294 "perferendis doloribus asperiores repellat",
295 "",
296 "Sed ut perspiciatis, unde omnis iste natus error sit voluptatem",
297 "accusantium doloremque laudantium, totam rem aperiam eaque ipsa, quae",
298 "ab illo inventore veritatis et quasi architecto beatae vitae dicta",
299 "sunt, explicabo. Nemo enim ipsam voluptatem, quia voluptas sit,",
300 "aspernatur aut odit aut fugit, sed quia consequuntur magni dolores",
301 "eos, qui ratione voluptatem sequi nesciunt, neque porro quisquam est,",
302 "qui dolorem ipsum, quia dolor sit amet consectetur adipiscing velit,",
303 "sed quia non numquam do eius modi tempora incididunt, ut labore et",
304 "dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam,",
305 "quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi",
306 "ut aliquid ex ea commodi consequatur? Quis autem vel eum iure",
307 "reprehenderit, qui in ea voluptate velit esse, quam nihil molestiae",
308 "consequatur, vel illum, qui dolorem eum fugiat, quo voluptas nulla",
309 "pariatur?",
310 "",
311 };
Hal Canary9a3f5542018-12-10 19:59:07 -0500312 SkCanvas* canvas = nullptr;
313 float x = 36;
314 float y = 36;
315 constexpr size_t kLineCount = SK_ARRAY_COUNT(kText);
316 constexpr int kLoopCount = 200;
Hal Canary28db53d2019-01-09 15:32:35 -0500317 SkFont font;
Hal Canary9a3f5542018-12-10 19:59:07 -0500318 SkPaint paint;
Hal Canary9a3f5542018-12-10 19:59:07 -0500319 for (int loop = 0; loop < kLoopCount; ++loop) {
320 for (size_t line = 0; line < kLineCount; ++line) {
Hal Canary28db53d2019-01-09 15:32:35 -0500321 y += font.getSpacing();
Hal Canary9a3f5542018-12-10 19:59:07 -0500322 if (!canvas || y > 792 - 36) {
Hal Canary28db53d2019-01-09 15:32:35 -0500323 y = 36 + font.getSpacing();
Hal Canary9a3f5542018-12-10 19:59:07 -0500324 canvas = doc->beginPage(612, 792);
325 background.notifyPixelsChanged();
326 canvas->drawBitmap(background, 0, 0);
327 }
Hal Canary28db53d2019-01-09 15:32:35 -0500328 canvas->drawString(kText[line], x, y, font, paint);
Hal Canary9a3f5542018-12-10 19:59:07 -0500329 }
330 }
331}
332
333SkBitmap make_background() {
334 SkBitmap background;
335 SkBitmap bitmap;
336 bitmap.allocN32Pixels(32, 32);
337 bitmap.eraseColor(SK_ColorWHITE);
338 SkCanvas tmp(bitmap);
339 SkPaint gray;
340 gray.setColor(SkColorSetARGB(0xFF, 0xEE, 0xEE, 0xEE));
341 tmp.drawRect({0,0,16,16}, gray);
342 tmp.drawRect({16,16,32,32}, gray);
343 SkPaint shader;
344 shader.setShader(
345 SkShader::MakeBitmapShader(
346 bitmap, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode));
347 background.allocN32Pixels(612, 792);
348 SkCanvas tmp2(background);
349 tmp2.drawPaint(shader);
350 return background;
351}
352
353struct PDFBigDocBench : public Benchmark {
Hal Canary28db53d2019-01-09 15:32:35 -0500354 bool fFast;
Hal Canary9a3f5542018-12-10 19:59:07 -0500355 SkBitmap fBackground;
Hal Canary28db53d2019-01-09 15:32:35 -0500356 std::unique_ptr<SkExecutor> fExecutor;
357 PDFBigDocBench(bool fast) : fFast(fast) {}
358 void onDelayedSetup() override {
359 fBackground = make_background();
360 fExecutor = fFast ? SkExecutor::MakeFIFOThreadPool() : nullptr;
Hal Canary9a3f5542018-12-10 19:59:07 -0500361 }
Hal Canary28db53d2019-01-09 15:32:35 -0500362 const char* onGetName() override {
363 static const char kNameFast[] = "PDFBigDocBench_fast";
364 static const char kNameSlow[] = "PDFBigDocBench_slow";
365 return fFast ? kNameFast : kNameSlow;
366 }
367 bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
Hal Canary9a3f5542018-12-10 19:59:07 -0500368 void onDraw(int loops, SkCanvas*) override {
Hal Canary28db53d2019-01-09 15:32:35 -0500369 while (loops-- > 0) {
370 #ifdef SK_PDF_TEST_BIGDOCBENCH_OUTPUT
371 SkFILEWStream wStream("/tmp/big_pdf.pdf");
372 #else
373 SkNullWStream wStream;
374 #endif
375 SkPDF::Metadata metadata;
376 metadata.fExecutor = fExecutor.get();
377 sk_sp<SkDocument> doc = SkPDF::MakeDocument(&wStream, metadata);
378 big_pdf_test(doc.get(), fBackground);
379 }
Hal Canary9a3f5542018-12-10 19:59:07 -0500380 }
381};
382} // namespace
Hal Canary28db53d2019-01-09 15:32:35 -0500383DEF_BENCH(return new PDFBigDocBench(false);)
384DEF_BENCH(return new PDFBigDocBench(true);)
Hal Canary43fb7a02016-12-30 13:09:03 -0500385#endif
386
Hal Canary9a3f5542018-12-10 19:59:07 -0500387#endif // SK_SUPPORT_PDF