2016-02-24 17:25:58 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2016 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "Benchmark.h"
|
2016-12-30 18:09:03 +00:00
|
|
|
|
2016-02-24 17:25:58 +00:00
|
|
|
#include "Resources.h"
|
2016-03-17 13:58:39 +00:00
|
|
|
#include "SkAutoPixmapStorage.h"
|
2016-02-24 17:25:58 +00:00
|
|
|
#include "SkData.h"
|
2018-01-02 21:25:53 +00:00
|
|
|
#include "SkFloatToDecimal.h"
|
2016-03-25 12:52:57 +00:00
|
|
|
#include "SkGradientShader.h"
|
2016-02-24 23:17:19 +00:00
|
|
|
#include "SkImage.h"
|
|
|
|
#include "SkPixmap.h"
|
2016-03-09 18:49:23 +00:00
|
|
|
#include "SkRandom.h"
|
2016-04-12 02:41:48 +00:00
|
|
|
#include "SkStream.h"
|
2018-06-13 13:59:02 +00:00
|
|
|
#include "SkTo.h"
|
2016-02-24 17:25:58 +00:00
|
|
|
|
|
|
|
namespace {
|
2016-12-30 18:09:03 +00:00
|
|
|
struct WStreamWriteTextBenchmark : public Benchmark {
|
|
|
|
std::unique_ptr<SkWStream> fWStream;
|
2017-03-22 14:01:53 +00:00
|
|
|
WStreamWriteTextBenchmark() : fWStream(new SkNullWStream) {}
|
2016-12-30 18:09:03 +00:00
|
|
|
const char* onGetName() override { return "WStreamWriteText"; }
|
|
|
|
bool isSuitableFor(Backend backend) override {
|
|
|
|
return backend == kNonRendering_Backend;
|
|
|
|
}
|
|
|
|
void onDraw(int loops, SkCanvas*) override {
|
|
|
|
while (loops-- > 0) {
|
|
|
|
for (int i = 1000; i-- > 0;) {
|
|
|
|
fWStream->writeText("HELLO SKIA!\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
DEF_BENCH(return new WStreamWriteTextBenchmark;)
|
|
|
|
|
2018-01-02 21:25:53 +00:00
|
|
|
// Test speed of SkFloatToDecimal for typical floats that
|
|
|
|
// might be found in a PDF document.
|
|
|
|
struct PDFScalarBench : public Benchmark {
|
2018-02-21 20:49:41 +00:00
|
|
|
PDFScalarBench(const char* n, float (*f)(SkRandom*)) : fName(n), fNextFloat(f) {}
|
|
|
|
const char* fName;
|
|
|
|
float (*fNextFloat)(SkRandom*);
|
2018-01-02 21:25:53 +00:00
|
|
|
bool isSuitableFor(Backend b) override {
|
|
|
|
return b == kNonRendering_Backend;
|
|
|
|
}
|
2018-02-21 20:49:41 +00:00
|
|
|
const char* onGetName() override { return fName; }
|
2018-01-02 21:25:53 +00:00
|
|
|
void onDraw(int loops, SkCanvas*) override {
|
|
|
|
SkRandom random;
|
|
|
|
char dst[kMaximumSkFloatToDecimalLength];
|
|
|
|
while (loops-- > 0) {
|
2018-02-21 20:49:41 +00:00
|
|
|
auto f = fNextFloat(&random);
|
2018-01-02 21:25:53 +00:00
|
|
|
(void)SkFloatToDecimal(f, dst);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-02-21 20:49:41 +00:00
|
|
|
float next_common(SkRandom* random) {
|
|
|
|
return random->nextRangeF(-500.0f, 1500.0f);
|
|
|
|
}
|
|
|
|
float next_any(SkRandom* random) {
|
|
|
|
union { uint32_t u; float f; };
|
|
|
|
u = random->nextU();
|
|
|
|
static_assert(sizeof(float) == sizeof(uint32_t), "");
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEF_BENCH(return new PDFScalarBench("PDFScalar_common", next_common);)
|
|
|
|
DEF_BENCH(return new PDFScalarBench("PDFScalar_random", next_any);)
|
2018-01-02 21:25:53 +00:00
|
|
|
|
2016-12-30 18:09:03 +00:00
|
|
|
#ifdef SK_SUPPORT_PDF
|
|
|
|
|
|
|
|
#include "SkPDFBitmap.h"
|
|
|
|
#include "SkPDFDocument.h"
|
|
|
|
#include "SkPDFShader.h"
|
|
|
|
|
|
|
|
namespace {
|
2016-03-25 18:57:49 +00:00
|
|
|
static void test_pdf_object_serialization(const sk_sp<SkPDFObject> object) {
|
2016-02-24 17:25:58 +00:00
|
|
|
// SkDebugWStream wStream;
|
2017-03-22 14:01:53 +00:00
|
|
|
SkNullWStream wStream;
|
2016-02-24 17:25:58 +00:00
|
|
|
SkPDFObjNumMap objNumMap;
|
2016-08-18 21:22:52 +00:00
|
|
|
objNumMap.addObjectRecursively(object.get());
|
2016-02-24 17:25:58 +00:00
|
|
|
for (int i = 0; i < objNumMap.objects().count(); ++i) {
|
2016-03-21 17:05:23 +00:00
|
|
|
SkPDFObject* object = objNumMap.objects()[i].get();
|
2016-02-24 17:25:58 +00:00
|
|
|
wStream.writeDecAsText(i + 1);
|
|
|
|
wStream.writeText(" 0 obj\n");
|
2016-08-18 21:22:52 +00:00
|
|
|
object->emitObject(&wStream, objNumMap);
|
2016-02-24 17:25:58 +00:00
|
|
|
wStream.writeText("\nendobj\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class PDFImageBench : public Benchmark {
|
|
|
|
public:
|
|
|
|
PDFImageBench() {}
|
2017-03-22 16:05:03 +00:00
|
|
|
~PDFImageBench() override {}
|
2016-02-24 17:25:58 +00:00
|
|
|
|
|
|
|
protected:
|
|
|
|
const char* onGetName() override { return "PDFImage"; }
|
|
|
|
bool isSuitableFor(Backend backend) override {
|
|
|
|
return backend == kNonRendering_Backend;
|
|
|
|
}
|
|
|
|
void onDelayedSetup() override {
|
2017-12-08 15:21:31 +00:00
|
|
|
sk_sp<SkImage> img(GetResourceAsImage("images/color_wheel.png"));
|
2016-02-24 17:25:58 +00:00
|
|
|
if (img) {
|
|
|
|
// force decoding, throw away reference to encoded data.
|
|
|
|
SkAutoPixmapStorage pixmap;
|
|
|
|
pixmap.alloc(SkImageInfo::MakeN32Premul(img->dimensions()));
|
|
|
|
if (img->readPixels(pixmap, 0, 0)) {
|
2016-03-17 17:51:11 +00:00
|
|
|
fImage = SkImage::MakeRasterCopy(pixmap);
|
2016-02-24 17:25:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void onDraw(int loops, SkCanvas*) override {
|
|
|
|
if (!fImage) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
while (loops-- > 0) {
|
2017-12-15 20:43:03 +00:00
|
|
|
auto object = SkPDFCreateBitmapObject(fImage);
|
2016-02-24 23:17:19 +00:00
|
|
|
SkASSERT(object);
|
|
|
|
if (!object) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
test_pdf_object_serialization(object);
|
2016-02-24 17:25:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2016-03-17 17:51:11 +00:00
|
|
|
sk_sp<SkImage> fImage;
|
2016-02-24 17:25:58 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class PDFJpegImageBench : public Benchmark {
|
|
|
|
public:
|
|
|
|
PDFJpegImageBench() {}
|
2017-03-22 16:05:03 +00:00
|
|
|
~PDFJpegImageBench() override {}
|
2016-02-24 17:25:58 +00:00
|
|
|
|
|
|
|
protected:
|
|
|
|
const char* onGetName() override { return "PDFJpegImage"; }
|
|
|
|
bool isSuitableFor(Backend backend) override {
|
|
|
|
return backend == kNonRendering_Backend;
|
|
|
|
}
|
|
|
|
void onDelayedSetup() override {
|
2017-12-08 15:21:31 +00:00
|
|
|
sk_sp<SkImage> img(GetResourceAsImage("images/mandrill_512_q075.jpg"));
|
2016-02-24 17:25:58 +00:00
|
|
|
if (!img) { return; }
|
2017-07-11 20:03:13 +00:00
|
|
|
sk_sp<SkData> encoded = img->refEncodedData();
|
2016-02-24 17:25:58 +00:00
|
|
|
SkASSERT(encoded);
|
|
|
|
if (!encoded) { return; }
|
2016-03-17 17:51:11 +00:00
|
|
|
fImage = img;
|
2016-02-24 17:25:58 +00:00
|
|
|
}
|
|
|
|
void onDraw(int loops, SkCanvas*) override {
|
|
|
|
if (!fImage) {
|
|
|
|
SkDEBUGFAIL("");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
while (loops-- > 0) {
|
2017-12-15 20:43:03 +00:00
|
|
|
auto object = SkPDFCreateBitmapObject(fImage);
|
2016-02-24 23:17:19 +00:00
|
|
|
SkASSERT(object);
|
|
|
|
if (!object) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
test_pdf_object_serialization(object);
|
2016-02-24 17:25:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2016-03-17 17:51:11 +00:00
|
|
|
sk_sp<SkImage> fImage;
|
2016-02-24 17:25:58 +00:00
|
|
|
};
|
|
|
|
|
2016-02-24 23:17:19 +00:00
|
|
|
/** Test calling DEFLATE on a 78k PDF command stream. Used for measuring
|
|
|
|
alternate zlib settings, usage, and library versions. */
|
|
|
|
class PDFCompressionBench : public Benchmark {
|
|
|
|
public:
|
|
|
|
PDFCompressionBench() {}
|
2017-03-22 16:05:03 +00:00
|
|
|
~PDFCompressionBench() override {}
|
2016-02-24 23:17:19 +00:00
|
|
|
|
|
|
|
protected:
|
|
|
|
const char* onGetName() override { return "PDFCompression"; }
|
|
|
|
bool isSuitableFor(Backend backend) override {
|
|
|
|
return backend == kNonRendering_Backend;
|
|
|
|
}
|
|
|
|
void onDelayedSetup() override {
|
2017-07-23 17:14:10 +00:00
|
|
|
fAsset = GetResourceAsStream("pdf_command_stream.txt");
|
2016-02-24 23:17:19 +00:00
|
|
|
}
|
|
|
|
void onDraw(int loops, SkCanvas*) override {
|
|
|
|
SkASSERT(fAsset);
|
|
|
|
if (!fAsset) { return; }
|
|
|
|
while (loops-- > 0) {
|
2016-07-29 17:13:18 +00:00
|
|
|
sk_sp<SkPDFObject> object =
|
|
|
|
sk_make_sp<SkPDFSharedStream>(
|
|
|
|
std::unique_ptr<SkStreamAsset>(fAsset->duplicate()));
|
2016-02-24 23:17:19 +00:00
|
|
|
test_pdf_object_serialization(object);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2016-11-03 18:40:50 +00:00
|
|
|
std::unique_ptr<SkStreamAsset> fAsset;
|
2016-02-24 23:17:19 +00:00
|
|
|
};
|
|
|
|
|
2016-07-15 20:41:27 +00:00
|
|
|
struct PDFColorComponentBench : public Benchmark {
|
|
|
|
bool isSuitableFor(Backend b) override {
|
|
|
|
return b == kNonRendering_Backend;
|
|
|
|
}
|
|
|
|
const char* onGetName() override { return "PDFColorComponent"; }
|
|
|
|
void onDraw(int loops, SkCanvas*) override {
|
|
|
|
char dst[5];
|
|
|
|
while (loops-- > 0) {
|
|
|
|
for (int i = 0; i < 256; ++i) {
|
|
|
|
(void)SkPDFUtils::ColorToDecimal(SkToU8(i), dst);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-03-25 12:52:57 +00:00
|
|
|
struct PDFShaderBench : public Benchmark {
|
|
|
|
sk_sp<SkShader> fShader;
|
|
|
|
const char* onGetName() final { return "PDFShader"; }
|
|
|
|
bool isSuitableFor(Backend b) final { return b == kNonRendering_Backend; }
|
|
|
|
void onDelayedSetup() final {
|
|
|
|
const SkPoint pts[2] = {{0.0f, 0.0f}, {100.0f, 100.0f}};
|
|
|
|
const SkColor colors[] = {
|
|
|
|
SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE,
|
|
|
|
SK_ColorWHITE, SK_ColorBLACK,
|
|
|
|
};
|
|
|
|
fShader = SkGradientShader::MakeLinear(
|
|
|
|
pts, colors, nullptr, SK_ARRAY_COUNT(colors),
|
|
|
|
SkShader::kClamp_TileMode);
|
|
|
|
}
|
|
|
|
void onDraw(int loops, SkCanvas*) final {
|
|
|
|
SkASSERT(fShader);
|
|
|
|
while (loops-- > 0) {
|
2017-03-22 14:01:53 +00:00
|
|
|
SkNullWStream nullStream;
|
2018-01-08 20:02:36 +00:00
|
|
|
SkPDFDocument doc(&nullStream, SkDocument::PDFMetadata());
|
2017-07-19 19:51:18 +00:00
|
|
|
sk_sp<SkPDFObject> shader = SkPDFMakeShader(&doc, fShader.get(), SkMatrix::I(),
|
|
|
|
{0, 0, 400, 400}, SK_ColorBLACK);
|
2016-03-25 12:52:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-06-23 21:08:11 +00:00
|
|
|
struct WritePDFTextBenchmark : public Benchmark {
|
|
|
|
std::unique_ptr<SkWStream> fWStream;
|
2017-03-22 14:01:53 +00:00
|
|
|
WritePDFTextBenchmark() : fWStream(new SkNullWStream) {}
|
2016-06-23 21:08:11 +00:00
|
|
|
const char* onGetName() override { return "WritePDFText"; }
|
|
|
|
bool isSuitableFor(Backend backend) override {
|
|
|
|
return backend == kNonRendering_Backend;
|
|
|
|
}
|
|
|
|
void onDraw(int loops, SkCanvas*) override {
|
|
|
|
static const char kHello[] = "HELLO SKIA!\n";
|
|
|
|
static const char kBinary[] = "\001\002\003\004\005\006";
|
|
|
|
while (loops-- > 0) {
|
|
|
|
for (int i = 1000; i-- > 0;) {
|
|
|
|
SkPDFUtils::WriteString(fWStream.get(), kHello, strlen(kHello));
|
|
|
|
SkPDFUtils::WriteString(fWStream.get(), kBinary, strlen(kBinary));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-02-24 17:25:58 +00:00
|
|
|
} // namespace
|
|
|
|
DEF_BENCH(return new PDFImageBench;)
|
|
|
|
DEF_BENCH(return new PDFJpegImageBench;)
|
2016-02-24 23:17:19 +00:00
|
|
|
DEF_BENCH(return new PDFCompressionBench;)
|
2016-07-15 20:41:27 +00:00
|
|
|
DEF_BENCH(return new PDFColorComponentBench;)
|
2016-03-25 12:52:57 +00:00
|
|
|
DEF_BENCH(return new PDFShaderBench;)
|
2016-06-23 21:08:11 +00:00
|
|
|
DEF_BENCH(return new WritePDFTextBenchmark;)
|
2016-12-30 18:09:03 +00:00
|
|
|
|
|
|
|
#endif
|
|
|
|
|