Use SkPMColor4f throughout clear APIs

Bug: skia:
Change-Id: I5386e27edbcf39233880d869841a6632ecb9416c
Reviewed-on: https://skia-review.googlesource.com/c/168261
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
diff --git a/src/gpu/GrBlurUtils.cpp b/src/gpu/GrBlurUtils.cpp
index 3535df9..b4b93f4 100644
--- a/src/gpu/GrBlurUtils.cpp
+++ b/src/gpu/GrBlurUtils.cpp
@@ -183,7 +183,7 @@
         return nullptr;
     }
 
-    rtContext->priv().absClear(nullptr, 0x0);
+    rtContext->priv().absClear(nullptr, SK_PMColor4fTRANSPARENT);
 
     GrPaint maskPaint;
     maskPaint.setCoverageSetOpXPFactory(SkRegion::kReplace_Op);
diff --git a/src/gpu/GrGpuCommandBuffer.cpp b/src/gpu/GrGpuCommandBuffer.cpp
index 421d057..8b5b128 100644
--- a/src/gpu/GrGpuCommandBuffer.cpp
+++ b/src/gpu/GrGpuCommandBuffer.cpp
@@ -16,7 +16,7 @@
 #include "GrRenderTarget.h"
 #include "SkRect.h"
 
-void GrGpuRTCommandBuffer::clear(const GrFixedClip& clip, GrColor color) {
+void GrGpuRTCommandBuffer::clear(const GrFixedClip& clip, const SkPMColor4f& color) {
     SkASSERT(fRenderTarget);
 
     this->onClear(clip, color);
diff --git a/src/gpu/GrGpuCommandBuffer.h b/src/gpu/GrGpuCommandBuffer.h
index 888d459..ca03378 100644
--- a/src/gpu/GrGpuCommandBuffer.h
+++ b/src/gpu/GrGpuCommandBuffer.h
@@ -8,7 +8,6 @@
 #ifndef GrGpuCommandBuffer_DEFINED
 #define GrGpuCommandBuffer_DEFINED
 
-#include "GrColor.h"
 #include "GrPipeline.h"
 #include "SkDrawable.h"
 #include "ops/GrDrawOp.h"
@@ -73,9 +72,9 @@
 class GrGpuRTCommandBuffer : public GrGpuCommandBuffer {
 public:
     struct LoadAndStoreInfo {
-        GrLoadOp  fLoadOp;
-        GrStoreOp fStoreOp;
-        GrColor   fClearColor;
+        GrLoadOp    fLoadOp;
+        GrStoreOp   fStoreOp;
+        SkPMColor4f fClearColor;
     };
 
     // Load-time clears of the stencil buffer are always to 0 so we don't store
@@ -109,7 +108,7 @@
     /**
      * Clear the owned render target. Ignores the draw state and clip.
      */
-    void clear(const GrFixedClip&, GrColor);
+    void clear(const GrFixedClip&, const SkPMColor4f&);
 
     void clearStencilClip(const GrFixedClip&, bool insideStencilMask);
 
@@ -155,7 +154,7 @@
                         const SkRect& bounds) = 0;
 
     // overridden by backend-specific derived class to perform the clear.
-    virtual void onClear(const GrFixedClip&, GrColor) = 0;
+    virtual void onClear(const GrFixedClip&, const SkPMColor4f&) = 0;
 
     virtual void onClearStencilClip(const GrFixedClip&, bool insideStencilMask) = 0;
 
diff --git a/src/gpu/GrOpList.cpp b/src/gpu/GrOpList.cpp
index 97214bd..dd889e8 100644
--- a/src/gpu/GrOpList.cpp
+++ b/src/gpu/GrOpList.cpp
@@ -213,7 +213,7 @@
                      : -1);
     SkDebugf("ColorLoadOp: %s %x StencilLoadOp: %s\n",
              op_to_name(fColorLoadOp),
-             GrLoadOp::kClear == fColorLoadOp ? fLoadClearColor : 0x0,
+             GrLoadOp::kClear == fColorLoadOp ? fLoadClearColor.toBytes_RGBA() : 0x0,
              op_to_name(fStencilLoadOp));
 
     if (printDependencies) {
diff --git a/src/gpu/GrPaint.cpp b/src/gpu/GrPaint.cpp
index 32b7016..ee09a26 100644
--- a/src/gpu/GrPaint.cpp
+++ b/src/gpu/GrPaint.cpp
@@ -57,20 +57,20 @@
                                                                    params));
 }
 
