move colorshader into its own .cpp, add color4f variant

Implemented as a different subclass for SkColorShader (which is also private) partly to make the CL clearer/simpler, and partly for flatten/unflatten compatibility. Later I'm sure we could combine these if that proves useful.

Lots of TODOs at the moment, but still valuable to get reviewed.

Note: this ignores the question (for the moment) about how to interpret SkColor in the larger world. That needs to happen, but this CL is more focused on what *else* to do besides handle the old-style input (and old-style pipeline).

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1934313002

Review-Url: https://codereview.chromium.org/1934313002
diff --git a/gm/color4f.cpp b/gm/color4f.cpp
index 2585ad8..829434c 100644
--- a/gm/color4f.cpp
+++ b/gm/color4f.cpp
@@ -84,3 +84,42 @@
         canvas->translate(0, 120);
     }
 }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+#include "SkColorSpace.h"
+
+DEF_SIMPLE_GM(color4shader, canvas, 1024, 260) {
+    canvas->translate(10, 10);
+
+    SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor);
+    // red -> blue, green -> red, blue -> green
+    mat.set3x3(0, 1, 0, 0, 0, 1, 1, 0, 0);
+
+    const SkColor4f colors[] {
+        { 1, 1, 0, 0 },
+        { 1, 0, 1, 0 },
+        { 1, 0, 0, 1 },
+        { 1, 0.5, 0.5, 0.5 },
+    };
+
+    SkPaint paint;
+    SkRect r = SkRect::MakeWH(100, 100);
+
+    for (const auto& c4 : colors) {
+        sk_sp<SkShader> shaders[] {
+            SkShader::MakeColorShader(c4, nullptr),
+            SkShader::MakeColorShader(c4, SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named)),
+            SkShader::MakeColorShader(c4, SkColorSpace::NewRGB(SkColorSpace::SkGammas(1, 1, 1),
+                                                               mat)),
+        };
+
+        canvas->save();
+        for (const auto& s : shaders) {
+            paint.setShader(s);
+            canvas->drawRect(r, paint);
+            canvas->translate(r.width() * 6 / 5, 0);
+        }
+        canvas->restore();
+        canvas->translate(0, r.height() * 6 / 5);
+    }
+}
diff --git a/gyp/core.gypi b/gyp/core.gypi
index c77b0d1..6322c54 100644
--- a/gyp/core.gypi
+++ b/gyp/core.gypi
@@ -73,6 +73,7 @@
         '<(skia_src_path)/core/SkColorFilterShader.cpp',
         '<(skia_src_path)/core/SkColorMatrixFilterRowMajor255.cpp',
         '<(skia_src_path)/core/SkColorMatrixFilterRowMajor255.h',
+        '<(skia_src_path)/core/SkColorShader.cpp',
         '<(skia_src_path)/core/SkColorShader.h',
         '<(skia_src_path)/core/SkColorSpace.cpp',
         '<(skia_src_path)/core/SkColorSpace.h',
diff --git a/include/core/SkShader.h b/include/core/SkShader.h
index 0de53ad..60aa7cd 100644
--- a/include/core/SkShader.h
+++ b/include/core/SkShader.h
@@ -17,6 +17,7 @@
 #include "../gpu/GrColor.h"
 
 class SkColorFilter;
+class SkColorSpace;
 class SkPath;
 class SkPicture;
 class SkXfermode;
@@ -375,6 +376,14 @@
      */
     static sk_sp<SkShader> MakeColorShader(SkColor);
 
+    /**
+     *  Create a shader that draws the specified color (in the specified colorspace).
+     *
+     *  This works around the limitation that SkPaint::setColor() only takes byte values, and does
+     *  not support specific colorspaces.
+     */
+    static sk_sp<SkShader> MakeColorShader(const SkColor4f&, sk_sp<SkColorSpace>);
+
     static sk_sp<SkShader> MakeComposeShader(sk_sp<SkShader> dst, sk_sp<SkShader> src,
                                              SkXfermode::Mode);
 
