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