1b92dc7ac0bd4109411851d7d3684ed3aa7108086msarett/*
2b92dc7ac0bd4109411851d7d3684ed3aa7108086msarett * Copyright 2016 Google Inc.
3b92dc7ac0bd4109411851d7d3684ed3aa7108086msarett *
4b92dc7ac0bd4109411851d7d3684ed3aa7108086msarett * Use of this source code is governed by a BSD-style license that can be
5b92dc7ac0bd4109411851d7d3684ed3aa7108086msarett * found in the LICENSE file.
6b92dc7ac0bd4109411851d7d3684ed3aa7108086msarett */
7b92dc7ac0bd4109411851d7d3684ed3aa7108086msarett
8b92dc7ac0bd4109411851d7d3684ed3aa7108086msarett#include "Benchmark.h"
9b92dc7ac0bd4109411851d7d3684ed3aa7108086msarett#include "Resources.h"
10b92dc7ac0bd4109411851d7d3684ed3aa7108086msarett#include "SkBitmap.h"
1105784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary#include "SkJpegEncoder.h"
1205784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary#include "SkPngEncoder.h"
1305784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary#include "SkWebpEncoder.h"
1405784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary#include "SkStream.h"
15db6830162eca5b94e61d9825ec93306fc615d204Hal Canary
16b92dc7ac0bd4109411851d7d3684ed3aa7108086msarettclass EncodeBench : public Benchmark {
17b92dc7ac0bd4109411851d7d3684ed3aa7108086msarettpublic:
1805784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary    using Encoder = bool (*)(SkWStream*, const SkPixmap&);
1905784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary    EncodeBench(const char* filename, Encoder encoder, const char* encoderName)
2005784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary        : fSourceFilename(filename)
2105784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary        , fEncoder(encoder)
2205784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary        , fName(SkStringPrintf("Encode_%s_%s", filename, encoderName)) {}
23b92dc7ac0bd4109411851d7d3684ed3aa7108086msarett
24b92dc7ac0bd4109411851d7d3684ed3aa7108086msarett    bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
2505784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary
26b92dc7ac0bd4109411851d7d3684ed3aa7108086msarett    const char* onGetName() override { return fName.c_str(); }
2705784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary
28b92dc7ac0bd4109411851d7d3684ed3aa7108086msarett    void onPreDraw(SkCanvas*) override {
2905784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary        SkAssertResult(GetResourceAsBitmap(fSourceFilename, &fBitmap));
30b92dc7ac0bd4109411851d7d3684ed3aa7108086msarett    }
31b92dc7ac0bd4109411851d7d3684ed3aa7108086msarett
32b92dc7ac0bd4109411851d7d3684ed3aa7108086msarett    void onDraw(int loops, SkCanvas*) override {
3305784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary        while (loops-- > 0) {
3405784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary            SkPixmap pixmap;
3505784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary            SkAssertResult(fBitmap.peekPixels(&pixmap));
3605784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary            SkNullWStream dst;
3705784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary            SkAssertResult(fEncoder(&dst, pixmap));
3805784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary            SkASSERT(dst.bytesWritten() > 0);
39b92dc7ac0bd4109411851d7d3684ed3aa7108086msarett        }
40b92dc7ac0bd4109411851d7d3684ed3aa7108086msarett    }
41b92dc7ac0bd4109411851d7d3684ed3aa7108086msarett
42b92dc7ac0bd4109411851d7d3684ed3aa7108086msarettprivate:
4305784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary    const char* fSourceFilename;
4405784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary    Encoder     fEncoder;
4505784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary    SkString    fName;
4605784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary    SkBitmap    fBitmap;
47b92dc7ac0bd4109411851d7d3684ed3aa7108086msarett};
48b92dc7ac0bd4109411851d7d3684ed3aa7108086msarett
4905784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canarystatic bool encode_jpeg(SkWStream* dst, const SkPixmap& src) {
5005784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary    SkJpegEncoder::Options opts;
5105784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary    opts.fQuality = 90;
5205784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary    return SkJpegEncoder::Encode(dst, src, opts);
5305784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary}
54b92dc7ac0bd4109411851d7d3684ed3aa7108086msarett
5505784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canarystatic bool encode_webp_lossy(SkWStream* dst, const SkPixmap& src) {
5605784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary    SkWebpEncoder::Options opts;
5705784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary    opts.fCompression = SkWebpEncoder::Compression::kLossy;
5805784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary    opts.fQuality = 90;
5905784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary    opts.fUnpremulBehavior = SkTransferFunctionBehavior::kIgnore;
6005784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary    return SkWebpEncoder::Encode(dst, src, opts);
6105784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary}
6205784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary
6305784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canarystatic bool encode_webp_lossless(SkWStream* dst, const SkPixmap& src) {
6405784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary    SkWebpEncoder::Options opts;
6505784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary    opts.fCompression = SkWebpEncoder::Compression::kLossless;
6605784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary    opts.fQuality = 90;
6705784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary    opts.fUnpremulBehavior = SkTransferFunctionBehavior::kIgnore;
6805784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary    return SkWebpEncoder::Encode(dst, src, opts);
6905784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary}
7005784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary
7105784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canarystatic bool encode_png(SkWStream* dst,
7205784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary                       const SkPixmap& src,
7305784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary                       SkPngEncoder::FilterFlag filters,
7405784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary                       int zlibLevel) {
7505784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary    SkPngEncoder::Options opts;
7605784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary    opts.fFilterFlags = filters;
7705784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary    opts.fUnpremulBehavior = SkTransferFunctionBehavior::kIgnore;
7805784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary    opts.fZLibLevel = zlibLevel;
7905784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary    return SkPngEncoder::Encode(dst, src, opts);
8005784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary}
81b92dc7ac0bd4109411851d7d3684ed3aa7108086msarett
8205784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary#define PNG(FLAG, ZLIBLEVEL) [](SkWStream* d, const SkPixmap& s) { \
8305784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary           return encode_png(d, s, SkPngEncoder::FilterFlag::FLAG, ZLIBLEVEL); }
8405784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary
85c465d13e6fca5e171bde45d35b2dd43117f4702eHal Canarystatic const char* srcs[2] = {"images/mandrill_512.png", "images/color_wheel.jpg"};
8605784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary
8705784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary// The Android Photos app uses a quality of 90 on JPEG encodes
8805784d9b1a0b63332fbc3aa8b022ece03d156358Hal CanaryDEF_BENCH(return new EncodeBench(srcs[0], &encode_jpeg, "JPEG"));
8905784d9b1a0b63332fbc3aa8b022ece03d156358Hal CanaryDEF_BENCH(return new EncodeBench(srcs[1], &encode_jpeg, "JPEG"));
90b92dc7ac0bd4109411851d7d3684ed3aa7108086msarett
91b92dc7ac0bd4109411851d7d3684ed3aa7108086msarett// TODO: What is the appropriate quality to use to benchmark WEBP encodes?
9205784d9b1a0b63332fbc3aa8b022ece03d156358Hal CanaryDEF_BENCH(return new EncodeBench(srcs[0], encode_webp_lossy, "WEBP"));
9305784d9b1a0b63332fbc3aa8b022ece03d156358Hal CanaryDEF_BENCH(return new EncodeBench(srcs[1], encode_webp_lossy, "WEBP"));
9405784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary
9505784d9b1a0b63332fbc3aa8b022ece03d156358Hal CanaryDEF_BENCH(return new EncodeBench(srcs[0], encode_webp_lossless, "WEBP_LL"));
9605784d9b1a0b63332fbc3aa8b022ece03d156358Hal CanaryDEF_BENCH(return new EncodeBench(srcs[1], encode_webp_lossless, "WEBP_LL"));
9705784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary
9805784d9b1a0b63332fbc3aa8b022ece03d156358Hal CanaryDEF_BENCH(return new EncodeBench(srcs[0], PNG(kAll, 6), "PNG"));
9905784d9b1a0b63332fbc3aa8b022ece03d156358Hal CanaryDEF_BENCH(return new EncodeBench(srcs[0], PNG(kAll, 3), "PNG_3"));
10005784d9b1a0b63332fbc3aa8b022ece03d156358Hal CanaryDEF_BENCH(return new EncodeBench(srcs[0], PNG(kAll, 1), "PNG_1"));
10105784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary
10205784d9b1a0b63332fbc3aa8b022ece03d156358Hal CanaryDEF_BENCH(return new EncodeBench(srcs[0], PNG(kSub, 6), "PNG_6s"));
10305784d9b1a0b63332fbc3aa8b022ece03d156358Hal CanaryDEF_BENCH(return new EncodeBench(srcs[0], PNG(kSub, 3), "PNG_3s"));
10405784d9b1a0b63332fbc3aa8b022ece03d156358Hal CanaryDEF_BENCH(return new EncodeBench(srcs[0], PNG(kSub, 1), "PNG_1s"));
10505784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary
10605784d9b1a0b63332fbc3aa8b022ece03d156358Hal CanaryDEF_BENCH(return new EncodeBench(srcs[0], PNG(kNone, 6), "PNG_6n"));
10705784d9b1a0b63332fbc3aa8b022ece03d156358Hal CanaryDEF_BENCH(return new EncodeBench(srcs[0], PNG(kNone, 3), "PNG_3n"));
10805784d9b1a0b63332fbc3aa8b022ece03d156358Hal CanaryDEF_BENCH(return new EncodeBench(srcs[0], PNG(kNone, 1), "PNG_1n"));
10905784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary
11005784d9b1a0b63332fbc3aa8b022ece03d156358Hal CanaryDEF_BENCH(return new EncodeBench(srcs[1], PNG(kAll, 6), "PNG"));
11105784d9b1a0b63332fbc3aa8b022ece03d156358Hal CanaryDEF_BENCH(return new EncodeBench(srcs[1], PNG(kAll, 3), "PNG_3"));
11205784d9b1a0b63332fbc3aa8b022ece03d156358Hal CanaryDEF_BENCH(return new EncodeBench(srcs[1], PNG(kAll, 1), "PNG_1"));
11305784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary
11405784d9b1a0b63332fbc3aa8b022ece03d156358Hal CanaryDEF_BENCH(return new EncodeBench(srcs[1], PNG(kSub, 6), "PNG_6s"));
11505784d9b1a0b63332fbc3aa8b022ece03d156358Hal CanaryDEF_BENCH(return new EncodeBench(srcs[1], PNG(kSub, 3), "PNG_3s"));
11605784d9b1a0b63332fbc3aa8b022ece03d156358Hal CanaryDEF_BENCH(return new EncodeBench(srcs[1], PNG(kSub, 1), "PNG_1s"));
11705784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary
11805784d9b1a0b63332fbc3aa8b022ece03d156358Hal CanaryDEF_BENCH(return new EncodeBench(srcs[1], PNG(kNone, 6), "PNG_6n"));
11905784d9b1a0b63332fbc3aa8b022ece03d156358Hal CanaryDEF_BENCH(return new EncodeBench(srcs[1], PNG(kNone, 3), "PNG_3n"));
12005784d9b1a0b63332fbc3aa8b022ece03d156358Hal CanaryDEF_BENCH(return new EncodeBench(srcs[1], PNG(kNone, 1), "PNG_1n"));
12105784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary
12205784d9b1a0b63332fbc3aa8b022ece03d156358Hal Canary#undef PNG
123