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