diff --git a/samplecode/GMSampleView.cpp b/samplecode/GMSampleView.cpp
index 76d0c59..80a6803 100644
--- a/samplecode/GMSampleView.cpp
+++ b/samplecode/GMSampleView.cpp
@@ -37,11 +37,39 @@
     return this->INHERITED::onEvent(evt);
 }
 
+#include "SkPicture.h"
+#include "SkStream.h"
+static sk_sp<SkPicture> round_trip_serialize(SkPicture* src) {
+    SkDynamicMemoryWStream stream;
+    src->serialize(&stream);
+    SkAutoTDelete<SkStream> reader(stream.detachAsStream());
+    return SkPicture::MakeFromStream(reader);
+}
+
+#include "SkPictureRecorder.h"
 void GMSampleView::onDrawContent(SkCanvas* canvas) {
+    SkPictureRecorder recorder;
+    SkCanvas* origCanvas = canvas;
+
+    if (false) {
+        SkISize size = fGM->getISize();
+        canvas = recorder.beginRecording(SkRect::MakeIWH(size.width(), size.height()));
+    }
+
     {
         SkAutoCanvasRestore acr(canvas, fShowSize);
         fGM->drawContent(canvas);
     }
+
+    if (origCanvas != canvas) {
+        sk_sp<SkPicture> pic = recorder.finishRecordingAsPicture();
+        if (false) {
+            pic = round_trip_serialize(pic.get());
+        }
+        origCanvas->drawPicture(pic);
+        canvas = origCanvas;
+    }
+
     if (fShowSize) {
         SkISize size = fGM->getISize();
         SkRect r = SkRect::MakeWH(SkIntToScalar(size.width()),
diff --git a/src/core/SkColorShader.cpp b/src/core/SkColorShader.cpp
new file mode 100644
index 0000000..f399eaa
--- /dev/null
+++ b/src/core/SkColorShader.cpp
@@ -0,0 +1,313 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkColorShader.h"
+#include "SkColorSpace.h"
+#include "SkReadBuffer.h"
+#include "SkUtils.h"
+
+SkColorShader::SkColorShader(SkColor c) : fColor(c) {}
+
+bool SkColorShader::isOpaque() const {
+    return SkColorGetA(fColor) == 255;
+}
+
+sk_sp<SkFlattenable> SkColorShader::CreateProc(SkReadBuffer& buffer) {
+    return sk_make_sp<SkColorShader>(buffer.readColor());
+}
+
+void SkColorShader::flatten(SkWriteBuffer& buffer) const {
+    buffer.writeColor(fColor);
+}
+
+uint32_t SkColorShader::ColorShaderContext::getFlags() const {
+    return fFlags;
+}
+
+SkShader::Context* SkColorShader::onCreateContext(const ContextRec& rec, void* storage) const {
+    return new (storage) ColorShaderContext(*this, rec);
+}
+
+SkColorShader::ColorShaderContext::ColorShaderContext(const SkColorShader& shader,
+                                                      const ContextRec& rec)
+    : INHERITED(shader, rec)
+{
+    SkColor color = shader.fColor;
+    unsigned a = SkAlphaMul(SkColorGetA(color), SkAlpha255To256(rec.fPaint->getAlpha()));
+
+    unsigned r = SkColorGetR(color);
+    unsigned g = SkColorGetG(color);
+    unsigned b = SkColorGetB(color);
+
+    if (a != 255) {
+        r = SkMulDiv255Round(r, a);
+        g = SkMulDiv255Round(g, a);
+        b = SkMulDiv255Round(b, a);
+    }
+    fPMColor = SkPackARGB32(a, r, g, b);
+
+    SkColor4f c4 = SkColor4f::FromColor(shader.fColor);
+    c4.fA *= rec.fPaint->getAlpha() / 255.0f;
+    fPM4f = c4.premul();
+
+    fFlags = kConstInY32_Flag;
+    if (255 == a) {
+        fFlags |= kOpaqueAlpha_Flag;
+    }
+}
+
+void SkColorShader::ColorShaderContext::shadeSpan(int x, int y, SkPMColor span[], int count) {
+    sk_memset32(span, fPMColor, count);
+}
+
+void SkColorShader::ColorShaderContext::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) {
+    memset(alpha, SkGetPackedA32(fPMColor), count);
+}
+
+void SkColorShader::ColorShaderContext::shadeSpan4f(int x, int y, SkPM4f span[], int count) {
+    for (int i = 0; i < count; ++i) {
+        span[i] = fPM4f;
+    }
+}
+
+SkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const {
+    if (info) {
+        if (info->fColors && info->fColorCount >= 1) {
+            info->fColors[0] = fColor;
+        }
+        info->fColorCount = 1;
+        info->fTileMode = SkShader::kRepeat_TileMode;
+    }
+    return kColor_GradientType;
+}
+
+#if SK_SUPPORT_GPU
+
+#include "SkGr.h"
+#include "effects/GrConstColorProcessor.h"
+const GrFragmentProcessor* SkColorShader::asFragmentProcessor(GrContext*, const SkMatrix&,
+                                                              const SkMatrix*,
+                                                              SkFilterQuality) const {
+    GrColor color = SkColorToPremulGrColor(fColor);
+    return GrConstColorProcessor::Create(color, GrConstColorProcessor::kModulateA_InputMode);
+}
+
+#endif
+
+#ifndef SK_IGNORE_TO_STRING
+void SkColorShader::toString(SkString* str) const {
+    str->append("SkColorShader: (");
+
+    str->append("Color: ");
+    str->appendHex(fColor);
+
+    this->INHERITED::toString(str);
+
+    str->append(")");
+}
+#endif
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+static unsigned unit_to_byte(float unit) {
+    SkASSERT(unit >= 0 && unit <= 1);
+    return (unsigned)(unit * 255 + 0.5);
+}
+
+static SkColor unit_to_skcolor(const SkColor4f& unit, SkColorSpace* cs) {
+    return SkColorSetARGB(unit_to_byte(unit.fA), unit_to_byte(unit.fR),
+                          unit_to_byte(unit.fG), unit_to_byte(unit.fB));
+}
+
+SkColor4Shader::SkColor4Shader(const SkColor4f& color, sk_sp<SkColorSpace> space)
+    : fColorSpace(std::move(space))
+    , fColor4(color)
+    , fCachedByteColor(unit_to_skcolor(color.pin(), space.get()))
+{}
+
+sk_sp<SkFlattenable> SkColor4Shader::CreateProc(SkReadBuffer& buffer) {
+    SkColor4f color;
+    color.fA = buffer.readScalar(); // readFloat()
+    color.fR = buffer.readScalar();
+    color.fG = buffer.readScalar();
+    color.fB = buffer.readScalar();
+    if (buffer.readBool()) {
+        // TODO how do we unflatten colorspaces
+    }
+    return SkShader::MakeColorShader(color, nullptr);
+}
+
+void SkColor4Shader::flatten(SkWriteBuffer& buffer) const {
+    buffer.writeScalar(fColor4.fA); // writeFloat()
+    buffer.writeScalar(fColor4.fR);
+    buffer.writeScalar(fColor4.fG);
+    buffer.writeScalar(fColor4.fB);
+    buffer.writeBool(false);    // TODO how do we flatten colorspaces?
+}
+
+uint32_t SkColor4Shader::Color4Context::getFlags() const {
+    return fFlags;
+}
+
+SkShader::Context* SkColor4Shader::onCreateContext(const ContextRec& rec, void* storage) const {
+    return new (storage) Color4Context(*this, rec);
+}
+
+SkColor4Shader::Color4Context::Color4Context(const SkColor4Shader& shader,
+                                                      const ContextRec& rec)
+: INHERITED(shader, rec)
+{
+    SkColor color = shader.fCachedByteColor;
+    unsigned a = SkAlphaMul(SkColorGetA(color), SkAlpha255To256(rec.fPaint->getAlpha()));
+
+    unsigned r = SkColorGetR(color);
+    unsigned g = SkColorGetG(color);
+    unsigned b = SkColorGetB(color);
+
+    if (a != 255) {
+        r = SkMulDiv255Round(r, a);
+        g = SkMulDiv255Round(g, a);
+        b = SkMulDiv255Round(b, a);
+    }
+    fPMColor = SkPackARGB32(a, r, g, b);
+
+    SkColor4f c4 = shader.fColor4;
+    c4.fA *= rec.fPaint->getAlpha() * (1 / 255.0f);
+    fPM4f = c4.premul();
+
+    fFlags = kConstInY32_Flag;
+    if (255 == a) {
+        fFlags |= kOpaqueAlpha_Flag;
+    }
+}
+
+void SkColor4Shader::Color4Context::shadeSpan(int x, int y, SkPMColor span[], int count) {
+    sk_memset32(span, fPMColor, count);
+}
+
+void SkColor4Shader::Color4Context::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) {
+    memset(alpha, SkGetPackedA32(fPMColor), count);
+}
+
+void SkColor4Shader::Color4Context::shadeSpan4f(int x, int y, SkPM4f span[], int count) {
+    for (int i = 0; i < count; ++i) {
+        span[i] = fPM4f;
+    }
+}
+
+// TODO: do we need an updated version of this method for color4+colorspace?
+SkShader::GradientType SkColor4Shader::asAGradient(GradientInfo* info) const {
+    if (info) {
+        if (info->fColors && info->fColorCount >= 1) {
+            info->fColors[0] = fCachedByteColor;
+        }
+        info->fColorCount = 1;
+        info->fTileMode = SkShader::kRepeat_TileMode;
+    }
+    return kColor_GradientType;
+}
+
+#if SK_SUPPORT_GPU
+
+#include "SkGr.h"
+#include "effects/GrConstColorProcessor.h"
+const GrFragmentProcessor* SkColor4Shader::asFragmentProcessor(GrContext*, const SkMatrix&,
+                                                               const SkMatrix*,
+                                                               SkFilterQuality) const {
+    // TODO: how to communicate color4f to Gr
+    GrColor color = SkColorToPremulGrColor(fCachedByteColor);
+    return GrConstColorProcessor::Create(color, GrConstColorProcessor::kModulateA_InputMode);
+}
+
+#endif
+
+#ifndef SK_IGNORE_TO_STRING
+void SkColor4Shader::toString(SkString* str) const {
+    str->append("SkColor4Shader: (");
+
+    str->append("ARGB:");
+    for (int i = 0; i < 4; ++i) {
+        str->appendf(" %g", fColor4.vec()[i]);
+    }
+    str->append(" )");
+}
+#endif
+
+sk_sp<SkShader> SkShader::MakeColorShader(const SkColor4f& color, sk_sp<SkColorSpace> space) {
+    if (!SkScalarsAreFinite(color.vec(), 4)) {
+        return nullptr;
+    }
+    return sk_make_sp<SkColor4Shader>(color, std::move(space));
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+static void D32_BlitBW(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst,
+                       int count) {
+    SkXfermode::D32Proc proc = (SkXfermode::D32Proc)state->fStorage[0];
+    const SkPM4f* src = (const SkPM4f*)state->fStorage[1];
+    proc(state->fXfer, dst.writable_addr32(x, y), src, count, nullptr);
+}
+
+static void D32_BlitAA(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst,
+                       int count, const SkAlpha aa[]) {
+    SkXfermode::D32Proc proc = (SkXfermode::D32Proc)state->fStorage[0];
+    const SkPM4f* src = (const SkPM4f*)state->fStorage[1];
+    proc(state->fXfer, dst.writable_addr32(x, y), src, count, aa);
+}
+
+static void F16_BlitBW(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst,
+                       int count) {
+    SkXfermode::F16Proc proc = (SkXfermode::F16Proc)state->fStorage[0];
+    const SkPM4f* src = (const SkPM4f*)state->fStorage[1];
+    proc(state->fXfer, dst.writable_addr64(x, y), src, count, nullptr);
+}
+
+static void F16_BlitAA(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst,
+                       int count, const SkAlpha aa[]) {
+    SkXfermode::F16Proc proc = (SkXfermode::F16Proc)state->fStorage[0];
+    const SkPM4f* src = (const SkPM4f*)state->fStorage[1];
+    proc(state->fXfer, dst.writable_addr64(x, y), src, count, aa);
+}
+
+static bool choose_blitprocs(const SkPM4f* pm4, const SkImageInfo& info,
+                             SkShader::Context::BlitState* state) {
+    uint32_t flags = SkXfermode::kSrcIsSingle_D32Flag;
+    if (pm4->a() == 1) {
+        flags |= SkXfermode::kSrcIsOpaque_D32Flag;
+    }
+    switch (info.colorType()) {
+        case kN32_SkColorType:
+            if (info.isSRGB()) {
+                flags |= SkXfermode::kDstIsSRGB_D32Flag;
+            }
+            state->fStorage[0] = (void*)SkXfermode::GetD32Proc(state->fXfer, flags);
+            state->fStorage[1] = (void*)pm4;
+            state->fBlitBW = D32_BlitBW;
+            state->fBlitAA = D32_BlitAA;
+            return true;
+        case kRGBA_F16_SkColorType:
+            state->fStorage[0] = (void*)SkXfermode::GetF16Proc(state->fXfer, flags);
+            state->fStorage[1] = (void*)pm4;
+            state->fBlitBW = F16_BlitBW;
+            state->fBlitAA = F16_BlitAA;
+            return true;
+        default:
+            return false;
+    }
+}
+
+bool SkColorShader::ColorShaderContext::onChooseBlitProcs(const SkImageInfo& info,
+                                                          BlitState* state) {
+    return choose_blitprocs(&fPM4f, info, state);
+}
+
+bool SkColor4Shader::Color4Context::onChooseBlitProcs(const SkImageInfo& info, BlitState* state) {
+    return choose_blitprocs(&fPM4f, info, state);
+}
diff --git a/src/core/SkColorShader.h b/src/core/SkColorShader.h
index db71b6e..f7e6094 100644
--- a/src/core/SkColorShader.h
+++ b/src/core/SkColorShader.h
@@ -72,4 +72,60 @@
     typedef SkShader INHERITED;
 };
 
+class SkColor4Shader : public SkShader {
+public:
+    SkColor4Shader(const SkColor4f&, sk_sp<SkColorSpace>);
+
+    bool isOpaque() const override {
+        return SkColorGetA(fCachedByteColor) == 255;
+    }
+
+    class Color4Context : public SkShader::Context {
+    public:
+        Color4Context(const SkColor4Shader& shader, const ContextRec&);
+
+        uint32_t getFlags() const override;
+        void shadeSpan(int x, int y, SkPMColor span[], int count) override;
+        void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) override;
+        void shadeSpan4f(int x, int y, SkPM4f[], int count) override;
+
+    protected:
+        bool onChooseBlitProcs(const SkImageInfo&, BlitState*) override;
+
+    private:
+        SkPM4f      fPM4f;
+        SkPMColor   fPMColor;
+        uint32_t    fFlags;
+
+        typedef SkShader::Context INHERITED;
+    };
+
+    GradientType asAGradient(GradientInfo* info) const override;
+
+#if SK_SUPPORT_GPU
+    const GrFragmentProcessor* asFragmentProcessor(GrContext*, const SkMatrix& viewM,
+                                                   const SkMatrix*, SkFilterQuality) const override;
+#endif
+
+    SK_TO_STRING_OVERRIDE()
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkColorShader)
+
+protected:
+    SkColor4Shader(SkReadBuffer&);
+    void flatten(SkWriteBuffer&) const override;
+    Context* onCreateContext(const ContextRec&, void* storage) const override;
+    size_t onContextSize(const ContextRec&) const override { return sizeof(Color4Context); }
+    bool onAsLuminanceColor(SkColor* lum) const override {
+        *lum = fCachedByteColor;
+        return true;
+    }
+
+private:
+    sk_sp<SkColorSpace> fColorSpace;
+    const SkColor4f     fColor4;
+    const SkColor       fCachedByteColor;
+    
+    typedef SkShader INHERITED;
+};
+
 #endif
