4-at-a-time SkPMColor -> SkPMFloat API.

Please see if this looks usable.  It may even give a perf boost if you use it, even without custom implementations for each instruction set.

I've been trying this morning to beat this naive loop implementation, but so far no luck with either _SSE2.h or _SSSE3.h.  It's possible this is an artifact of the microbenchmark, because we're not doing anything between the conversions.  I'd like to see how this fits into real code, what assembly's generated, what the hot spots are, etc.

I've updated the tests to test these new APIs, and splintered off a pair of new benchmarks that use the new APIs.  This required some minor rejiggering in the benches.

BUG=skia:

Review URL: https://codereview.chromium.org/978213003
diff --git a/bench/PMFloatBench.cpp b/bench/PMFloatBench.cpp
index ee4914a..1da667f 100644
--- a/bench/PMFloatBench.cpp
+++ b/bench/PMFloatBench.cpp
@@ -12,10 +12,21 @@
     return *seed;
 }
 
+// I'm having better luck getting these to constant-propagate away as template parameters.
+template <bool kClamp, bool kWide>
 struct PMFloatBench : public Benchmark {
-    explicit PMFloatBench(bool clamp) : fClamp(clamp) {}
+    PMFloatBench() {}
 
-    const char* onGetName() SK_OVERRIDE { return fClamp ? "SkPMFloat_clamp" : "SkPMFloat_get"; }
+    const char* onGetName() SK_OVERRIDE {
+        switch (kClamp << 1 | kWide) {
+            case 0: return "SkPMFloat_get_1x";
+            case 1: return "SkPMFloat_get_4x";
+            case 2: return "SkPMFloat_clamp_1x";
+            case 3: return "SkPMFloat_clamp_4x";
+        }
+        SkFAIL("unreachable");
+        return "oh bother";
+    }
     bool isSuitableFor(Backend backend) SK_OVERRIDE { return backend == kNonRendering_Backend; }
 
     void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
@@ -23,21 +34,47 @@
         uint32_t junk = 0;
         uint32_t seed = 0;
         for (int i = 0; i < loops; i++) {
+            SkPMColor colors[4];
         #ifdef SK_DEBUG
-            // Our SkASSERTs will remind us that it's technically required that we premultiply.
-            SkPMColor c = SkPreMultiplyColor(lcg_rand(&seed));
+            for (int i = 0; i < 4; i++) {
+                // Our SkASSERTs will remind us that it's technically required that we premultiply.
+                colors[i] = SkPreMultiplyColor(lcg_rand(&seed));
+            }
         #else
             // But it's a lot faster not to, and this code won't really mind the non-PM colors.
-            SkPMColor c = lcg_rand(&seed);
+            (void)lcg_rand(&seed);
+            colors[0] = seed + 0;
+            colors[1] = seed + 1;
+            colors[2] = seed + 2;
+            colors[3] = seed + 3;
         #endif
-            SkPMFloat pmf = SkPMFloat::FromPMColor(c);
-            SkPMColor back = fClamp ? pmf.clamped() : pmf.get();
-            junk ^= back;
+
+            SkPMFloat floats[4];
+            if (kWide) {
+                SkPMFloat::From4PMColors(floats, colors);
+            } else {
+                for (int i = 0; i < 4; i++) {
+                    floats[i] = SkPMFloat::FromPMColor(colors[i]);
+                }
+            }
+
+            SkPMColor back[4];
+            switch (kClamp << 1 | kWide) {
+                case 0: for (int i = 0; i < 4; i++) { back[i] = floats[i].get(); }     break;
+                case 1: SkPMFloat::To4PMColors(back, floats);                          break;
+                case 2: for (int i = 0; i < 4; i++) { back[i] = floats[i].clamped(); } break;
+                case 3: SkPMFloat::ClampTo4PMColors(back, floats);                     break;
+            }
+            for (int i = 0; i < 4; i++) {
+                junk ^= back[i];
+            }
         }
         blackhole ^= junk;
     }
-
-    bool fClamp;
 };
-DEF_BENCH(return new PMFloatBench( true);)
-DEF_BENCH(return new PMFloatBench(false);)
+
+// Extra () help DEF_BENCH not get confused by the comma inside the <>.
+DEF_BENCH(return (new PMFloatBench< true,  true>);)
+DEF_BENCH(return (new PMFloatBench<false,  true>);)
+DEF_BENCH(return (new PMFloatBench< true, false>);)
+DEF_BENCH(return (new PMFloatBench<false, false>);)