1 /* 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" 9 #include "Resources.h" 10 #include "SkBitmap.h" 11 #include "SkJpegEncoder.h" 12 #include "SkPngEncoder.h" 13 #include "SkWebpEncoder.h" 14 #include "SkStream.h" 15 16 // Like other Benchmark subclasses, Encoder benchmarks are run by: 17 // nanobench --match ^Encode_ 18 // 19 // There is no corresponding DecodeBench class. Decoder benchmarks are run by: 20 // nanobench --benchType skcodec --images your_images_directory 21 22 class EncodeBench : public Benchmark { 23 public: 24 using Encoder = bool (*)(SkWStream*, const SkPixmap&); 25 EncodeBench(const char* filename, Encoder encoder, const char* encoderName) 26 : fSourceFilename(filename) 27 , fEncoder(encoder) 28 , fName(SkStringPrintf("Encode_%s_%s", filename, encoderName)) {} 29 30 bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; } 31 32 const char* onGetName() override { return fName.c_str(); } 33 34 void onDelayedSetup() override { 35 SkAssertResult(GetResourceAsBitmap(fSourceFilename, &fBitmap)); 36 } 37 38 void onDraw(int loops, SkCanvas*) override { 39 while (loops-- > 0) { 40 SkPixmap pixmap; 41 SkAssertResult(fBitmap.peekPixels(&pixmap)); 42 SkNullWStream dst; 43 SkAssertResult(fEncoder(&dst, pixmap)); 44 SkASSERT(dst.bytesWritten() > 0); 45 } 46 } 47 48 private: 49 const char* fSourceFilename; 50 Encoder fEncoder; 51 SkString fName; 52 SkBitmap fBitmap; 53 }; 54 55 static bool encode_jpeg(SkWStream* dst, const SkPixmap& src) { 56 SkJpegEncoder::Options opts; 57 opts.fQuality = 90; 58 return SkJpegEncoder::Encode(dst, src, opts); 59 } 60 61 static bool encode_webp_lossy(SkWStream* dst, const SkPixmap& src) { 62 SkWebpEncoder::Options opts; 63 opts.fCompression = SkWebpEncoder::Compression::kLossy; 64 opts.fQuality = 90; 65 return SkWebpEncoder::Encode(dst, src, opts); 66 } 67 68 static bool encode_webp_lossless(SkWStream* dst, const SkPixmap& src) { 69 SkWebpEncoder::Options opts; 70 opts.fCompression = SkWebpEncoder::Compression::kLossless; 71 opts.fQuality = 90; 72 return SkWebpEncoder::Encode(dst, src, opts); 73 } 74 75 static bool encode_png(SkWStream* dst, 76 const SkPixmap& src, 77 SkPngEncoder::FilterFlag filters, 78 int zlibLevel) { 79 SkPngEncoder::Options opts; 80 opts.fFilterFlags = filters; 81 opts.fZLibLevel = zlibLevel; 82 return SkPngEncoder::Encode(dst, src, opts); 83 } 84 85 #define PNG(FLAG, ZLIBLEVEL) [](SkWStream* d, const SkPixmap& s) { \ 86 return encode_png(d, s, SkPngEncoder::FilterFlag::FLAG, ZLIBLEVEL); } 87 88 static const char* srcs[2] = {"images/mandrill_512.png", "images/color_wheel.jpg"}; 89 90 // The Android Photos app uses a quality of 90 on JPEG encodes 91 DEF_BENCH(return new EncodeBench(srcs[0], &encode_jpeg, "JPEG")); 92 DEF_BENCH(return new EncodeBench(srcs[1], &encode_jpeg, "JPEG")); 93 94 // TODO: What is the appropriate quality to use to benchmark WEBP encodes? 95 DEF_BENCH(return new EncodeBench(srcs[0], encode_webp_lossy, "WEBP")); 96 DEF_BENCH(return new EncodeBench(srcs[1], encode_webp_lossy, "WEBP")); 97 98 DEF_BENCH(return new EncodeBench(srcs[0], encode_webp_lossless, "WEBP_LL")); 99 DEF_BENCH(return new EncodeBench(srcs[1], encode_webp_lossless, "WEBP_LL")); 100 101 DEF_BENCH(return new EncodeBench(srcs[0], PNG(kAll, 6), "PNG")); 102 DEF_BENCH(return new EncodeBench(srcs[0], PNG(kAll, 3), "PNG_3")); 103 DEF_BENCH(return new EncodeBench(srcs[0], PNG(kAll, 1), "PNG_1")); 104 105 DEF_BENCH(return new EncodeBench(srcs[0], PNG(kSub, 6), "PNG_6s")); 106 DEF_BENCH(return new EncodeBench(srcs[0], PNG(kSub, 3), "PNG_3s")); 107 DEF_BENCH(return new EncodeBench(srcs[0], PNG(kSub, 1), "PNG_1s")); 108 109 DEF_BENCH(return new EncodeBench(srcs[0], PNG(kNone, 6), "PNG_6n")); 110 DEF_BENCH(return new EncodeBench(srcs[0], PNG(kNone, 3), "PNG_3n")); 111 DEF_BENCH(return new EncodeBench(srcs[0], PNG(kNone, 1), "PNG_1n")); 112 113 DEF_BENCH(return new EncodeBench(srcs[1], PNG(kAll, 6), "PNG")); 114 DEF_BENCH(return new EncodeBench(srcs[1], PNG(kAll, 3), "PNG_3")); 115 DEF_BENCH(return new EncodeBench(srcs[1], PNG(kAll, 1), "PNG_1")); 116 117 DEF_BENCH(return new EncodeBench(srcs[1], PNG(kSub, 6), "PNG_6s")); 118 DEF_BENCH(return new EncodeBench(srcs[1], PNG(kSub, 3), "PNG_3s")); 119 DEF_BENCH(return new EncodeBench(srcs[1], PNG(kSub, 1), "PNG_1s")); 120 121 DEF_BENCH(return new EncodeBench(srcs[1], PNG(kNone, 6), "PNG_6n")); 122 DEF_BENCH(return new EncodeBench(srcs[1], PNG(kNone, 3), "PNG_3n")); 123 DEF_BENCH(return new EncodeBench(srcs[1], PNG(kNone, 1), "PNG_1n")); 124 125 #undef PNG 126