diff --git a/src/core/SkGlobalInitialization_core.cpp b/src/core/SkGlobalInitialization_core.cpp
index e377437..022c497 100644
--- a/src/core/SkGlobalInitialization_core.cpp
+++ b/src/core/SkGlobalInitialization_core.cpp
@@ -32,6 +32,7 @@
     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBitmapProcShader)
     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkColorFilterShader)
     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkColorShader)
+    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkColor4Shader)
     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeShader)
     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkEmptyShader)
     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkImageShader)
diff --git a/src/core/SkShader.cpp b/src/core/SkShader.cpp
index 0ed97b0..1b729ea 100644
--- a/src/core/SkShader.cpp
+++ b/src/core/SkShader.cpp
@@ -252,171 +252,7 @@
 }
 #endif
 
-//////////////////////////////////////////////////////////////////////////////
-
-#include "SkUtils.h"
-
-SkColorShader::SkColorShader(SkColor c)
-    : fColor(c) {
-}
-
-bool SkColorShader::isOpaque() const {
-    return SkColorGetA(fColor) == 255;
-}
-
-sk_sp<SkFlattenable> SkColorShader::CreateProc(SkReadBuffer& buffer) {
-    return sk_make_sp<SkColorShader>(buffer.readColor());
-}
-
-void SkColorShader::flatten(SkWriteBuffer& buffer) const {
-    buffer.writeColor(fColor);
-}
-
-uint32_t SkColorShader::ColorShaderContext::getFlags() const {
-    return fFlags;
-}
-
-SkShader::Context* SkColorShader::onCreateContext(const ContextRec& rec, void* storage) const {
-    return new (storage) ColorShaderContext(*this, rec);
-}
-
-SkColorShader::ColorShaderContext::ColorShaderContext(const SkColorShader& shader,
-                                                      const ContextRec& rec)
-    : INHERITED(shader, rec)
-{
-    SkColor color = shader.fColor;
-    unsigned a = SkAlphaMul(SkColorGetA(color), SkAlpha255To256(rec.fPaint->getAlpha()));
-
-    unsigned r = SkColorGetR(color);
-    unsigned g = SkColorGetG(color);
-    unsigned b = SkColorGetB(color);
-
-    if (a != 255) {
-        r = SkMulDiv255Round(r, a);
-        g = SkMulDiv255Round(g, a);
-        b = SkMulDiv255Round(b, a);
-    }
-    fPMColor = SkPackARGB32(a, r, g, b);
-
-    SkColor4f c4 = SkColor4f::FromColor(shader.fColor);
-    c4.fA *= rec.fPaint->getAlpha() / 255.0f;
-    fPM4f = c4.premul();
-
-    fFlags = kConstInY32_Flag;
-    if (255 == a) {
-        fFlags |= kOpaqueAlpha_Flag;
-    }
-}
-
-void SkColorShader::ColorShaderContext::shadeSpan(int x, int y, SkPMColor span[], int count) {
-    sk_memset32(span, fPMColor, count);
-}
-
-void SkColorShader::ColorShaderContext::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) {
-    memset(alpha, SkGetPackedA32(fPMColor), count);
-}
-
-void SkColorShader::ColorShaderContext::shadeSpan4f(int x, int y, SkPM4f span[], int count) {
-    for (int i = 0; i < count; ++i) {
-        span[i] = fPM4f;
-    }
-}
-
-SkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const {
-    if (info) {
-        if (info->fColors && info->fColorCount >= 1) {
-            info->fColors[0] = fColor;
-        }
-        info->fColorCount = 1;
-        info->fTileMode = SkShader::kRepeat_TileMode;
-    }
-    return kColor_GradientType;
-}
-
-#if SK_SUPPORT_GPU
-
-#include "SkGr.h"
-#include "effects/GrConstColorProcessor.h"
-const GrFragmentProcessor* SkColorShader::asFragmentProcessor(GrContext*, const SkMatrix&,
-                                                              const SkMatrix*,
-                                                              SkFilterQuality) const {
-    GrColor color = SkColorToPremulGrColor(fColor);
-    return GrConstColorProcessor::Create(color, GrConstColorProcessor::kModulateA_InputMode);
-}
-
-#endif
-
-#ifndef SK_IGNORE_TO_STRING
-void SkColorShader::toString(SkString* str) const {
-    str->append("SkColorShader: (");
-
-    str->append("Color: ");
-    str->appendHex(fColor);
-
-    this->INHERITED::toString(str);
-
-    str->append(")");
-}
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-
-static void D32_BlitBW(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst,
-                       int count) {
-    SkXfermode::D32Proc proc = (SkXfermode::D32Proc)state->fStorage[0];
-    const SkPM4f* src = (const SkPM4f*)state->fStorage[1];
-    proc(state->fXfer, dst.writable_addr32(x, y), src, count, nullptr);
-}
-
-static void D32_BlitAA(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst,
-                       int count, const SkAlpha aa[]) {
-    SkXfermode::D32Proc proc = (SkXfermode::D32Proc)state->fStorage[0];
-    const SkPM4f* src = (const SkPM4f*)state->fStorage[1];
-    proc(state->fXfer, dst.writable_addr32(x, y), src, count, aa);
-}
-
-static void F16_BlitBW(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst,
-                       int count) {
-    SkXfermode::F16Proc proc = (SkXfermode::F16Proc)state->fStorage[0];
-    const SkPM4f* src = (const SkPM4f*)state->fStorage[1];
-    proc(state->fXfer, dst.writable_addr64(x, y), src, count, nullptr);
-}
-
-static void F16_BlitAA(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst,
-                       int count, const SkAlpha aa[]) {
-    SkXfermode::F16Proc proc = (SkXfermode::F16Proc)state->fStorage[0];
-    const SkPM4f* src = (const SkPM4f*)state->fStorage[1];
-    proc(state->fXfer, dst.writable_addr64(x, y), src, count, aa);
-}
-
-bool SkColorShader::ColorShaderContext::onChooseBlitProcs(const SkImageInfo& info,
-                                                          BlitState* state) {
-    uint32_t flags = SkXfermode::kSrcIsSingle_D32Flag;
-    if (fPM4f.a() == 1) {
-        flags |= SkXfermode::kSrcIsOpaque_D32Flag;
-    }
-    switch (info.colorType()) {
-        case kN32_SkColorType:
-            if (info.isSRGB()) {
-                flags |= SkXfermode::kDstIsSRGB_D32Flag;
-            }
-            state->fStorage[0] = (void*)SkXfermode::GetD32Proc(state->fXfer, flags);
-            state->fStorage[1] = &fPM4f;
-            state->fBlitBW = D32_BlitBW;
-            state->fBlitAA = D32_BlitAA;
-            return true;
-        case kRGBA_F16_SkColorType:
-            state->fStorage[0] = (void*)SkXfermode::GetF16Proc(state->fXfer, flags);
-            state->fStorage[1] = &fPM4f;
-            state->fBlitBW = F16_BlitBW;
-            state->fBlitAA = F16_BlitAA;
-            return true;
-        default:
-            return false;
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
 sk_sp<SkFlattenable> SkEmptyShader::CreateProc(SkReadBuffer&) {
     return SkShader::MakeEmptyShader();