blob: c2a8e6024976999ed094415749e32d47905c0d2d [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"
halcanaryd11c7262016-03-25 05:52:57 -070013#include "SkGradientShader.h"
halcanary1e440512016-02-24 15:17:19 -080014#include "SkImage.h"
halcanary1e440512016-02-24 15:17:19 -080015#include "SkPixmap.h"
halcanarycf430132016-03-09 10:49:23 -080016#include "SkRandom.h"
halcanarycbc060a2016-04-11 19:41:48 -070017#include "SkStream.h"
halcanary1abea462016-02-24 09:25:58 -080018
19namespace {
Hal Canary43fb7a02016-12-30 13:09:03 -050020struct WStreamWriteTextBenchmark : public Benchmark {
21 std::unique_ptr<SkWStream> fWStream;
Mike Reed2a65cc02017-03-22 10:01:53 -040022 WStreamWriteTextBenchmark() : fWStream(new SkNullWStream) {}
Hal Canary43fb7a02016-12-30 13:09:03 -050023 const char* onGetName() override { return "WStreamWriteText"; }
24 bool isSuitableFor(Backend backend) override {
25 return backend == kNonRendering_Backend;
26 }
27 void onDraw(int loops, SkCanvas*) override {
28 while (loops-- > 0) {
29 for (int i = 1000; i-- > 0;) {
30 fWStream->writeText("HELLO SKIA!\n");
31 }
32 }
33 }
34};
35} // namespace
36
37DEF_BENCH(return new WStreamWriteTextBenchmark;)
38
39#ifdef SK_SUPPORT_PDF
40
41#include "SkPDFBitmap.h"
42#include "SkPDFDocument.h"
43#include "SkPDFShader.h"
44#include "SkPDFUtils.h"
45
46namespace {
halcanarya50151d2016-03-25 11:57:49 -070047static void test_pdf_object_serialization(const sk_sp<SkPDFObject> object) {
halcanary1abea462016-02-24 09:25:58 -080048 // SkDebugWStream wStream;
Mike Reed2a65cc02017-03-22 10:01:53 -040049 SkNullWStream wStream;
halcanary1abea462016-02-24 09:25:58 -080050 SkPDFObjNumMap objNumMap;
halcanary530032a2016-08-18 14:22:52 -070051 objNumMap.addObjectRecursively(object.get());
halcanary1abea462016-02-24 09:25:58 -080052 for (int i = 0; i < objNumMap.objects().count(); ++i) {
halcanarybae235e2016-03-21 10:05:23 -070053 SkPDFObject* object = objNumMap.objects()[i].get();
halcanary1abea462016-02-24 09:25:58 -080054 wStream.writeDecAsText(i + 1);
55 wStream.writeText(" 0 obj\n");
halcanary530032a2016-08-18 14:22:52 -070056 object->emitObject(&wStream, objNumMap);
halcanary1abea462016-02-24 09:25:58 -080057 wStream.writeText("\nendobj\n");
58 }
59}
60
61class PDFImageBench : public Benchmark {
62public:
63 PDFImageBench() {}
Brian Salomond3b65972017-03-22 12:05:03 -040064 ~PDFImageBench() override {}
halcanary1abea462016-02-24 09:25:58 -080065
66protected:
67 const char* onGetName() override { return "PDFImage"; }
68 bool isSuitableFor(Backend backend) override {
69 return backend == kNonRendering_Backend;
70 }
71 void onDelayedSetup() override {
Hal Canaryc465d132017-12-08 10:21:31 -050072 sk_sp<SkImage> img(GetResourceAsImage("images/color_wheel.png"));
halcanary1abea462016-02-24 09:25:58 -080073 if (img) {
74 // force decoding, throw away reference to encoded data.
75 SkAutoPixmapStorage pixmap;
76 pixmap.alloc(SkImageInfo::MakeN32Premul(img->dimensions()));
77 if (img->readPixels(pixmap, 0, 0)) {
reed9ce9d672016-03-17 10:51:11 -070078 fImage = SkImage::MakeRasterCopy(pixmap);
halcanary1abea462016-02-24 09:25:58 -080079 }
80 }
81 }
82 void onDraw(int loops, SkCanvas*) override {
83 if (!fImage) {
84 return;
85 }
86 while (loops-- > 0) {
Mike Reeda4daf192017-12-14 13:25:04 -050087 auto object = SkPDFCreateBitmapObject(fImage,
88#ifdef SK_SUPPORT_LEGACY_PDF_PIXELSERIALIZER
89 nullptr,
90#endif
91 false);
halcanary1e440512016-02-24 15:17:19 -080092 SkASSERT(object);
93 if (!object) {
94 return;
95 }
96 test_pdf_object_serialization(object);
halcanary1abea462016-02-24 09:25:58 -080097 }
98 }
99
100private:
reed9ce9d672016-03-17 10:51:11 -0700101 sk_sp<SkImage> fImage;
halcanary1abea462016-02-24 09:25:58 -0800102};
103
104class PDFJpegImageBench : public Benchmark {
105public:
106 PDFJpegImageBench() {}
Brian Salomond3b65972017-03-22 12:05:03 -0400107 ~PDFJpegImageBench() override {}
halcanary1abea462016-02-24 09:25:58 -0800108
109protected:
110 const char* onGetName() override { return "PDFJpegImage"; }
111 bool isSuitableFor(Backend backend) override {
112 return backend == kNonRendering_Backend;
113 }
114 void onDelayedSetup() override {
Hal Canaryc465d132017-12-08 10:21:31 -0500115 sk_sp<SkImage> img(GetResourceAsImage("images/mandrill_512_q075.jpg"));
halcanary1abea462016-02-24 09:25:58 -0800116 if (!img) { return; }
Mike Reed6409f842017-07-11 16:03:13 -0400117 sk_sp<SkData> encoded = img->refEncodedData();
halcanary1abea462016-02-24 09:25:58 -0800118 SkASSERT(encoded);
119 if (!encoded) { return; }
reed9ce9d672016-03-17 10:51:11 -0700120 fImage = img;
halcanary1abea462016-02-24 09:25:58 -0800121 }
122 void onDraw(int loops, SkCanvas*) override {
123 if (!fImage) {
124 SkDEBUGFAIL("");
125 return;
126 }
127 while (loops-- > 0) {
Mike Reeda4daf192017-12-14 13:25:04 -0500128 auto object = SkPDFCreateBitmapObject(fImage,
129#ifdef SK_SUPPORT_LEGACY_PDF_PIXELSERIALIZER
130 nullptr,
131#endif
132 false);
halcanary1e440512016-02-24 15:17:19 -0800133 SkASSERT(object);
134 if (!object) {
135 return;
136 }
137 test_pdf_object_serialization(object);
halcanary1abea462016-02-24 09:25:58 -0800138 }
139 }
140
141private:
reed9ce9d672016-03-17 10:51:11 -0700142 sk_sp<SkImage> fImage;
halcanary1abea462016-02-24 09:25:58 -0800143};
144
halcanary1e440512016-02-24 15:17:19 -0800145/** Test calling DEFLATE on a 78k PDF command stream. Used for measuring
146 alternate zlib settings, usage, and library versions. */
147class PDFCompressionBench : public Benchmark {
148public:
149 PDFCompressionBench() {}
Brian Salomond3b65972017-03-22 12:05:03 -0400150 ~PDFCompressionBench() override {}
halcanary1e440512016-02-24 15:17:19 -0800151
152protected:
153 const char* onGetName() override { return "PDFCompression"; }
154 bool isSuitableFor(Backend backend) override {
155 return backend == kNonRendering_Backend;
156 }
157 void onDelayedSetup() override {
Mike Reed71f867c2017-07-23 13:14:10 -0400158 fAsset = GetResourceAsStream("pdf_command_stream.txt");
halcanary1e440512016-02-24 15:17:19 -0800159 }
160 void onDraw(int loops, SkCanvas*) override {
161 SkASSERT(fAsset);
162 if (!fAsset) { return; }
163 while (loops-- > 0) {
halcanaryfa251062016-07-29 10:13:18 -0700164 sk_sp<SkPDFObject> object =
165 sk_make_sp<SkPDFSharedStream>(
166 std::unique_ptr<SkStreamAsset>(fAsset->duplicate()));
halcanary1e440512016-02-24 15:17:19 -0800167 test_pdf_object_serialization(object);
168 }
169 }
170
171private:
Ben Wagner145dbcd2016-11-03 14:40:50 -0400172 std::unique_ptr<SkStreamAsset> fAsset;
halcanary1e440512016-02-24 15:17:19 -0800173};
174
halcanarycf430132016-03-09 10:49:23 -0800175// Test speed of SkPDFUtils::FloatToDecimal for typical floats that
176// might be found in a PDF document.
177struct PDFScalarBench : public Benchmark {
178 bool isSuitableFor(Backend b) override {
179 return b == kNonRendering_Backend;
180 }
181 const char* onGetName() override { return "PDFScalar"; }
182 void onDraw(int loops, SkCanvas*) override {
183 SkRandom random;
184 char dst[SkPDFUtils::kMaximumFloatDecimalLength];
185 while (loops-- > 0) {
186 auto f = random.nextRangeF(-500.0f, 1500.0f);
187 (void)SkPDFUtils::FloatToDecimal(f, dst);
188 }
189 }
190};
191
halcanaryeb92cb32016-07-15 13:41:27 -0700192struct PDFColorComponentBench : public Benchmark {
193 bool isSuitableFor(Backend b) override {
194 return b == kNonRendering_Backend;
195 }
196 const char* onGetName() override { return "PDFColorComponent"; }
197 void onDraw(int loops, SkCanvas*) override {
198 char dst[5];
199 while (loops-- > 0) {
200 for (int i = 0; i < 256; ++i) {
201 (void)SkPDFUtils::ColorToDecimal(SkToU8(i), dst);
202 }
203 }
204 }
205};
206
halcanaryd11c7262016-03-25 05:52:57 -0700207struct PDFShaderBench : public Benchmark {
208 sk_sp<SkShader> fShader;
209 const char* onGetName() final { return "PDFShader"; }
210 bool isSuitableFor(Backend b) final { return b == kNonRendering_Backend; }
211 void onDelayedSetup() final {
212 const SkPoint pts[2] = {{0.0f, 0.0f}, {100.0f, 100.0f}};
213 const SkColor colors[] = {
214 SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE,
215 SK_ColorWHITE, SK_ColorBLACK,
216 };
217 fShader = SkGradientShader::MakeLinear(
218 pts, colors, nullptr, SK_ARRAY_COUNT(colors),
219 SkShader::kClamp_TileMode);
220 }
221 void onDraw(int loops, SkCanvas*) final {
222 SkASSERT(fShader);
223 while (loops-- > 0) {
Mike Reed2a65cc02017-03-22 10:01:53 -0400224 SkNullWStream nullStream;
Mike Reeda4daf192017-12-14 13:25:04 -0500225 SkPDFDocument doc(&nullStream, nullptr, SkDocument::PDFMetadata());
Hal Canary7e872ca2017-07-19 15:51:18 -0400226 sk_sp<SkPDFObject> shader = SkPDFMakeShader(&doc, fShader.get(), SkMatrix::I(),
227 {0, 0, 400, 400}, SK_ColorBLACK);
halcanaryd11c7262016-03-25 05:52:57 -0700228 }
229 }
230};
231
halcanaryee41b752016-06-23 14:08:11 -0700232struct WritePDFTextBenchmark : public Benchmark {
233 std::unique_ptr<SkWStream> fWStream;
Mike Reed2a65cc02017-03-22 10:01:53 -0400234 WritePDFTextBenchmark() : fWStream(new SkNullWStream) {}
halcanaryee41b752016-06-23 14:08:11 -0700235 const char* onGetName() override { return "WritePDFText"; }
236 bool isSuitableFor(Backend backend) override {
237 return backend == kNonRendering_Backend;
238 }
239 void onDraw(int loops, SkCanvas*) override {
240 static const char kHello[] = "HELLO SKIA!\n";
241 static const char kBinary[] = "\001\002\003\004\005\006";
242 while (loops-- > 0) {
243 for (int i = 1000; i-- > 0;) {
244 SkPDFUtils::WriteString(fWStream.get(), kHello, strlen(kHello));
245 SkPDFUtils::WriteString(fWStream.get(), kBinary, strlen(kBinary));
246 }
247 }
248 }
249};
250
halcanary1abea462016-02-24 09:25:58 -0800251} // namespace
252DEF_BENCH(return new PDFImageBench;)
253DEF_BENCH(return new PDFJpegImageBench;)
halcanary1e440512016-02-24 15:17:19 -0800254DEF_BENCH(return new PDFCompressionBench;)
halcanarycf430132016-03-09 10:49:23 -0800255DEF_BENCH(return new PDFScalarBench;)
halcanaryeb92cb32016-07-15 13:41:27 -0700256DEF_BENCH(return new PDFColorComponentBench;)
halcanaryd11c7262016-03-25 05:52:57 -0700257DEF_BENCH(return new PDFShaderBench;)
halcanaryee41b752016-06-23 14:08:11 -0700258DEF_BENCH(return new WritePDFTextBenchmark;)
Hal Canary43fb7a02016-12-30 13:09:03 -0500259
260#endif
261