| /* | 
 |  * 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 "bench/Benchmark.h" | 
 | #include "include/core/SkBitmap.h" | 
 | #include "include/core/SkStream.h" | 
 | #include "include/encode/SkJpegEncoder.h" | 
 | #include "include/encode/SkPngEncoder.h" | 
 | #include "include/encode/SkWebpEncoder.h" | 
 | #include "tools/Resources.h" | 
 |  | 
 | // Like other Benchmark subclasses, Encoder benchmarks are run by: | 
 | // nanobench --match ^Encode_ | 
 | // | 
 | // There is no corresponding DecodeBench class. Decoder benchmarks are run by: | 
 | // nanobench --benchType skcodec --images your_images_directory | 
 |  | 
 | class EncodeBench : public Benchmark { | 
 | public: | 
 |     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 onDelayedSetup() override { | 
 |         SkAssertResult(GetResourceAsBitmap(fSourceFilename, &fBitmap)); | 
 |     } | 
 |  | 
 |     void onDraw(int loops, SkCanvas*) override { | 
 |         while (loops-- > 0) { | 
 |             SkPixmap pixmap; | 
 |             SkAssertResult(fBitmap.peekPixels(&pixmap)); | 
 |             SkNullWStream dst; | 
 |             SkAssertResult(fEncoder(&dst, pixmap)); | 
 |             SkASSERT(dst.bytesWritten() > 0); | 
 |         } | 
 |     } | 
 |  | 
 | private: | 
 |     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); | 
 | } | 
 |  | 
 | static bool encode_webp_lossy(SkWStream* dst, const SkPixmap& src) { | 
 |     SkWebpEncoder::Options opts; | 
 |     opts.fCompression = SkWebpEncoder::Compression::kLossy; | 
 |     opts.fQuality = 90; | 
 |     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; | 
 |     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.fZLibLevel = zlibLevel; | 
 |     return SkPngEncoder::Encode(dst, src, opts); | 
 | } | 
 |  | 
 | #define PNG(FLAG, ZLIBLEVEL) [](SkWStream* d, const SkPixmap& s) { \ | 
 |            return encode_png(d, s, SkPngEncoder::FilterFlag::FLAG, ZLIBLEVEL); } | 
 |  | 
 | static const char* srcs[2] = {"images/mandrill_512.png", "images/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(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 |