Image Encoder:  more benches

Change-Id: I35973ee9223c2db3e2250dae4c5dd3cc13a5aa92
Reviewed-on: https://skia-review.googlesource.com/20156
Reviewed-by: Matt Sarett <msarett@google.com>
Commit-Queue: Hal Canary <halcanary@google.com>
diff --git a/bench/EncoderBench.cpp b/bench/EncoderBench.cpp
index f0adaa1..44c459f 100644
--- a/bench/EncoderBench.cpp
+++ b/bench/EncoderBench.cpp
@@ -8,76 +8,115 @@
 #include "Benchmark.h"
 #include "Resources.h"
 #include "SkBitmap.h"
-#include "SkData.h"
-#include "SkImageEncoder.h"
-
-#include "sk_tool_utils.h"
+#include "SkJpegEncoder.h"
+#include "SkPngEncoder.h"
+#include "SkWebpEncoder.h"
+#include "SkStream.h"
 
 class EncodeBench : public Benchmark {
 public:
-    EncodeBench(const char* filename, SkEncodedImageFormat type, int quality)
-        : fFilename(filename)
-        , fType(type)
-        , fQuality(quality)
-    {
-        // Set the name of the bench
-        SkString name("Encode_");
-        name.append(filename);
-        name.append("_");
-        switch (type) {
-            case SkEncodedImageFormat::kJPEG:
-                name.append("JPEG");
-                break;
-            case SkEncodedImageFormat::kPNG:
-                name.append("PNG");
-                break;
-            case SkEncodedImageFormat::kWEBP:
-                name.append("WEBP");
-                break;
-            default:
-                name.append("Unknown");
-                break;
-        }
-        
-        fName = name;
-    }
+    using Encoder = bool (*)(SkWStream*, const SkPixmap&);
+    EncodeBench(const char* filename, Encoder encoder, const char* encoderName)
+        : fSourceFilename(filename)
+        , fEncoder(encoder)
+        , fName(SkStringPrintf("Encode_%s_%s", filename, encoderName)) {}
 
     bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
-    
+
     const char* onGetName() override { return fName.c_str(); }
-    
+
     void onPreDraw(SkCanvas*) override {
-#ifdef SK_DEBUG
-        bool result =
-#endif
-        GetResourceAsBitmap(fFilename, &fBitmap);
-        SkASSERT(result);
+        SkAssertResult(GetResourceAsBitmap(fSourceFilename, &fBitmap));
     }
 
     void onDraw(int loops, SkCanvas*) override {
-        for (int i = 0; i < loops; i++) {
-            sk_sp<SkData> data(sk_tool_utils::EncodeImageToData(fBitmap, fType, fQuality));
-            SkASSERT(data);
+        while (loops-- > 0) {
+            SkPixmap pixmap;
+            SkAssertResult(fBitmap.peekPixels(&pixmap));
+            SkNullWStream dst;
+            SkAssertResult(fEncoder(&dst, pixmap));
+            SkASSERT(dst.bytesWritten() > 0);
         }
     }
 
 private:
-    const char*                fFilename;
-    const SkEncodedImageFormat fType;
-    const int                  fQuality;
-    SkString                   fName;
-    SkBitmap                   fBitmap;
+    const char* fSourceFilename;
+    Encoder     fEncoder;
+    SkString    fName;
+    SkBitmap    fBitmap;
 };
 
+static bool encode_jpeg(SkWStream* dst, const SkPixmap& src) {
+    SkJpegEncoder::Options opts;
+    opts.fQuality = 90;
+    return SkJpegEncoder::Encode(dst, src, opts);
+}
+
+static bool encode_webp_lossy(SkWStream* dst, const SkPixmap& src) {
+    SkWebpEncoder::Options opts;
+    opts.fCompression = SkWebpEncoder::Compression::kLossy;
+    opts.fQuality = 90;
+    opts.fUnpremulBehavior = SkTransferFunctionBehavior::kIgnore;
+    return SkWebpEncoder::Encode(dst, src, opts);
+}
+
+static bool encode_webp_lossless(SkWStream* dst, const SkPixmap& src) {
+    SkWebpEncoder::Options opts;
+    opts.fCompression = SkWebpEncoder::Compression::kLossless;
+    opts.fQuality = 90;
+    opts.fUnpremulBehavior = SkTransferFunctionBehavior::kIgnore;
+    return SkWebpEncoder::Encode(dst, src, opts);
+}
+
+static bool encode_png(SkWStream* dst,
+                       const SkPixmap& src,
+                       SkPngEncoder::FilterFlag filters,
+                       int zlibLevel) {
+    SkPngEncoder::Options opts;
+    opts.fFilterFlags = filters;
+    opts.fUnpremulBehavior = SkTransferFunctionBehavior::kIgnore;
+    opts.fZLibLevel = zlibLevel;
+    return SkPngEncoder::Encode(dst, src, opts);
+}
+
+#define PNG(FLAG, ZLIBLEVEL) [](SkWStream* d, const SkPixmap& s) { \
+           return encode_png(d, s, SkPngEncoder::FilterFlag::FLAG, ZLIBLEVEL); }
+
+static const char* srcs[2] = {"mandrill_512.png", "color_wheel.jpg"};
 
 // The Android Photos app uses a quality of 90 on JPEG encodes
