From 05784d9b1a0b63332fbc3aa8b022ece03d156358 Mon Sep 17 00:00:00 2001 From: Hal Canary Date: Fri, 16 Jun 2017 16:52:10 -0400 Subject: Image Encoder: more benches Change-Id: I35973ee9223c2db3e2250dae4c5dd3cc13a5aa92 Reviewed-on: https://skia-review.googlesource.com/20156 Reviewed-by: Matt Sarett Commit-Queue: Hal Canary --- bench/EncoderBench.cpp | 145 +++++++++++++++++++++++++++++++------------------ 1 file changed, 92 insertions(+), 53 deletions(-) (limited to 'bench/EncoderBench.cpp') diff --git a/bench/EncoderBench.cpp b/bench/EncoderBench.cpp index f0adaa1071..44c459fa80 100644 --- a/bench/EncoderBench.cpp +++ b/bench/EncoderBench.cpp @@ -8,76 +8,115 @@ #include "Benchmark.h" #include "Resources.h" #include "SkBitmap.h" -#include "SkData.h" -#include "SkImageEncoder.h" - -#include "sk_tool_utils.h" +#include "SkJpegEncoder.h" +#include "SkPngEncoder.h" +#include "SkWebpEncoder.h" +#include "SkStream.h" class EncodeBench : public Benchmark { public: - EncodeBench(const char* filename, SkEncodedImageFormat type, int quality) - : fFilename(filename) - , fType(type) - , fQuality(quality) - { - // Set the name of the bench - SkString name("Encode_"); - name.append(filename); - name.append("_"); - switch (type) { - case SkEncodedImageFormat::kJPEG: - name.append("JPEG"); - break; - case SkEncodedImageFormat::kPNG: - name.append("PNG"); - break; - case SkEncodedImageFormat::kWEBP: - name.append("WEBP"); - break; - default: - name.append("Unknown"); - break; - } - - fName = name; - } + using Encoder = bool (*)(SkWStream*, const SkPixmap&); + EncodeBench(const char* filename, Encoder encoder, const char* encoderName) + : fSourceFilename(filename) + , fEncoder(encoder) + , fName(SkStringPrintf("Encode_%s_%s", filename, encoderName)) {} bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; } - + const char* onGetName() override { return fName.c_str(); } - + void onPreDraw(SkCanvas*) override { -#ifdef SK_DEBUG - bool result = -#endif - GetResourceAsBitmap(fFilename, &fBitmap); - SkASSERT(result); + SkAssertResult(GetResourceAsBitmap(fSourceFilename, &fBitmap)); } void onDraw(int loops, SkCanvas*) override { - for (int i = 0; i < loops; i++) { - sk_sp data(sk_tool_utils::EncodeImageToData(fBitmap, fType, fQuality)); - SkASSERT(data); + while (loops-- > 0) { + SkPixmap pixmap; + SkAssertResult(fBitmap.peekPixels(&pixmap)); + SkNullWStream dst; + SkAssertResult(fEncoder(&dst, pixmap)); + SkASSERT(dst.bytesWritten() > 0); } } private: - const char* fFilename; - const SkEncodedImageFormat fType; - const int fQuality; - SkString fName; - SkBitmap fBitmap; + const char* fSourceFilename; + Encoder fEncoder; + SkString fName; + SkBitmap fBitmap; }; +static bool encode_jpeg(SkWStream* dst, const SkPixmap& src) { + SkJpegEncoder::Options opts; + opts.fQuality = 90; + return SkJpegEncoder::Encode(dst, src, opts); +} -// The Android Photos app uses a quality of 90 on JPEG encodes -DEF_BENCH(return new EncodeBench("mandrill_512.png", SkEncodedImageFormat::kJPEG, 90)); -DEF_BENCH(return new EncodeBench("color_wheel.jpg", SkEncodedImageFormat::kJPEG, 90)); +static bool encode_webp_lossy(SkWStream* dst, const SkPixmap& src) { + SkWebpEncoder::Options opts; + opts.fCompression = SkWebpEncoder::Compression::kLossy; + opts.fQuality = 90; + opts.fUnpremulBehavior = SkTransferFunctionBehavior::kIgnore; + return SkWebpEncoder::Encode(dst, src, opts); +} + +static bool encode_webp_lossless(SkWStream* dst, const SkPixmap& src) { + SkWebpEncoder::Options opts; + opts.fCompression = SkWebpEncoder::Compression::kLossless; + opts.fQuality = 90; + opts.fUnpremulBehavior = SkTransferFunctionBehavior::kIgnore; + return SkWebpEncoder::Encode(dst, src, opts); +} + +static bool encode_png(SkWStream* dst, + const SkPixmap& src, + SkPngEncoder::FilterFlag filters, + int zlibLevel) { + SkPngEncoder::Options opts; + opts.fFilterFlags = filters; + opts.fUnpremulBehavior = SkTransferFunctionBehavior::kIgnore; + opts.fZLibLevel = zlibLevel; + return SkPngEncoder::Encode(dst, src, opts); +} -// PNG encodes are lossless so quality should be ignored -DEF_BENCH(return new EncodeBench("mandrill_512.png", SkEncodedImageFormat::kPNG, 90)); -DEF_BENCH(return new EncodeBench("color_wheel.jpg", SkEncodedImageFormat::kPNG, 90)); +#define PNG(FLAG, ZLIBLEVEL) [](SkWStream* d, const SkPixmap& s) { \ + return encode_png(d, s, SkPngEncoder::FilterFlag::FLAG, ZLIBLEVEL); } + +static const char* srcs[2] = {"mandrill_512.png", "color_wheel.jpg"}; + +// The Android Photos app uses a quality of 90 on JPEG encodes +DEF_BENCH(return new EncodeBench(srcs[0], &encode_jpeg, "JPEG")); +DEF_BENCH(return new EncodeBench(srcs[1], &encode_jpeg, "JPEG")); // TODO: What is the appropriate quality to use to benchmark WEBP encodes? -DEF_BENCH(return new EncodeBench("mandrill_512.png", SkEncodedImageFormat::kWEBP, 90)); -DEF_BENCH(return new EncodeBench("color_wheel.jpg", SkEncodedImageFormat::kWEBP, 90)); +DEF_BENCH(return new EncodeBench(srcs[0], encode_webp_lossy, "WEBP")); +DEF_BENCH(return new EncodeBench(srcs[1], encode_webp_lossy, "WEBP")); + +DEF_BENCH(return new EncodeBench(srcs[0], encode_webp_lossless, "WEBP_LL")); +DEF_BENCH(return new EncodeBench(srcs[1], encode_webp_lossless, "WEBP_LL")); + +DEF_BENCH(return new EncodeBench(srcs[0], PNG(kAll, 6), "PNG")); +DEF_BENCH(return new EncodeBench(srcs[0], PNG(kAll, 3), "PNG_3")); +DEF_BENCH(return new EncodeBench(srcs[0], PNG(kAll, 1), "PNG_1")); + +DEF_BENCH(return new EncodeBench(srcs[0], PNG(kSub, 6), "PNG_6s")); +DEF_BENCH(return new EncodeBench(srcs[0], PNG(kSub, 3), "PNG_3s")); +DEF_BENCH(return new EncodeBench(srcs[0], PNG(kSub, 1), "PNG_1s")); + +DEF_BENCH(return new EncodeBench(srcs[0], PNG(kNone, 6), "PNG_6n")); +DEF_BENCH(return new EncodeBench(srcs[0], PNG(kNone, 3), "PNG_3n")); +DEF_BENCH(return new EncodeBench(srcs[0], PNG(kNone, 1), "PNG_1n")); + +DEF_BENCH(return new EncodeBench(srcs[1], PNG(kAll, 6), "PNG")); +DEF_BENCH(return new EncodeBench(srcs[1], PNG(kAll, 3), "PNG_3")); +DEF_BENCH(return new EncodeBench(srcs[1], PNG(kAll, 1), "PNG_1")); + +DEF_BENCH(return new EncodeBench(srcs[1], PNG(kSub, 6), "PNG_6s")); +DEF_BENCH(return new EncodeBench(srcs[1], PNG(kSub, 3), "PNG_3s")); +DEF_BENCH(return new EncodeBench(srcs[1], PNG(kSub, 1), "PNG_1s")); + +DEF_BENCH(return new EncodeBench(srcs[1], PNG(kNone, 6), "PNG_6n")); +DEF_BENCH(return new EncodeBench(srcs[1], PNG(kNone, 3), "PNG_3n")); +DEF_BENCH(return new EncodeBench(srcs[1], PNG(kNone, 1), "PNG_1n")); + +#undef PNG -- cgit v1.2.3