Home | History | Annotate | Download | only in bench
      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