-DEF_BENCH(return new EncodeBench("mandrill_512.png", SkEncodedImageFormat::kJPEG, 90));
-DEF_BENCH(return new EncodeBench("color_wheel.jpg", SkEncodedImageFormat::kJPEG, 90));
-
-// PNG encodes are lossless so quality should be ignored
-DEF_BENCH(return new EncodeBench("mandrill_512.png", SkEncodedImageFormat::kPNG, 90));
-DEF_BENCH(return new EncodeBench("color_wheel.jpg", SkEncodedImageFormat::kPNG, 90));
+DEF_BENCH(return new EncodeBench(srcs[0], &encode_jpeg, "JPEG"));
+DEF_BENCH(return new EncodeBench(srcs[1], &encode_jpeg, "JPEG"));
 
 // TODO: What is the appropriate quality to use to benchmark WEBP encodes?
-DEF_BENCH(return new EncodeBench("mandrill_512.png", SkEncodedImageFormat::kWEBP, 90));
-DEF_BENCH(return new EncodeBench("color_wheel.jpg", SkEncodedImageFormat::kWEBP, 90));
+DEF_BENCH(return new EncodeBench(srcs[0], encode_webp_lossy, "WEBP"));
+DEF_BENCH(return new EncodeBench(srcs[1], encode_webp_lossy, "WEBP"));
+
+DEF_BENCH(return new EncodeBench(srcs[0], encode_webp_lossless, "WEBP_LL"));
+DEF_BENCH(return new EncodeBench(srcs[1], encode_webp_lossless, "WEBP_LL"));
+
+DEF_BENCH(return new EncodeBench(srcs[0], PNG(kAll, 6), "PNG"));
+DEF_BENCH(return new EncodeBench(srcs[0], PNG(kAll, 3), "PNG_3"));
+DEF_BENCH(return new EncodeBench(srcs[0], PNG(kAll, 1), "PNG_1"));
+
+DEF_BENCH(return new EncodeBench(srcs[0], PNG(kSub, 6), "PNG_6s"));
+DEF_BENCH(return new EncodeBench(srcs[0], PNG(kSub, 3), "PNG_3s"));
+DEF_BENCH(return new EncodeBench(srcs[0], PNG(kSub, 1), "PNG_1s"));
+
+DEF_BENCH(return new EncodeBench(srcs[0], PNG(kNone, 6), "PNG_6n"));
+DEF_BENCH(return new EncodeBench(srcs[0], PNG(kNone, 3), "PNG_3n"));
+DEF_BENCH(return new EncodeBench(srcs[0], PNG(kNone, 1), "PNG_1n"));
+
+DEF_BENCH(return new EncodeBench(srcs[1], PNG(kAll, 6), "PNG"));
+DEF_BENCH(return new EncodeBench(srcs[1], PNG(kAll, 3), "PNG_3"));
+DEF_BENCH(return new EncodeBench(srcs[1], PNG(kAll, 1), "PNG_1"));
+
+DEF_BENCH(return new EncodeBench(srcs[1], PNG(kSub, 6), "PNG_6s"));
+DEF_BENCH(return new EncodeBench(srcs[1], PNG(kSub, 3), "PNG_3s"));
+DEF_BENCH(return new EncodeBench(srcs[1], PNG(kSub, 1), "PNG_1s"));
+
+DEF_BENCH(return new EncodeBench(srcs[1], PNG(kNone, 6), "PNG_6n"));
+DEF_BENCH(return new EncodeBench(srcs[1], PNG(kNone, 3), "PNG_3n"));
+DEF_BENCH(return new EncodeBench(srcs[1], PNG(kNone, 1), "PNG_1n"));
+
+#undef PNG