blob: 751a828c1209b15c0b5b983ffe5dd7002746cb24 [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 Canary9a3f5542018-12-10 19:59:07 -0500254#if 0
255#include "SkExecutor.h"
256namespace {
257void big_pdf_test(const SkBitmap& background) {
258 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 };
312 //SkFILEWStream wStream("/tmp/big_pdf.pdf");
313 SkNullWStream wStream;
314 SkPDF::Metadata metadata;
315 //std::unique_ptr<SkExecutor> executor = SkExecutor::MakeFIFOThreadPool();
316 //metadata.fExecutor = executor.get();
317 sk_sp<SkDocument> doc = SkPDF::MakeDocument(&wStream, metadata);
318
319 SkCanvas* canvas = nullptr;
320 float x = 36;
321 float y = 36;
322 constexpr size_t kLineCount = SK_ARRAY_COUNT(kText);
323 constexpr int kLoopCount = 200;
324 SkPaint paint;
325 paint.setTextEncoding(kUTF8_SkTextEncoding);
326 for (int loop = 0; loop < kLoopCount; ++loop) {
327 for (size_t line = 0; line < kLineCount; ++line) {
328 y += paint.getFontSpacing();
329 if (!canvas || y > 792 - 36) {
330 y = 36 + paint.getFontSpacing();
331 canvas = doc->beginPage(612, 792);
332 background.notifyPixelsChanged();
333 canvas->drawBitmap(background, 0, 0);
334 }
335 canvas->drawText(kText[line], strlen(kText[line]), x, y, paint);
336 }
337 }
338}
339
340SkBitmap make_background() {
341 SkBitmap background;
342 SkBitmap bitmap;
343 bitmap.allocN32Pixels(32, 32);
344 bitmap.eraseColor(SK_ColorWHITE);
345 SkCanvas tmp(bitmap);
346 SkPaint gray;
347 gray.setColor(SkColorSetARGB(0xFF, 0xEE, 0xEE, 0xEE));
348 tmp.drawRect({0,0,16,16}, gray);
349 tmp.drawRect({16,16,32,32}, gray);
350 SkPaint shader;
351 shader.setShader(
352 SkShader::MakeBitmapShader(
353 bitmap, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode));
354 background.allocN32Pixels(612, 792);
355 SkCanvas tmp2(background);
356 tmp2.drawPaint(shader);
357 return background;
358}
359
360struct PDFBigDocBench : public Benchmark {
361 SkBitmap fBackground;
362 void onDelayedSetup() override { fBackground = make_background(); }
363 const char* onGetName() override { return "PDFBigDocBench"; }
364 bool isSuitableFor(Backend backend) override {
365 return backend == kNonRendering_Backend;
366 }
367 void onDraw(int loops, SkCanvas*) override {
368 while (loops-- > 0) { big_pdf_test(fBackground); }
369 }
370};
371} // namespace
372DEF_BENCH(return new PDFBigDocBench;)
Hal Canary43fb7a02016-12-30 13:09:03 -0500373#endif
374
Hal Canary9a3f5542018-12-10 19:59:07 -0500375#endif // SK_SUPPORT_PDF