Add 4f linear gradient benches

Plus some more regular tiling mode variations and random cleanups.

R=reed@google.com,mtklein@google.com
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1728283003

Review URL: https://codereview.chromium.org/1728283003
diff --git a/bench/GradientBench.cpp b/bench/GradientBench.cpp
index 53b9e95..73014f7 100644
--- a/bench/GradientBench.cpp
+++ b/bench/GradientBench.cpp
@@ -10,6 +10,7 @@
 #include "SkCanvas.h"
 #include "SkColorPriv.h"
 #include "SkGradientShader.h"
+#include "SkLinearGradient.h"
 #include "SkPaint.h"
 #include "SkShader.h"
 #include "SkString.h"
@@ -47,12 +48,14 @@
 
 /// Ignores scale
 static SkShader* MakeLinear(const SkPoint pts[2], const GradData& data,
-                            SkShader::TileMode tm, float scale) {
-    return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos, data.fCount, tm);
+                            SkShader::TileMode tm, float scale, bool force4f) {
+    const uint32_t flags = force4f ? SkLinearGradient::kForce4fContext_PrivateFlag : 0;
+    return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos,
+                                          data.fCount, tm, flags, nullptr);
 }
 
 static SkShader* MakeRadial(const SkPoint pts[2], const GradData& data,
-                            SkShader::TileMode tm, float scale) {
+                            SkShader::TileMode tm, float scale, bool force4f) {
     SkPoint center;
     center.set(SkScalarAve(pts[0].fX, pts[1].fX),
                SkScalarAve(pts[0].fY, pts[1].fY));
@@ -63,7 +66,7 @@
 
 /// Ignores scale
 static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data,
-                           SkShader::TileMode tm, float scale) {
+                           SkShader::TileMode tm, float scale, bool force4f) {
     SkPoint center;
     center.set(SkScalarAve(pts[0].fX, pts[1].fX),
                SkScalarAve(pts[0].fY, pts[1].fY));
@@ -73,7 +76,7 @@
 
 /// Ignores scale
 static SkShader* MakeConical(const SkPoint pts[2], const GradData& data,
-                             SkShader::TileMode tm, float scale) {
+                             SkShader::TileMode tm, float scale, bool force4f) {
     SkPoint center0, center1;
     center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
                 SkScalarAve(pts[0].fY, pts[1].fY));
@@ -86,7 +89,7 @@
 
 /// Ignores scale
 static SkShader* MakeConicalZeroRad(const SkPoint pts[2], const GradData& data,
-                                    SkShader::TileMode tm, float scale) {
+                                    SkShader::TileMode tm, float scale, bool force4f) {
     SkPoint center0, center1;
     center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
                 SkScalarAve(pts[0].fY, pts[1].fY));
@@ -99,7 +102,7 @@
 
 /// Ignores scale
 static SkShader* MakeConicalOutside(const SkPoint pts[2], const GradData& data,
-                                    SkShader::TileMode tm, float scale) {
+                                    SkShader::TileMode tm, float scale, bool force4f) {
     SkPoint center0, center1;
     SkScalar radius0 = (pts[1].fX - pts[0].fX) / 10;
     SkScalar radius1 = (pts[1].fX - pts[0].fX) / 3;
@@ -113,7 +116,7 @@
 
 /// Ignores scale
 static SkShader* MakeConicalOutsideZeroRad(const SkPoint pts[2], const GradData& data,
-                                           SkShader::TileMode tm, float scale) {
+                                           SkShader::TileMode tm, float scale, bool force4f) {
     SkPoint center0, center1;
     SkScalar radius0 = (pts[1].fX - pts[0].fX) / 10;
     SkScalar radius1 = (pts[1].fX - pts[0].fX) / 3;
@@ -126,7 +129,7 @@
 }
 
 typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data,
-                               SkShader::TileMode tm, float scale);
+                               SkShader::TileMode tm, float scale, bool force4f);
 
 static const struct {
     GradMaker   fMaker;
@@ -185,33 +188,19 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 class GradientBench : public Benchmark {
-    SkString fName;
-    SkShader* fShader;
-    bool fDither;
-    enum {
-        W   = 400,
-        H   = 400,
-    };
 public:
-    SkShader* makeShader(GradType gradType, GradData data, SkShader::TileMode tm, float scale) {
-        const SkPoint pts[2] = {
-            { 0, 0 },
-            { SkIntToScalar(W), SkIntToScalar(H) }
-        };
-
-        return gGrads[gradType].fMaker(pts, data, tm, scale);
-    }
-
     GradientBench(GradType gradType,
                   GradData data = gGradData[0],
                   SkShader::TileMode tm = SkShader::kClamp_TileMode,
                   GeomType geomType = kRect_GeomType,
-                  float scale = 1.0f) {
+                  float scale = 1.0f,
+                  bool force4f = false)
+        : fGeomType(geomType) {
+
         fName.printf("gradient_%s_%s", gGrads[gradType].fName,
                      tilemodename(tm));
         if (geomType != kRect_GeomType) {
-            fName.append("_");
-            fName.append(geomtypename(geomType));
+            fName.appendf("_%s", geomtypename(geomType));
         }
 
         if (scale != 1.f) {
@@ -220,51 +209,52 @@
 
         fName.append(data.fName);
 
-        fDither = false;
-        fShader = this->makeShader(gradType, data, tm, scale);
-        fGeomType = geomType;
+        if (force4f) {
+            fName.append("_4f");
+        }
+
+        SkAutoTUnref<SkShader> shader(MakeShader(gradType, data, tm, scale, force4f));
+        this->setupPaint(&fPaint);
+        fPaint.setShader(shader);
     }
 
-    GradientBench(GradType gradType, GradData data, bool dither) {
+    GradientBench(GradType gradType, GradData data, bool dither, bool force4f = false)
+        : fGeomType(kRect_GeomType) {
+
         const char *tmname = tilemodename(SkShader::kClamp_TileMode);
         fName.printf("gradient_%s_%s", gGrads[gradType].fName, tmname);
         fName.append(data.fName);
 
-        fDither = dither;
         if (dither) {
             fName.appendf("_dither");
         }
 
-        fShader = this->makeShader(gradType, data, SkShader::kClamp_TileMode, 1.0f);
-        fGeomType = kRect_GeomType;
-    }
-
-    virtual ~GradientBench() {
-        fShader->unref();
+        SkAutoTUnref<SkShader> shader(
+            MakeShader(gradType, data, SkShader::kClamp_TileMode, 1.0f, force4f));
+        this->setupPaint(&fPaint);
+        fPaint.setShader(shader);
+        fPaint.setDither(dither);
     }
 
 protected:
-    virtual const char* onGetName() {
+    const char* onGetName() override {
         return fName.c_str();
     }
 
-    virtual void onDraw(int loops, SkCanvas* canvas) {
-        SkPaint paint;
-        this->setupPaint(&paint);
+    SkIPoint onGetSize() override {
+        return SkIPoint::Make(kSize, kSize);
+    }
 
-        paint.setShader(fShader);
-        if (fDither) {
-            paint.setDither(true);
-        }
+    void onDraw(int loops, SkCanvas* canvas) override {
+        const SkRect r = SkRect::MakeIWH(kSize, kSize);
 
-        SkRect r = { 0, 0, SkIntToScalar(W), SkIntToScalar(H) };
         for (int i = 0; i < loops; i++) {
             switch (fGeomType) {
                case kRect_GeomType:
-                   canvas->drawRect(r, paint);
+                   canvas->drawRect(r, fPaint);
                    break;
                case kOval_GeomType:
-                   canvas->drawOval(r, paint);
+                   canvas->drawOval(r, fPaint);
                    break;
             }
         }
@@ -273,13 +263,52 @@
 private:
     typedef Benchmark INHERITED;
 
-    GeomType fGeomType;
+    SkShader* MakeShader(GradType gradType, GradData data,
+                         SkShader::TileMode tm, float scale, bool force4f) {
+        const SkPoint pts[2] = {
+            { 0, 0 },
+            { SkIntToScalar(kSize), SkIntToScalar(kSize) }
+        };
+
+        return gGrads[gradType].fMaker(pts, data, tm, scale, force4f);
+    }
+
+    static const int kSize = 400;
+
+    SkString       fName;
+    SkPaint        fPaint;
+    const GeomType fGeomType;
 };
 
-DEF_BENCH( return new GradientBench(kLinear_GradType); )
+// 4f
+DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[0], SkShader::kClamp_TileMode,
+                                    kRect_GeomType, 1, true); )
+DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[1], SkShader::kClamp_TileMode,
+                                    kRect_GeomType, 1, true); )
+DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[2], SkShader::kClamp_TileMode,
+                                    kRect_GeomType, 1, true); )
+DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[0], SkShader::kRepeat_TileMode,
+                                    kRect_GeomType, 1, true); )
+DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[1], SkShader::kRepeat_TileMode,
+                                    kRect_GeomType, 1, true); )
+DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[2], SkShader::kRepeat_TileMode,
+                                    kRect_GeomType, 1, true); )
+DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[0], SkShader::kMirror_TileMode,
+                                    kRect_GeomType, 1, true); )
+DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[1], SkShader::kMirror_TileMode,
+                                    kRect_GeomType, 1, true); )
+DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[2], SkShader::kMirror_TileMode,
+                                    kRect_GeomType, 1, true); )
+
+DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[0]); )
 DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[1]); )
 DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[2]); )
+DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[0], SkShader::kRepeat_TileMode); )
+DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[1], SkShader::kRepeat_TileMode); )
+DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[2], SkShader::kRepeat_TileMode); )
 DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[0], SkShader::kMirror_TileMode); )
+DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[1], SkShader::kMirror_TileMode); )
+DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[2], SkShader::kMirror_TileMode); )
 
 DEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[0]); )
 DEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[1]); )