-bool GrPaint::isConstantBlendedColor(GrColor* constantColor) const {
+bool GrPaint::isConstantBlendedColor(SkPMColor4f* constantColor) const {
     // This used to do a more sophisticated analysis but now it just explicitly looks for common
     // cases.
     static const GrXPFactory* kSrc = GrPorterDuffXPFactory::Get(SkBlendMode::kSrc);
     static const GrXPFactory* kClear = GrPorterDuffXPFactory::Get(SkBlendMode::kClear);
     if (kClear == fXPFactory) {
-        *constantColor = GrColor_TRANSPARENT_BLACK;
+        *constantColor = SK_PMColor4fTRANSPARENT;
         return true;
     }
     if (this->numColorFragmentProcessors()) {
         return false;
     }
     if (kSrc == fXPFactory || (!fXPFactory && fColor.isOpaque())) {
-        *constantColor = fColor.toBytes_RGBA();
+        *constantColor = fColor;
         return true;
     }
     return false;
diff --git a/src/gpu/GrPaint.h b/src/gpu/GrPaint.h
index 7f5b035..f6173b7 100644
--- a/src/gpu/GrPaint.h
+++ b/src/gpu/GrPaint.h
@@ -112,7 +112,7 @@
      * coverage and color, so the actual values written to pixels with partial coverage may still
      * not seem constant, even if this function returns true.
      */
-    bool isConstantBlendedColor(GrColor* constantColor) const;
+    bool isConstantBlendedColor(SkPMColor4f* constantColor) const;
 
     /**
      * A trivial paint is one that uses src-over and has no fragment processors.
diff --git a/src/gpu/GrReducedClip.cpp b/src/gpu/GrReducedClip.cpp
index 4cf3477..97af1de 100644
--- a/src/gpu/GrReducedClip.cpp
+++ b/src/gpu/GrReducedClip.cpp
@@ -747,7 +747,8 @@
 
     // The scratch texture that we are drawing into can be substantially larger than the mask. Only
     // clear the part that we care about.
-    GrColor initialCoverage = InitialState::kAllIn == this->initialState() ? -1 : 0;
+    SkPMColor4f initialCoverage =
+        InitialState::kAllIn == this->initialState() ? SK_PMColor4fWHITE : SK_PMColor4fTRANSPARENT;
     rtc->priv().clear(clip, initialCoverage, GrRenderTargetContext::CanClearFullscreen::kYes);
 
     // Set the matrix so that rendered clip elements are transformed to mask space from clip space.
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index 3989374..fc446bf 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -256,7 +256,7 @@
 }
 
 void GrRenderTargetContext::clear(const SkIRect* rect,
-                                  const GrColor color,
+                                  const SkPMColor4f& color,
                                   CanClearFullscreen canClearFullscreen) {
     ASSERT_SINGLE_OWNER
     RETURN_IF_ABANDONED
@@ -268,7 +268,7 @@
                         canClearFullscreen);
 }
 
-void GrRenderTargetContextPriv::absClear(const SkIRect* clearRect, const GrColor color) {
+void GrRenderTargetContextPriv::absClear(const SkIRect* clearRect, const SkPMColor4f& color) {
     ASSERT_SINGLE_OWNER_PRIV
     RETURN_IF_ABANDONED_PRIV
     SkDEBUGCODE(fRenderTargetContext->validate();)
@@ -298,7 +298,7 @@
     // It could be done but will take more finagling.
     if (clearRect && fRenderTargetContext->caps()->performPartialClearsAsDraws()) {
         GrPaint paint;
-        paint.setColor4f(SkPMColor4f::FromBytes_RGBA(color));
+        paint.setColor4f(color);
         SkRect scissor = SkRect::Make(rtRect);
         std::unique_ptr<GrDrawOp> op(GrRectOpFactory::MakeNonAAFill(fRenderTargetContext->fContext,
                                                                     std::move(paint), SkMatrix::I(),
@@ -319,7 +319,7 @@
 }
 
 void GrRenderTargetContextPriv::clear(const GrFixedClip& clip,
-                                      const GrColor color,
+                                      const SkPMColor4f& color,
                                       CanClearFullscreen canClearFullscreen) {
     ASSERT_SINGLE_OWNER_PRIV
     RETURN_IF_ABANDONED_PRIV
@@ -332,7 +332,7 @@
 }
 
 void GrRenderTargetContext::internalClear(const GrFixedClip& clip,
-                                          const GrColor color,
+                                          const SkPMColor4f& color,
                                           CanClearFullscreen canClearFullscreen) {
     bool isFull = false;
     if (!clip.hasWindowRectangles()) {
@@ -347,7 +347,7 @@
     } else {
         if (this->caps()->performPartialClearsAsDraws()) {
             GrPaint paint;
-            paint.setColor4f(SkPMColor4f::FromBytes_RGBA(color));
+            paint.setColor4f(color);
             SkRect scissor = SkRect::Make(clip.scissorRect());
             std::unique_ptr<GrDrawOp> op(GrRectOpFactory::MakeNonAAFill(fContext, std::move(paint),
                                                                         SkMatrix::I(), scissor,
@@ -392,7 +392,7 @@
 
     // Check if the paint is a constant color, which is the first criterion to being able to turn
     // the drawPaint() into a clear(). More expensive geometry checks can happen after that.
-    GrColor clearColor;
+    SkPMColor4f clearColor;
     if (paint.isConstantBlendedColor(&clearColor)) {
         // Regardless of the actual clip geometry, if it completely covers the device bounds it can
         // be turned into a fullscreen clear.
@@ -568,7 +568,7 @@
                 rect_contains_inclusive(rect, quad.point(2)) &&
                 rect_contains_inclusive(rect, quad.point(3))) {
                 // Will it blend?
-                GrColor clearColor;
+                SkPMColor4f clearColor;
                 if (paint.isConstantBlendedColor(&clearColor)) {
                     this->clear(nullptr, clearColor,
                                 GrRenderTargetContext::CanClearFullscreen::kYes);
diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h
index 1200e6f..941c954 100644
--- a/src/gpu/GrRenderTargetContext.h
+++ b/src/gpu/GrRenderTargetContext.h
@@ -79,7 +79,7 @@
      * @param CanClearFullscreen allows partial clears to be converted to fullscreen clears on
      *                           tiling platforms where that is an optimization.
      */
-    void clear(const SkIRect* rect, GrColor color, CanClearFullscreen);
+    void clear(const SkIRect* rect, const SkPMColor4f& color, CanClearFullscreen);
 
     /**
      *  Draw everywhere (respecting the clip) with the paint.
@@ -441,7 +441,7 @@
                              std::unique_ptr<GrFragmentProcessor>,
                              sk_sp<GrTextureProxy>);
 
-    void internalClear(const GrFixedClip&, const GrColor, CanClearFullscreen);
+    void internalClear(const GrFixedClip&, const SkPMColor4f&, CanClearFullscreen);
 
     // Only consumes the GrPaint if successful.
     bool drawFilledDRRect(const GrClip& clip,
diff --git a/src/gpu/GrRenderTargetContextPriv.h b/src/gpu/GrRenderTargetContextPriv.h
index 2a29282..c06c8ca 100644
--- a/src/gpu/GrRenderTargetContextPriv.h
+++ b/src/gpu/GrRenderTargetContextPriv.h
@@ -45,7 +45,7 @@
 
     using CanClearFullscreen = GrRenderTargetContext::CanClearFullscreen;
 
-    void clear(const GrFixedClip&, const GrColor, CanClearFullscreen);
+    void clear(const GrFixedClip&, const SkPMColor4f&, CanClearFullscreen);
 
     void clearStencilClip(const GrFixedClip&, bool insideStencilMask);
 
@@ -60,7 +60,7 @@
      * @param rect      if (!null) the rect to clear, otherwise it is a full screen clear
      * @param color     the color to clear to
      */
-    void absClear(const SkIRect* rect, const GrColor color);
+    void absClear(const SkIRect* rect, const SkPMColor4f& color);
 
     void stencilRect(const GrHardClip&,
                      const GrUserStencilSettings* ss,
diff --git a/src/gpu/GrRenderTargetOpList.cpp b/src/gpu/GrRenderTargetOpList.cpp
index 2b2eece..df5233d 100644
--- a/src/gpu/GrRenderTargetOpList.cpp
+++ b/src/gpu/GrRenderTargetOpList.cpp
@@ -120,7 +120,7 @@
                                                    GrSurfaceOrigin origin,
                                                    const SkRect& bounds,
                                                    GrLoadOp colorLoadOp,
-                                                   GrColor loadClearColor,
+                                                   const SkPMColor4f& loadClearColor,
                                                    GrLoadOp stencilLoadOp) {
     const GrGpuRTCommandBuffer::LoadAndStoreInfo kColorLoadStoreInfo {
         colorLoadOp,
@@ -216,7 +216,7 @@
     }
 }
 
-void GrRenderTargetOpList::fullClear(GrContext* context, GrColor color) {
+void GrRenderTargetOpList::fullClear(GrContext* context, const SkPMColor4f& color) {
 
     // This is conservative. If the opList is marked as needing a stencil buffer then there
     // may be a prior op that writes to the stencil buffer. Although the clear will ignore the
diff --git a/src/gpu/GrRenderTargetOpList.h b/src/gpu/GrRenderTargetOpList.h
index ad629e6..27922a8 100644
--- a/src/gpu/GrRenderTargetOpList.h
+++ b/src/gpu/GrRenderTargetOpList.h
@@ -89,7 +89,7 @@
     void discard();
 
     /** Clears the entire render target */
-    void fullClear(GrContext*, GrColor color);
+    void fullClear(GrContext*, const SkPMColor4f& color);
 
     /**
      * Copies a pixel rectangle from one surface to another. This call may finalize
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index f0aafc1..daa86fc 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -242,7 +242,8 @@
     GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "clearAll", fContext.get());
 
     SkIRect rect = SkIRect::MakeWH(this->width(), this->height());
-    fRenderTargetContext->clear(&rect, 0x0, GrRenderTargetContext::CanClearFullscreen::kYes);
+    fRenderTargetContext->clear(&rect, SK_PMColor4fTRANSPARENT,
+                                GrRenderTargetContext::CanClearFullscreen::kYes);
 }
 
 void SkGpuDevice::replaceRenderTargetContext(bool shouldRetainContent) {
diff --git a/src/gpu/ccpr/GrCCAtlas.cpp b/src/gpu/ccpr/GrCCAtlas.cpp
index a566707..0d1f9d9 100644
--- a/src/gpu/ccpr/GrCCAtlas.cpp
+++ b/src/gpu/ccpr/GrCCAtlas.cpp
@@ -202,7 +202,8 @@
     }
 
     SkIRect clearRect = SkIRect::MakeSize(fDrawBounds);
-    rtc->clear(&clearRect, 0, GrRenderTargetContext::CanClearFullscreen::kYes);
+    rtc->clear(&clearRect, SK_PMColor4fTRANSPARENT,
+               GrRenderTargetContext::CanClearFullscreen::kYes);
     return rtc;
 }
 
diff --git a/src/gpu/effects/GrRRectBlurEffect.h b/src/gpu/effects/GrRRectBlurEffect.h
index 3093b31..e760f60 100644
--- a/src/gpu/effects/GrRRectBlurEffect.h
+++ b/src/gpu/effects/GrRRectBlurEffect.h
@@ -62,7 +62,8 @@
 
             GrPaint paint;
 
-            rtc->clear(nullptr, 0x0, GrRenderTargetContext::CanClearFullscreen::kYes);
+            rtc->clear(nullptr, SK_PMColor4fTRANSPARENT,
+                       GrRenderTargetContext::CanClearFullscreen::kYes);
             rtc->drawRRect(GrNoClip(), std::move(paint), GrAA::kYes, SkMatrix::I(), rrectToDraw,
                            GrStyle::SimpleFill());
 
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 214cdd6..902509d 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -2000,23 +2000,15 @@
     }
 }
 
-void GrGLGpu::clear(const GrFixedClip& clip, GrColor color,
+void GrGLGpu::clear(const GrFixedClip& clip, const SkPMColor4f& color,
                     GrRenderTarget* target, GrSurfaceOrigin origin) {
     // parent class should never let us get here with no RT
     SkASSERT(target);
 
     this->handleDirtyContext();
 
-    GrGLfloat r, g, b, a;
-    static const GrGLfloat scale255 = 1.f / 255.f;
-    a = GrColorUnpackA(color) * scale255;
-    GrGLfloat scaleRGB = scale255;
-    r = GrColorUnpackR(color) * scaleRGB;
-    g = GrColorUnpackG(color) * scaleRGB;
-    b = GrColorUnpackB(color) * scaleRGB;
-
     if (this->glCaps().useDrawToClearColor()) {
-        this->clearColorAsDraw(clip, r, g, b, a, target, origin);
+        this->clearColorAsDraw(clip, color, target, origin);
         return;
     }
 
@@ -2033,6 +2025,8 @@
     GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
     fHWWriteToColor = kYes_TriState;
 
+    GrGLfloat r = color.fR, g = color.fG, b = color.fB, a = color.fA;
+
     if (this->glCaps().clearToBoundaryValuesIsBroken() &&
         (1 == r || 0 == r) && (1 == g || 0 == g) && (1 == b || 0 == b) && (1 == a || 0 == a)) {
         static const GrGLfloat safeAlpha1 = nextafter(1.f, 2.f);
@@ -3647,8 +3641,8 @@
     return true;
 }
 
-void GrGLGpu::clearColorAsDraw(const GrFixedClip& clip, GrGLfloat r, GrGLfloat g, GrGLfloat b,
-                               GrGLfloat a, GrRenderTarget* dst, GrSurfaceOrigin origin) {
+void GrGLGpu::clearColorAsDraw(const GrFixedClip& clip, const SkPMColor4f& color,
+                               GrRenderTarget* dst, GrSurfaceOrigin origin) {
     if (!fClearColorProgram.fProgram) {
         if (!this->createClearColorProgram()) {
             SkDebugf("Failed to create clear color program.\n");
@@ -3674,7 +3668,7 @@
     this->flushScissor(clip.scissorState(), glrt->getViewport(), origin);
     this->flushWindowRectangles(clip.windowRectsState(), glrt, origin);
 
-    GL_CALL(Uniform4f(fClearColorProgram.fColorUniform, r, g, b, a));
+    GL_CALL(Uniform4f(fClearColorProgram.fColorUniform, color.fR, color.fG, color.fB, color.fA));
 
     GrXferProcessor::BlendInfo blendInfo;
     blendInfo.reset();
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 1fa18c5..8812a02 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -108,9 +108,9 @@
     // The GrGLGpuRTCommandBuffer does not buffer up draws before submitting them to the gpu.
     // Thus this is the implementation of the clear call for the corresponding passthrough function
     // on GrGLGpuRTCommandBuffer.
-    void clear(const GrFixedClip&, GrColor, GrRenderTarget*, GrSurfaceOrigin);
-    void clearColorAsDraw(const GrFixedClip&, GrGLfloat r, GrGLfloat g, GrGLfloat b, GrGLfloat a,
-                          GrRenderTarget*, GrSurfaceOrigin);
+    void clear(const GrFixedClip&, const SkPMColor4f&, GrRenderTarget*, GrSurfaceOrigin);
+    void clearColorAsDraw(const GrFixedClip&, const SkPMColor4f& color, GrRenderTarget*,
+                          GrSurfaceOrigin);
 
     // The GrGLGpuRTCommandBuffer does not buffer up draws before submitting them to the gpu.
     // Thus this is the implementation of the clearStencil call for the corresponding passthrough
diff --git a/src/gpu/gl/GrGLGpuCommandBuffer.h b/src/gpu/gl/GrGLGpuCommandBuffer.h
index 63aacf3..e8c9bbd 100644
--- a/src/gpu/gl/GrGLGpuCommandBuffer.h
+++ b/src/gpu/gl/GrGLGpuCommandBuffer.h
@@ -89,7 +89,7 @@
         fGpu->draw(primProc, pipeline, fixedDynamicState, dynamicStateArrays, mesh, meshCount);
     }
 
-    void onClear(const GrFixedClip& clip, GrColor color) override {
+    void onClear(const GrFixedClip& clip, const SkPMColor4f& color) override {
         fGpu->clear(clip, color, fRenderTarget, fOrigin);
     }
 
diff --git a/src/gpu/mock/GrMockGpuCommandBuffer.h b/src/gpu/mock/GrMockGpuCommandBuffer.h
index cad5836..a14fb64 100644
--- a/src/gpu/mock/GrMockGpuCommandBuffer.h
+++ b/src/gpu/mock/GrMockGpuCommandBuffer.h
@@ -51,7 +51,7 @@
                 const GrMesh[], int meshCount, const SkRect& bounds) override {
         ++fNumDraws;
     }
-    void onClear(const GrFixedClip&, GrColor) override {}
+    void onClear(const GrFixedClip&, const SkPMColor4f&) override {}
     void onClearStencilClip(const GrFixedClip&, bool insideStencilMask) override {}
 
     GrMockGpu* fGpu;
diff --git a/src/gpu/mtl/GrMtlGpuCommandBuffer.h b/src/gpu/mtl/GrMtlGpuCommandBuffer.h
index 9e1ce45..1505789 100644
--- a/src/gpu/mtl/GrMtlGpuCommandBuffer.h
+++ b/src/gpu/mtl/GrMtlGpuCommandBuffer.h
@@ -84,7 +84,7 @@
                 int meshCount,
                 const SkRect& bounds) override;
 
-    void onClear(const GrFixedClip& clip, GrColor color) override;
+    void onClear(const GrFixedClip& clip, const SkPMColor4f& color) override;
 
     void onClearStencilClip(const GrFixedClip& clip, bool insideStencilMask) override;
 
diff --git a/src/gpu/mtl/GrMtlGpuCommandBuffer.mm b/src/gpu/mtl/GrMtlGpuCommandBuffer.mm
index b982577..48258cc 100644
--- a/src/gpu/mtl/GrMtlGpuCommandBuffer.mm
+++ b/src/gpu/mtl/GrMtlGpuCommandBuffer.mm
@@ -181,14 +181,12 @@
     fCommandBufferInfo.fBounds.join(bounds);
 }
 
-void GrMtlGpuRTCommandBuffer::onClear(const GrFixedClip& clip, GrColor color) {
+void GrMtlGpuRTCommandBuffer::onClear(const GrFixedClip& clip, const SkPMColor4f& color) {
     // if we end up here from absClear, the clear bounds may be bigger than the RT proxy bounds -
     // but in that case, scissor should be enabled, so this check should still succeed
     SkASSERT(!clip.scissorEnabled() || clip.scissorRect().contains(fBounds));
-    float clear[4];
-    GrColorToRGBAFloat(color, clear);
-    fRenderPassDesc.colorAttachments[0].clearColor = MTLClearColorMake(clear[0], clear[1], clear[2],
-                                                                       clear[3]);
+    fRenderPassDesc.colorAttachments[0].clearColor = MTLClearColorMake(color.fR, color.fG, color.fB,
+                                                                       color.fA);
     fRenderPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear;
     this->internalBegin();
     this->internalEnd();
@@ -242,8 +240,7 @@
             static_cast<GrMtlRenderTarget*>(fRenderTarget)->mtlRenderTexture();
     renderPassDesc.colorAttachments[0].slice = 0;
     renderPassDesc.colorAttachments[0].level = 0;
-    float clearColor[4];
-    GrColorToRGBAFloat(fColorLoadAndStoreInfo.fClearColor, clearColor);
+    const SkPMColor4f& clearColor = fColorLoadAndStoreInfo.fClearColor;
     renderPassDesc.colorAttachments[0].clearColor =
             MTLClearColorMake(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
     renderPassDesc.colorAttachments[0].loadAction =
diff --git a/src/gpu/ops/GrClearOp.cpp b/src/gpu/ops/GrClearOp.cpp
index 612ff20..ece91ad 100644
--- a/src/gpu/ops/GrClearOp.cpp
+++ b/src/gpu/ops/GrClearOp.cpp
@@ -14,7 +14,7 @@
 
 std::unique_ptr<GrClearOp> GrClearOp::Make(GrContext* context,
                                            const GrFixedClip& clip,
-                                           GrColor color,
+                                           const SkPMColor4f& color,
                                            GrSurfaceProxy* dstProxy) {
     const SkIRect rect = SkIRect::MakeWH(dstProxy->width(), dstProxy->height());
     if (clip.scissorEnabled() && !SkIRect::Intersects(clip.scissorRect(), rect)) {
@@ -28,7 +28,7 @@
 
 std::unique_ptr<GrClearOp> GrClearOp::Make(GrContext* context,
                                            const SkIRect& rect,
-                                           GrColor color,
+                                           const SkPMColor4f& color,
                                            bool fullScreen) {
     SkASSERT(fullScreen || !rect.isEmpty());
 
@@ -37,7 +37,7 @@
     return pool->allocate<GrClearOp>(rect, color, fullScreen);
 }
 
-GrClearOp::GrClearOp(const GrFixedClip& clip, GrColor color, GrSurfaceProxy* proxy)
+GrClearOp::GrClearOp(const GrFixedClip& clip, const SkPMColor4f& color, GrSurfaceProxy* proxy)
         : INHERITED(ClassID())
         , fClip(clip)
         , fColor(color) {
diff --git a/src/gpu/ops/GrClearOp.h b/src/gpu/ops/GrClearOp.h
index 7e19d61..c123e58 100644
--- a/src/gpu/ops/GrClearOp.h
+++ b/src/gpu/ops/GrClearOp.h
@@ -19,12 +19,12 @@
 
     static std::unique_ptr<GrClearOp> Make(GrContext* context,
                                            const GrFixedClip& clip,
-                                           GrColor color,
+                                           const SkPMColor4f& color,
                                            GrSurfaceProxy* dstProxy);
 
     static std::unique_ptr<GrClearOp> Make(GrContext* context,
                                            const SkIRect& rect,
-                                           GrColor color,
+                                           const SkPMColor4f& color,
                                            bool fullScreen);
 
     const char* name() const override { return "Clear"; }
@@ -39,19 +39,19 @@
         } else {
             string.append("disabled");
         }
-        string.appendf("], Color: 0x%08x\n", fColor);
+        string.appendf("], Color: 0x%08x\n", fColor.toBytes_RGBA());
         return string;
     }
 
-    GrColor color() const { return fColor; }
-    void setColor(GrColor color) { fColor = color; }
+    const SkPMColor4f& color() const { return fColor; }
+    void setColor(const SkPMColor4f& color) { fColor = color; }
 
 private:
     friend class GrOpMemoryPool; // for ctors
 
-    GrClearOp(const GrFixedClip& clip, GrColor color, GrSurfaceProxy* proxy);
+    GrClearOp(const GrFixedClip& clip, const SkPMColor4f& color, GrSurfaceProxy* proxy);
 
-    GrClearOp(const SkIRect& rect, GrColor color, bool fullScreen)
+    GrClearOp(const SkIRect& rect, const SkPMColor4f& color, bool fullScreen)
         : INHERITED(ClassID())
         , fClip(GrFixedClip(rect))
         , fColor(color) {
@@ -92,7 +92,7 @@
     void onExecute(GrOpFlushState* state) override;
 
     GrFixedClip fClip;
-    GrColor     fColor;
+    SkPMColor4f fColor;
 
     typedef GrOp INHERITED;
 };
diff --git a/src/gpu/vk/GrVkGpuCommandBuffer.cpp b/src/gpu/vk/GrVkGpuCommandBuffer.cpp
index fce6235..9ffd8f8 100644
--- a/src/gpu/vk/GrVkGpuCommandBuffer.cpp
+++ b/src/gpu/vk/GrVkGpuCommandBuffer.cpp
@@ -243,7 +243,7 @@
 
     this->INHERITED::set(rt, origin);
 
-    GrColorToRGBAFloat(colorInfo.fClearColor, fClearColor);
+    fClearColor = colorInfo.fClearColor;
 
     get_vk_load_store_ops(colorInfo.fLoadOp, colorInfo.fStoreOp,
                           &fVkColorLoadOp, &fVkColorStoreOp);
@@ -371,7 +371,7 @@
     }
 }
 
-void GrVkGpuRTCommandBuffer::onClear(const GrFixedClip& clip, GrColor color) {
+void GrVkGpuRTCommandBuffer::onClear(const GrFixedClip& clip, const SkPMColor4f& color) {
     GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
 
     // parent class should never let us get here with no RT
@@ -379,8 +379,7 @@
 
     CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
 
-    VkClearColorValue vkColor;
-    GrColorToRGBAFloat(color, vkColor.float32);
+    VkClearColorValue vkColor = {{color.fR, color.fG, color.fB, color.fA}};
 
     if (cbInfo.fIsEmpty && !clip.scissorEnabled()) {
         // Change the render pass to do a clear load
@@ -406,7 +405,7 @@
         SkASSERT(cbInfo.fRenderPass->isCompatible(*oldRP));
         oldRP->unref(fGpu);
 
-        GrColorToRGBAFloat(color, cbInfo.fColorClearValue.color.float32);
+        cbInfo.fColorClearValue.color = {{color.fR, color.fG, color.fB, color.fA}};
         cbInfo.fLoadStoreState = LoadStoreState::kStartsWithClear;
         // If we are going to clear the whole render target then the results of any copies we did
         // immediately before to the target won't matter, so just drop them.
diff --git a/src/gpu/vk/GrVkGpuCommandBuffer.h b/src/gpu/vk/GrVkGpuCommandBuffer.h
index b40cff3..151d962 100644
--- a/src/gpu/vk/GrVkGpuCommandBuffer.h
+++ b/src/gpu/vk/GrVkGpuCommandBuffer.h
@@ -134,7 +134,7 @@
                                        const GrBuffer* instanceBuffer, int instanceCount,
                                        int baseInstance, GrPrimitiveRestart) final;
 
-    void onClear(const GrFixedClip&, GrColor color) override;
+    void onClear(const GrFixedClip&, const SkPMColor4f& color) override;
 
     void onClearStencilClip(const GrFixedClip&, bool insideStencilMask) override;
 
@@ -201,7 +201,7 @@
     VkAttachmentStoreOp         fVkColorStoreOp;
     VkAttachmentLoadOp          fVkStencilLoadOp;
     VkAttachmentStoreOp         fVkStencilStoreOp;
-    float                       fClearColor[4];
+    SkPMColor4f                 fClearColor;
     GrVkPipelineState*          fLastPipelineState;
 
     typedef GrGpuRTCommandBuffer INHERITED;