Make GrPaints move their GrProcessor ownership into GrPipelineBuilder.

This makes GrPaints usable only once. In some places we must make copies in order to issue draws with the same paint state.

Change-Id: Ie816e5185ce93a064111cad64c6880e1e21184c2
Reviewed-on: https://skia-review.googlesource.com/6844
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/gm/beziereffects.cpp b/gm/beziereffects.cpp
index bcce9db..cc28538 100644
--- a/gm/beziereffects.cpp
+++ b/gm/beziereffects.cpp
@@ -198,8 +198,8 @@
                     std::unique_ptr<GrDrawOp> op =
                             BezierCubicOrConicTestOp::Make(gp, bounds, color, klmEqs, klmSigns[c]);
 
-                    renderTargetContext->priv().testingOnly_addDrawOp(grPaint, GrAAType::kNone,
-                                                                      std::move(op));
+                    renderTargetContext->priv().testingOnly_addDrawOp(
+                            std::move(grPaint), GrAAType::kNone, std::move(op));
                 }
                 ++col;
                 if (numCols == col) {
@@ -331,8 +331,8 @@
                     std::unique_ptr<GrDrawOp> op =
                             BezierCubicOrConicTestOp::Make(gp, bounds, color, klmEqs, 1.f);
 
-                    renderTargetContext->priv().testingOnly_addDrawOp(grPaint, GrAAType::kNone,
-                                                                      std::move(op));
+                    renderTargetContext->priv().testingOnly_addDrawOp(
+                            std::move(grPaint), GrAAType::kNone, std::move(op));
                 }
                 ++col;
                 if (numCols == col) {
@@ -547,8 +547,8 @@
                     std::unique_ptr<GrDrawOp> op =
                             BezierQuadTestOp::Make(gp, bounds, color, DevToUV);
 
-                    renderTargetContext->priv().testingOnly_addDrawOp(grPaint, GrAAType::kNone,
-                                                                      std::move(op));
+                    renderTargetContext->priv().testingOnly_addDrawOp(
+                            std::move(grPaint), GrAAType::kNone, std::move(op));
                 }
                 ++col;
                 if (numCols == col) {
diff --git a/gm/bigrrectaaeffect.cpp b/gm/bigrrectaaeffect.cpp
index d8034a4..f4e00fb 100644
--- a/gm/bigrrectaaeffect.cpp
+++ b/gm/bigrrectaaeffect.cpp
@@ -74,14 +74,13 @@
                 paint.setColor(SK_ColorWHITE);
                 canvas->drawRect(testBounds, paint);
 
-                GrPaint grPaint;
-                grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
-
                 SkRRect rrect = fRRect;
                 rrect.offset(SkIntToScalar(x + kGap), SkIntToScalar(y + kGap));
                 sk_sp<GrFragmentProcessor> fp(GrRRectEffect::Make(edgeType, rrect));
                 SkASSERT(fp);
                 if (fp) {
+                    GrPaint grPaint;
+                    grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
                     grPaint.addCoverageFragmentProcessor(std::move(fp));
 
                     SkRect bounds = testBounds;
@@ -89,8 +88,8 @@
 
                     std::unique_ptr<GrDrawOp> op(GrRectOpFactory::MakeNonAAFill(
                             0xff000000, SkMatrix::I(), bounds, nullptr, nullptr));
-                    renderTargetContext->priv().testingOnly_addDrawOp(grPaint, GrAAType::kNone,
-                                                                      std::move(op));
+                    renderTargetContext->priv().testingOnly_addDrawOp(
+                            std::move(grPaint), GrAAType::kNone, std::move(op));
                 }
             canvas->restore();
             x = x + fTestOffsetX;
diff --git a/gm/constcolorprocessor.cpp b/gm/constcolorprocessor.cpp
index 0fe476f..17a1bc5 100644
--- a/gm/constcolorprocessor.cpp
+++ b/gm/constcolorprocessor.cpp
@@ -111,8 +111,8 @@
 
                     std::unique_ptr<GrDrawOp> op(GrRectOpFactory::MakeNonAAFill(
                             grPaint.getColor(), viewMatrix, renderRect, nullptr, nullptr));
-                    renderTargetContext->priv().testingOnly_addDrawOp(grPaint, GrAAType::kNone,
-                                                                      std::move(op));
+                    renderTargetContext->priv().testingOnly_addDrawOp(
+                            std::move(grPaint), GrAAType::kNone, std::move(op));
 
                     // Draw labels for the input to the processor and the processor to the right of
                     // the test rect. The input label appears above the processor label.
diff --git a/gm/convexpolyeffect.cpp b/gm/convexpolyeffect.cpp
index 5927d5d..1be92da 100644
--- a/gm/convexpolyeffect.cpp
+++ b/gm/convexpolyeffect.cpp
@@ -185,8 +185,8 @@
 
                 std::unique_ptr<GrDrawOp> op = PolyBoundsOp::Make(p.getBounds(), 0xff000000);
 
-                renderTargetContext->priv().testingOnly_addDrawOp(grPaint, GrAAType::kNone,
-                                                                  std::move(op));
+                renderTargetContext->priv().testingOnly_addDrawOp(std::move(grPaint),
+                                                                  GrAAType::kNone, std::move(op));
 
                 x += SkScalarCeilToScalar(path->getBounds().width() + kDX);
             }
@@ -225,8 +225,8 @@
 
                 std::unique_ptr<GrDrawOp> op = PolyBoundsOp::Make(rect, 0xff000000);
 
-                renderTargetContext->priv().testingOnly_addDrawOp(grPaint, GrAAType::kNone,
-                                                                  std::move(op));
+                renderTargetContext->priv().testingOnly_addDrawOp(std::move(grPaint),
+                                                                  GrAAType::kNone, std::move(op));
 
                 x += SkScalarCeilToScalar(rect.width() + kDX);
             }
diff --git a/gm/rrects.cpp b/gm/rrects.cpp
index 33de77f..d4f5bdf 100644
--- a/gm/rrects.cpp
+++ b/gm/rrects.cpp
@@ -102,14 +102,13 @@
                     canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
                     if (kEffect_Type == fType) {
 #if SK_SUPPORT_GPU
-                        GrPaint grPaint;
-                        grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
-
                         SkRRect rrect = fRRects[curRRect];
                         rrect.offset(SkIntToScalar(x), SkIntToScalar(y));
                         GrPrimitiveEdgeType edgeType = (GrPrimitiveEdgeType) et;
                         sk_sp<GrFragmentProcessor> fp(GrRRectEffect::Make(edgeType, rrect));
                         if (fp) {
+                            GrPaint grPaint;
+                            grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
                             grPaint.addCoverageFragmentProcessor(std::move(fp));
 
                             SkRect bounds = rrect.getBounds();
@@ -117,9 +116,8 @@
 
                             std::unique_ptr<GrDrawOp> op(GrRectOpFactory::MakeNonAAFill(
                                     0xff000000, SkMatrix::I(), bounds, nullptr, nullptr));
-                            renderTargetContext->priv().testingOnly_addDrawOp(grPaint,
-                                                                              GrAAType::kNone,
-                                                                              std::move(op));
+                            renderTargetContext->priv().testingOnly_addDrawOp(
+                                    std::move(grPaint), GrAAType::kNone, std::move(op));
                         } else {
                             drew = false;
                         }
diff --git a/gm/texdata.cpp b/gm/texdata.cpp
index 574dfad..8520d28 100644
--- a/gm/texdata.cpp
+++ b/gm/texdata.cpp
@@ -102,7 +102,8 @@
         tm.postIDiv(2*S, 2*S);
         paint.addColorTextureProcessor(texture, nullptr, tm);
 
-        renderTargetContext->drawRect(clip, paint, GrAA::kNo, vm, SkRect::MakeWH(2*S, 2*S));
+        renderTargetContext->drawRect(clip, GrPaint(paint), GrAA::kNo, vm,
+                                      SkRect::MakeWH(2 * S, 2 * S));
 
         // now update the lower right of the texture in first pass
         // or upper right in second pass
@@ -116,7 +117,8 @@
         texture->writePixels(S, (i ? 0 : S), S, S,
                                 texture->config(), gTextureData.get(),
                                 4 * stride);
-        renderTargetContext->drawRect(clip, paint, GrAA::kNo, vm, SkRect::MakeWH(2*S, 2*S));
+        renderTargetContext->drawRect(clip, std::move(paint), GrAA::kNo, vm,
+                                      SkRect::MakeWH(2 * S, 2 * S));
     }
 }
 #endif
diff --git a/gm/texturedomaineffect.cpp b/gm/texturedomaineffect.cpp
index 7313f89..32042aa 100644
--- a/gm/texturedomaineffect.cpp
+++ b/gm/texturedomaineffect.cpp
@@ -128,8 +128,8 @@
 
                     std::unique_ptr<GrDrawOp> op(GrRectOpFactory::MakeNonAAFill(
                             GrColor_WHITE, viewMatrix, renderRect, nullptr, nullptr));
-                    renderTargetContext->priv().testingOnly_addDrawOp(grPaint, GrAAType::kNone,
-                                                                      std::move(op));
+                    renderTargetContext->priv().testingOnly_addDrawOp(
+                            std::move(grPaint), GrAAType::kNone, std::move(op));
                     x += renderRect.width() + kTestPad;
                 }
                 y += renderRect.height() + kTestPad;
diff --git a/gm/windowrectangles.cpp b/gm/windowrectangles.cpp
index 156da58..29356fc 100644
--- a/gm/windowrectangles.cpp
+++ b/gm/windowrectangles.cpp
@@ -127,10 +127,8 @@
     constexpr static int kMaskCheckerSize = 5;
     SkString onShortName() final { return SkString("windowrectangles_mask"); }
     void onCoverClipStack(const SkClipStack&, SkCanvas*) final;
-    void visualizeAlphaMask(GrContext*, GrRenderTargetContext*, const GrReducedClip&,
-                            const GrPaint&);
-    void visualizeStencilMask(GrContext*, GrRenderTargetContext*, const GrReducedClip&,
-                              const GrPaint&);
+    void visualizeAlphaMask(GrContext*, GrRenderTargetContext*, const GrReducedClip&, GrPaint&&);
+    void visualizeStencilMask(GrContext*, GrRenderTargetContext*, const GrReducedClip&, GrPaint&&);
     void stencilCheckerboard(GrRenderTargetContext*, bool flip);
     void fail(SkCanvas*);
 };
@@ -192,16 +190,15 @@
     GrPaint paint;
     if (!rtc->isStencilBufferMultisampled()) {
         paint.setColor4f(GrColor4f(0, 0.25f, 1, 1));
-        this->visualizeAlphaMask(ctx, rtc, reducedClip, paint);
+        this->visualizeAlphaMask(ctx, rtc, reducedClip, std::move(paint));
     } else {
         paint.setColor4f(GrColor4f(1, 0.25f, 0.25f, 1));
-        this->visualizeStencilMask(ctx, rtc, reducedClip, paint);
+        this->visualizeStencilMask(ctx, rtc, reducedClip, std::move(paint));
     }
 }
 
 void WindowRectanglesMaskGM::visualizeAlphaMask(GrContext* ctx, GrRenderTargetContext* rtc,
-                                                const GrReducedClip& reducedClip,
-                                                const GrPaint& paint) {
+                                                const GrReducedClip& reducedClip, GrPaint&& paint) {
     sk_sp<GrRenderTargetContext> maskRTC(
         ctx->makeRenderTargetContextWithFallback(SkBackingFit::kExact, kLayerRect.width(),
                                                  kLayerRect.height(), kAlpha_8_GrPixelConfig,
@@ -228,13 +225,13 @@
     // inside window rectangles or outside the scissor should still have the initial checkerboard
     // intact. (This verifies we didn't spend any time modifying those pixels in the mask.)
     AlphaOnlyClip clip(mask.get(), x, y);
-    rtc->drawRect(clip, paint, GrAA::kYes, SkMatrix::I(),
-                 SkRect::Make(SkIRect::MakeXYWH(x, y, mask->width(), mask->height())));
+    rtc->drawRect(clip, std::move(paint), GrAA::kYes, SkMatrix::I(),
+                  SkRect::Make(SkIRect::MakeXYWH(x, y, mask->width(), mask->height())));
 }
 
 void WindowRectanglesMaskGM::visualizeStencilMask(GrContext* ctx, GrRenderTargetContext* rtc,
                                                   const GrReducedClip& reducedClip,
-                                                  const GrPaint& paint) {
+                                                  GrPaint&& paint) {
     if (!ctx->resourceProvider()->attachStencilAttachment(rtc->accessRenderTarget())) {
         return;
     }
@@ -247,7 +244,7 @@
     // Now visualize the stencil mask by covering the entire render target. The regions inside
     // window rectangless or outside the scissor should still have the initial checkerboard intact.
     // (This verifies we didn't spend any time modifying those pixels in the mask.)
-    rtc->drawPaint(StencilOnlyClip(), paint, SkMatrix::I());
+    rtc->drawPaint(StencilOnlyClip(), std::move(paint), SkMatrix::I());
 }
 
 void WindowRectanglesMaskGM::stencilCheckerboard(GrRenderTargetContext* rtc, bool flip) {
diff --git a/gm/yuvtorgbeffect.cpp b/gm/yuvtorgbeffect.cpp
index 103c2e4..8d78f13 100644
--- a/gm/yuvtorgbeffect.cpp
+++ b/gm/yuvtorgbeffect.cpp
@@ -110,8 +110,6 @@
                                        {1, 2, 0}, {2, 0, 1}, {2, 1, 0}};
 
             for (int i = 0; i < 6; ++i) {
-                GrPaint grPaint;
-                grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
                 sk_sp<GrFragmentProcessor> fp(
                         GrYUVEffect::MakeYUVToRGB(texture[indices[i][0]].get(),
                                                   texture[indices[i][1]].get(),
@@ -120,13 +118,15 @@
                                                   static_cast<SkYUVColorSpace>(space),
                                                   false));
                 if (fp) {
+                    GrPaint grPaint;
+                    grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
+                    grPaint.addColorFragmentProcessor(std::move(fp));
                     SkMatrix viewMatrix;
                     viewMatrix.setTranslate(x, y);
-                    grPaint.addColorFragmentProcessor(std::move(fp));
                     std::unique_ptr<GrDrawOp> op(GrRectOpFactory::MakeNonAAFill(
                             GrColor_WHITE, viewMatrix, renderRect, nullptr, nullptr));
-                    renderTargetContext->priv().testingOnly_addDrawOp(grPaint, GrAAType::kNone,
-                                                                      std::move(op));
+                    renderTargetContext->priv().testingOnly_addDrawOp(
+                            std::move(grPaint), GrAAType::kNone, std::move(op));
                 }
                 x += renderRect.width() + kTestPad;
             }
@@ -238,8 +238,8 @@
                 grPaint.addColorFragmentProcessor(fp);
                 std::unique_ptr<GrDrawOp> op(GrRectOpFactory::MakeNonAAFill(
                         GrColor_WHITE, viewMatrix, renderRect, nullptr, nullptr));
-                renderTargetContext->priv().testingOnly_addDrawOp(grPaint, GrAAType::kNone,
-                                                                  std::move(op));
+                renderTargetContext->priv().testingOnly_addDrawOp(std::move(grPaint),
+                                                                  GrAAType::kNone, std::move(op));
             }
         }
     }
diff --git a/include/core/SkMaskFilter.h b/include/core/SkMaskFilter.h
index 198cf37..3475429 100644
--- a/include/core/SkMaskFilter.h
+++ b/include/core/SkMaskFilter.h
@@ -112,23 +112,23 @@
                                   SkRect* maskRect) const;
 
     /**
-     *  Try to directly render the mask filter into the target.  Returns
-     *  true if drawing was successful.
+     *  Try to directly render the mask filter into the target. Returns true if drawing was
+     *  successful. If false is returned then paint is unmodified.
      */
     virtual bool directFilterMaskGPU(GrTextureProvider* texProvider,
                                      GrRenderTargetContext* renderTargetContext,
-                                     GrPaint* grp,
+                                     GrPaint&& paint,
                                      const GrClip&,
                                      const SkMatrix& viewMatrix,
                                      const SkStrokeRec& strokeRec,
                                      const SkPath& path) const;
     /**
      *  Try to directly render a rounded rect mask filter into the target.  Returns
-     *  true if drawing was successful.
+     *  true if drawing was successful.  If false is returned then paint is unmodified.
      */
     virtual bool directFilterRRectMaskGPU(GrContext*,
                                           GrRenderTargetContext* renderTargetContext,
-                                          GrPaint* grp,
+                                          GrPaint&& paint,
                                           const GrClip&,
                                           const SkMatrix& viewMatrix,
                                           const SkStrokeRec& strokeRec,
diff --git a/include/gpu/GrPaint.h b/include/gpu/GrPaint.h
index 6bbd66c..0f3b525 100644
--- a/include/gpu/GrPaint.h
+++ b/include/gpu/GrPaint.h
@@ -12,13 +12,13 @@
 
 #include "GrColor.h"
 #include "GrColorSpaceXform.h"
-#include "GrXferProcessor.h"
-#include "effects/GrPorterDuffXferProcessor.h"
 #include "GrFragmentProcessor.h"
-
+#include "GrXferProcessor.h"
 #include "SkBlendMode.h"
 #include "SkRefCnt.h"
 #include "SkRegion.h"
+#include "SkTLazy.h"
+#include "effects/GrPorterDuffXferProcessor.h"
 
 /**
  * The paint describes how color and coverage are computed at each pixel by GrContext draw
@@ -39,11 +39,9 @@
  */
 class GrPaint {
 public:
-    GrPaint();
-
-    GrPaint(const GrPaint& paint) { *this = paint; }
-
-    ~GrPaint() { }
+    GrPaint() = default;
+    explicit GrPaint(const GrPaint&) = default;
+    ~GrPaint() = default;
 
     /**
      * The initial color of the drawn primitive. Defaults to solid white.
@@ -132,20 +130,6 @@
         return fCoverageFragmentProcessors[i].get();
     }
 
-    GrPaint& operator=(const GrPaint& paint) {
-        fDisableOutputConversionToSRGB = paint.fDisableOutputConversionToSRGB;
-        fAllowSRGBInputs = paint.fAllowSRGBInputs;
-        fUsesDistanceVectorField = paint.fUsesDistanceVectorField;
-
-        fColor = paint.fColor;
-        fColorFragmentProcessors = paint.fColorFragmentProcessors;
-        fCoverageFragmentProcessors = paint.fCoverageFragmentProcessors;
-
-        fXPFactory = paint.fXPFactory;
-
-        return *this;
-    }
-
     /**
      * Returns true if the paint's output color will be constant after blending. If the result is
      * true, constantColor will be updated to contain the constant color. Note that we can conflate
@@ -165,17 +149,61 @@
     }
 
 private:
+    template <bool> class MoveOrImpl;
+
+public:
+    /**
+     * A temporary instance of this class can be used to select between moving an existing paint or
+     * a temporary copy of an existing paint into a call site. MoveOrClone(paint, false) is a rvalue
+     * reference to paint while MoveOrClone(paint, true) is a rvalue reference to a copy of paint.
+     */
+    using MoveOrClone = MoveOrImpl<true>;
+
+    /**
+     * A temporary instance of this class can be used to select between moving an existing or a
+     * newly default constructed paint into a call site. MoveOrNew(paint, false) is a rvalue
+     * reference to paint while MoveOrNew(paint, true) is a rvalue reference to a default paint.
+     */
+    using MoveOrNew = MoveOrImpl<false>;
+
+private:
+    GrPaint& operator=(const GrPaint&) = delete;
+
+    friend class GrPipelineBuilder;
+
     bool internalIsConstantBlendedColor(GrColor paintColor, GrColor* constantColor) const;
 
-    const GrXPFactory*                        fXPFactory;
+    const GrXPFactory* fXPFactory = nullptr;
     SkSTArray<4, sk_sp<GrFragmentProcessor>>  fColorFragmentProcessors;
     SkSTArray<2, sk_sp<GrFragmentProcessor>>  fCoverageFragmentProcessors;
+    bool fDisableOutputConversionToSRGB = false;
+    bool fAllowSRGBInputs = false;
+    bool fUsesDistanceVectorField = false;
+    GrColor4f fColor = GrColor4f::OpaqueWhite();
+};
 
-    bool                                      fDisableOutputConversionToSRGB;
-    bool                                      fAllowSRGBInputs;
-    bool                                      fUsesDistanceVectorField;
+/** This is the implementation of MoveOrCopy and MoveOrNew. */
+template <bool COPY_IF_NEW>
+class GrPaint::MoveOrImpl {
+public:
+    MoveOrImpl(GrPaint& paint, bool newPaint) {
+        if (newPaint) {
+            if (COPY_IF_NEW) {
+                fStorage.init(paint);
+            } else {
+                fStorage.init();
+            };
+            fPaint = fStorage.get();
+        } else {
+            fPaint = &paint;
+        }
+    }
 
-    GrColor4f                                 fColor;
+    operator GrPaint&&() { return std::move(*fPaint); }
+
+private:
+    SkTLazy<GrPaint> fStorage;
+    GrPaint* fPaint;
 };
 
 #endif
diff --git a/include/gpu/GrRenderTargetContext.h b/include/gpu/GrRenderTargetContext.h
index 5813f98..b16e6c7 100644
--- a/include/gpu/GrRenderTargetContext.h
+++ b/include/gpu/GrRenderTargetContext.h
@@ -53,13 +53,13 @@
     // TODO: it is odd that we need both the SkPaint in the following 3 methods.
     // We should extract the text parameters from SkPaint and pass them separately
     // akin to GrStyle (GrTextInfo?)
-    virtual void drawText(const GrClip&,  const GrPaint&, const SkPaint&,
-                          const SkMatrix& viewMatrix, const char text[], size_t byteLength,
-                          SkScalar x, SkScalar y, const SkIRect& clipBounds);
-    virtual void drawPosText(const GrClip&, const GrPaint&, const SkPaint&,
-                             const SkMatrix& viewMatrix, const char text[], size_t byteLength,
-                             const SkScalar pos[], int scalarsPerPosition,
-                             const SkPoint& offset, const SkIRect& clipBounds);
+    virtual void drawText(const GrClip&, GrPaint&&, const SkPaint&, const SkMatrix& viewMatrix,
+                          const char text[], size_t byteLength, SkScalar x, SkScalar y,
+                          const SkIRect& clipBounds);
+    virtual void drawPosText(const GrClip&, GrPaint&&, const SkPaint&, const SkMatrix& viewMatrix,
+                             const char text[], size_t byteLength, const SkScalar pos[],
+                             int scalarsPerPosition, const SkPoint& offset,
+                             const SkIRect& clipBounds);
     virtual void drawTextBlob(const GrClip&, const SkPaint&,
                               const SkMatrix& viewMatrix, const SkTextBlob*,
                               SkScalar x, SkScalar y,
@@ -83,7 +83,7 @@
     /**
      *  Draw everywhere (respecting the clip) with the paint.
      */
-    void drawPaint(const GrClip&, const GrPaint&, const SkMatrix& viewMatrix);
+    void drawPaint(const GrClip&, GrPaint&&, const SkMatrix& viewMatrix);
 
     /**
      * Draw the rect using a paint.
@@ -95,11 +95,11 @@
      * The rects coords are used to access the paint (through texture matrix)
      */
     void drawRect(const GrClip&,
-                  const GrPaint& paint,
+                  GrPaint&& paint,
                   GrAA,
                   const SkMatrix& viewMatrix,
                   const SkRect&,
-                  const GrStyle* style  = nullptr);
+                  const GrStyle* style = nullptr);
 
     /**
      * Maps a rectangle of shader coordinates to a rectangle and fills that rectangle.
@@ -111,7 +111,7 @@
      * @param localRect    the rectangle of shader coordinates applied to rectToDraw
      */
     void fillRectToRect(const GrClip&,
-                        const GrPaint& paint,
+                        GrPaint&& paint,
                         GrAA,
                         const SkMatrix& viewMatrix,
                         const SkRect& rectToDraw,
@@ -121,7 +121,7 @@
      * Fills a rect with a paint and a localMatrix.
      */
     void fillRectWithLocalMatrix(const GrClip& clip,
-                                 const GrPaint& paint,
+                                 GrPaint&& paint,
                                  GrAA,
                                  const SkMatrix& viewMatrix,
                                  const SkRect& rect,
@@ -137,7 +137,7 @@
      * @param style       style to apply to the rrect. Currently path effects are not allowed.
      */
     void drawRRect(const GrClip&,
-                   const GrPaint&,
+                   GrPaint&&,
                    GrAA,
                    const SkMatrix& viewMatrix,
                    const SkRRect& rrect,
@@ -154,7 +154,7 @@
      * @param style        style to apply to the rrect. Currently path effects are not allowed.
      */
     void drawShadowRRect(const GrClip&,
-                         const GrPaint&,
+                         GrPaint&&,
                          const SkMatrix& viewMatrix,
                          const SkRRect& rrect,
                          SkScalar blurRadius,
@@ -171,7 +171,7 @@
      * @param inner        the inner roundrect
      */
     void drawDRRect(const GrClip&,
-                    const GrPaint&,
+                    GrPaint&&,
                     GrAA,
                     const SkMatrix& viewMatrix,
                     const SkRRect& outer,
@@ -187,7 +187,7 @@
      * @param style         style to apply to the path.
      */
     void drawPath(const GrClip&,
-                  const GrPaint&,
+                  GrPaint&&,
                   GrAA,
                   const SkMatrix& viewMatrix,
                   const SkPath&,
@@ -211,7 +211,7 @@
      *                          number of indices.
      */
     void drawVertices(const GrClip&,
-                      const GrPaint& paint,
+                      GrPaint&& paint,
                       const SkMatrix& viewMatrix,
                       GrPrimitiveType primitiveType,
                       int vertexCount,
@@ -234,7 +234,7 @@
      *                          the paint's color field.
      */
     void drawAtlas(const GrClip&,
-                   const GrPaint& paint,
+                   GrPaint&& paint,
                    const SkMatrix& viewMatrix,
                    int spriteCount,
                    const SkRSXform xform[],
@@ -251,7 +251,7 @@
      * @param style         style to apply to the region
      */
     void drawRegion(const GrClip&,
-                    const GrPaint& paint,
+                    GrPaint&& paint,
                     GrAA aa,
                     const SkMatrix& viewMatrix,
                     const SkRegion& region,
@@ -267,7 +267,7 @@
      * @param style         style to apply to the oval. Currently path effects are not allowed.
      */
     void drawOval(const GrClip&,
-                  const GrPaint& paint,
+                  GrPaint&& paint,
                   GrAA,
                   const SkMatrix& viewMatrix,
                   const SkRect& oval,
@@ -288,7 +288,7 @@
      * @param style         style to apply to the oval.
      */
     void drawArc(const GrClip&,
-                 const GrPaint& paint,
+                 GrPaint&& paint,
                  GrAA,
                  const SkMatrix& viewMatrix,
                  const SkRect& oval,
@@ -301,7 +301,7 @@
      * Draw the image as a set of rects, specified by |iter|.
      */
     void drawImageLattice(const GrClip&,
-                          const GrPaint& paint,
+                          GrPaint&& paint,
                           const SkMatrix& viewMatrix,
                           int imageWidth,
                           int imageHeight,
@@ -437,22 +437,24 @@
 
     void internalClear(const GrFixedClip&, const GrColor, bool canIgnoreClip);
 
+    // Only consumes the GrPaint if successful.
     bool drawFilledDRRect(const GrClip& clip,
-                          const GrPaint& paint,
+                          GrPaint&& paint,
                           GrAA,
                           const SkMatrix& viewMatrix,
                           const SkRRect& origOuter,
                           const SkRRect& origInner);
 
+    // Only consumes the GrPaint if successful.
     bool drawFilledRect(const GrClip& clip,
-                        const GrPaint& paint,
+                        GrPaint&& paint,
                         GrAA,
                         const SkMatrix& viewMatrix,
                         const SkRect& rect,
                         const GrUserStencilSettings* ss);
 
     void drawNonAAFilledRect(const GrClip&,
-                             const GrPaint&,
+                             GrPaint&&,
                              const SkMatrix& viewMatrix,
                              const SkRect& rect,
                              const SkRect* localRect,
@@ -460,12 +462,8 @@
                              const GrUserStencilSettings* ss,
                              GrAAType hwOrNoneAAType);
 
-    void internalDrawPath(const GrClip&,
-                          const GrPaint&,
-                          GrAA,
-                          const SkMatrix&,
-                          const SkPath&,
-                          const GrStyle&);
+    void internalDrawPath(
+            const GrClip&, GrPaint&&, GrAA, const SkMatrix&, const SkPath&, const GrStyle&);
 
     bool onCopy(GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override;
 
diff --git a/src/core/SkGpuBlurUtils.cpp b/src/core/SkGpuBlurUtils.cpp
index 005670a..b3b523a 100644
--- a/src/core/SkGpuBlurUtils.cpp
+++ b/src/core/SkGpuBlurUtils.cpp
@@ -84,7 +84,7 @@
     paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
     SkMatrix localMatrix = SkMatrix::MakeTrans(-SkIntToScalar(srcOffset.x()),
                                                -SkIntToScalar(srcOffset.y()));
-    renderTargetContext->fillRectWithLocalMatrix(clip, paint, GrAA::kNo, SkMatrix::I(),
+    renderTargetContext->fillRectWithLocalMatrix(clip, std::move(paint), GrAA::kNo, SkMatrix::I(),
                                                  SkRect::Make(dstRect), localMatrix);
 }
 
@@ -112,7 +112,7 @@
             true, sigmaX, sigmaY));
     paint.addColorFragmentProcessor(std::move(conv));
     paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
-    renderTargetContext->fillRectWithLocalMatrix(clip, paint, GrAA::kNo, SkMatrix::I(),
+    renderTargetContext->fillRectWithLocalMatrix(clip, std::move(paint), GrAA::kNo, SkMatrix::I(),
                                                  SkRect::Make(dstRect), localMatrix);
 }
 
@@ -288,7 +288,7 @@
         paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
         shrink_irect_by_2(&dstRect, i < scaleFactorX, i < scaleFactorY);
 
-        dstRenderTargetContext->fillRectToRect(clip, paint, GrAA::kNo, SkMatrix::I(),
+        dstRenderTargetContext->fillRectToRect(clip, std::move(paint), GrAA::kNo, SkMatrix::I(),
                                                SkRect::Make(dstRect), SkRect::Make(srcRect));
 
         srcRenderTargetContext = dstRenderTargetContext;
@@ -380,7 +380,7 @@
         SkIRect dstRect(srcRect);
         scale_irect(&dstRect, scaleFactorX, scaleFactorY);
 
-        dstRenderTargetContext->fillRectToRect(clip, paint, GrAA::kNo, SkMatrix::I(),
+        dstRenderTargetContext->fillRectToRect(clip, std::move(paint), GrAA::kNo, SkMatrix::I(),
                                                SkRect::Make(dstRect), SkRect::Make(srcRect));
 
         srcRenderTargetContext = dstRenderTargetContext;
diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp
index 90433fa..8ce5e8e 100644
--- a/src/core/SkImageFilter.cpp
+++ b/src/core/SkImageFilter.cpp
@@ -298,7 +298,8 @@
     SkRect srcRect = SkRect::Make(bounds);
     SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
     GrFixedClip clip(dstIRect);
-    renderTargetContext->fillRectToRect(clip, paint, GrAA::kNo, SkMatrix::I(), dstRect, srcRect);
+    renderTargetContext->fillRectToRect(clip, std::move(paint), GrAA::kNo, SkMatrix::I(), dstRect,
+                                        srcRect);
 
     return SkSpecialImage::MakeDeferredFromGpu(context, dstIRect,
                                                kNeedNewImageUniqueID_SpecialImage,
diff --git a/src/core/SkMaskFilter.cpp b/src/core/SkMaskFilter.cpp
index 8ad13aa..59dbe2e 100644
--- a/src/core/SkMaskFilter.cpp
+++ b/src/core/SkMaskFilter.cpp
@@ -314,20 +314,19 @@
     return false;
 }
 
- bool SkMaskFilter::directFilterMaskGPU(GrTextureProvider* texProvider,
-                                        GrRenderTargetContext* renderTargetContext,
-                                        GrPaint* grp,
-                                        const GrClip&,
-                                        const SkMatrix& viewMatrix,
-                                        const SkStrokeRec& strokeRec,
-                                        const SkPath& path) const {
+bool SkMaskFilter::directFilterMaskGPU(GrTextureProvider* texProvider,
+                                       GrRenderTargetContext* renderTargetContext,
+                                       GrPaint&&,
+                                       const GrClip&,
+                                       const SkMatrix& viewMatrix,
+                                       const SkStrokeRec& strokeRec,
+                                       const SkPath& path) const {
     return false;
 }
 
-
 bool SkMaskFilter::directFilterRRectMaskGPU(GrContext*,
                                             GrRenderTargetContext* renderTargetContext,
-                                            GrPaint* grp,
+                                            GrPaint&&,
                                             const GrClip&,
                                             const SkMatrix& viewMatrix,
                                             const SkStrokeRec& strokeRec,
diff --git a/src/effects/SkAlphaThresholdFilter.cpp b/src/effects/SkAlphaThresholdFilter.cpp
index 81416e2..82daa3c 100644
--- a/src/effects/SkAlphaThresholdFilter.cpp
+++ b/src/effects/SkAlphaThresholdFilter.cpp
@@ -106,15 +106,15 @@
         return nullptr;
     }
 
-    GrPaint grPaint;
-    grPaint.setPorterDuffXPFactory(SkBlendMode::kSrc);
+    GrPaint paint;
+    paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
     SkRegion::Iterator iter(fRegion);
     rtContext->clear(nullptr, 0x0, true);
 
     GrFixedClip clip(SkIRect::MakeWH(bounds.width(), bounds.height()));
     while (!iter.done()) {
         SkRect rect = SkRect::Make(iter.rect());
-        rtContext->drawRect(clip, grPaint, GrAA::kNo, inMatrix, rect);
+        rtContext->drawRect(clip, std::move(paint), GrAA::kNo, inMatrix, rect);
         iter.next();
     }
 
diff --git a/src/effects/SkArithmeticImageFilter.cpp b/src/effects/SkArithmeticImageFilter.cpp
index dc15254..1e4f589 100644
--- a/src/effects/SkArithmeticImageFilter.cpp
+++ b/src/effects/SkArithmeticImageFilter.cpp
@@ -403,7 +403,8 @@
 
     SkMatrix matrix;
     matrix.setTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top()));
-    renderTargetContext->drawRect(GrNoClip(), paint, GrAA::kNo, matrix, SkRect::Make(bounds));
+    renderTargetContext->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, matrix,
+                                  SkRect::Make(bounds));
 
     return SkSpecialImage::MakeDeferredFromGpu(context,
                                                SkIRect::MakeWH(bounds.width(), bounds.height()),
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
index f56c273..fa4cb33 100644
--- a/src/effects/SkBlurMaskFilter.cpp
+++ b/src/effects/SkBlurMaskFilter.cpp
@@ -52,14 +52,14 @@
                           SkRect* maskRect) const override;
     bool directFilterMaskGPU(GrTextureProvider* texProvider,
                              GrRenderTargetContext* renderTargetContext,
-                             GrPaint* grp,
+                             GrPaint&&,
                              const GrClip&,
                              const SkMatrix& viewMatrix,
                              const SkStrokeRec& strokeRec,
                              const SkPath& path) const override;
     bool directFilterRRectMaskGPU(GrContext*,
                                   GrRenderTargetContext* renderTargetContext,
-                                  GrPaint* grp,
+                                  GrPaint&&,
                                   const GrClip&,
                                   const SkMatrix& viewMatrix,
                                   const SkStrokeRec& strokeRec,
@@ -1014,10 +1014,9 @@
                                   sigma);
 }
 
-
 bool SkBlurMaskFilterImpl::directFilterMaskGPU(GrTextureProvider* texProvider,
                                                GrRenderTargetContext* renderTargetContext,
-                                               GrPaint* grp,
+                                               GrPaint&& paint,
                                                const GrClip& clip,
                                                const SkMatrix& viewMatrix,
                                                const SkStrokeRec& strokeRec,
@@ -1057,15 +1056,14 @@
         return false;
     }
 
-    grp->addCoverageFragmentProcessor(std::move(fp));
-
     SkMatrix inverse;
     if (!viewMatrix.invert(&inverse)) {
         return false;
     }
 
-    renderTargetContext->fillRectWithLocalMatrix(clip, *grp, GrAA::kNo, SkMatrix::I(), rect,
-                                                 inverse);
+    paint.addCoverageFragmentProcessor(std::move(fp));
+    renderTargetContext->fillRectWithLocalMatrix(clip, std::move(paint), GrAA::kNo, SkMatrix::I(),
+                                                 rect, inverse);
     return true;
 }
 
@@ -1132,10 +1130,10 @@
             return nullptr;
         }
 
-        GrPaint grPaint;
+        GrPaint paint;
 
         rtc->clear(nullptr, 0x0, true);
-        rtc->drawRRect(GrNoClip(), grPaint, GrAA::kYes, SkMatrix::I(), rrectToDraw,
+        rtc->drawRRect(GrNoClip(), std::move(paint), GrAA::kYes, SkMatrix::I(), rrectToDraw,
                        GrStyle::SimpleFill());
 
         sk_sp<GrTexture> srcTexture(rtc->asTexture());
@@ -1342,7 +1340,7 @@
 
 bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrContext* context,
                                                     GrRenderTargetContext* renderTargetContext,
-                                                    GrPaint* grp,
+                                                    GrPaint&& paint,
                                                     const GrClip& clip,
                                                     const SkMatrix& viewMatrix,
                                                     const SkStrokeRec& strokeRec,
@@ -1381,13 +1379,12 @@
             return false;
         }
 
-        GrPaint newPaint(*grp);
-        newPaint.addCoverageFragmentProcessor(std::move(fp));
+        paint.addCoverageFragmentProcessor(std::move(fp));
 
         SkRect srcProxyRect = srcRRect.rect();
         srcProxyRect.outset(3.0f*fSigma, 3.0f*fSigma);
 
-        renderTargetContext->drawRect(clip, newPaint, GrAA::kNo, viewMatrix, srcProxyRect);
+        renderTargetContext->drawRect(clip, std::move(paint), GrAA::kNo, viewMatrix, srcProxyRect);
         return true;
     }
 
@@ -1397,9 +1394,6 @@
         return false;
     }
 
-    GrPaint newPaint(*grp);
-    newPaint.addCoverageFragmentProcessor(std::move(fp));
-
     if (!this->ignoreXform()) {
         SkRect srcProxyRect = srcRRect.rect();
         srcProxyRect.outset(3.0f*fSigma, 3.0f*fSigma);
@@ -1431,8 +1425,10 @@
             numIndices = 6;
         }
 
-        renderTargetContext->drawVertices(clip, newPaint, viewMatrix, kTriangles_GrPrimitiveType,
-                                          numPoints, points, nullptr, nullptr, indices, numIndices);
+        paint.addCoverageFragmentProcessor(std::move(fp));
+        renderTargetContext->drawVertices(clip, std::move(paint), viewMatrix,
+                                          kTriangles_GrPrimitiveType, numPoints, points, nullptr,
+                                          nullptr, indices, numIndices);
 
     } else {
         SkMatrix inverse;
@@ -1444,9 +1440,9 @@
         SkRect proxyRect = devRRect.rect();
         proxyRect.outset(extra, extra);
 
-
-        renderTargetContext->fillRectWithLocalMatrix(clip, newPaint, GrAA::kNo, SkMatrix::I(),
-                                                     proxyRect, inverse);
+        paint.addCoverageFragmentProcessor(std::move(fp));
+        renderTargetContext->fillRectWithLocalMatrix(clip, std::move(paint), GrAA::kNo,
+                                                     SkMatrix::I(), proxyRect, inverse);
     }
 
     return true;
@@ -1543,7 +1539,7 @@
             paint.setCoverageSetOpXPFactory(SkRegion::kReplace_Op);
         }
 
-        renderTargetContext->drawRect(GrNoClip(), paint, GrAA::kNo, SkMatrix::I(),
+        renderTargetContext->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(),
                                       SkRect::Make(clipRect));
     }
 
diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp
index bac1b1c..04b9b4f 100644
--- a/src/effects/SkDisplacementMapEffect.cpp
+++ b/src/effects/SkDisplacementMapEffect.cpp
@@ -366,7 +366,7 @@
         }
         paint.setGammaCorrect(renderTargetContext->isGammaCorrect());
 
-        renderTargetContext->drawRect(GrNoClip(), paint, GrAA::kNo, matrix,
+        renderTargetContext->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, matrix,
                                       SkRect::Make(colorBounds));
 
         offset->fX = bounds.left();
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
index 97d5930..5ea8c33 100644
--- a/src/effects/SkLightingImageFilter.cpp
+++ b/src/effects/SkLightingImageFilter.cpp
@@ -400,7 +400,8 @@
                                                               boundaryMode));
     paint.addColorFragmentProcessor(std::move(fp));
     paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
-    renderTargetContext->fillRectToRect(clip, paint, GrAA::kNo, SkMatrix::I(), dstRect, srcRect);
+    renderTargetContext->fillRectToRect(clip, std::move(paint), GrAA::kNo, SkMatrix::I(), dstRect,
+                                        srcRect);
 }
 
 sk_sp<SkSpecialImage> SkLightingImageFilterInternal::filterImageGPU(
diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp
index 8b5cbaa..6e2a805 100644
--- a/src/effects/SkMorphologyImageFilter.cpp
+++ b/src/effects/SkMorphologyImageFilter.cpp
@@ -407,9 +407,8 @@
     paint.addColorFragmentProcessor(GrMorphologyEffect::Make(tex, direction, radius, morphType,
                                                              bounds));
     paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
-    renderTargetContext->fillRectToRect(clip, paint, GrAA::kNo,
-                                        SkMatrix::I(), SkRect::Make(dstRect),
-                                        SkRect::Make(srcRect));
+    renderTargetContext->fillRectToRect(clip, std::move(paint), GrAA::kNo, SkMatrix::I(),
+                                        SkRect::Make(dstRect), SkRect::Make(srcRect));
 }
 
 static void apply_morphology_rect_no_bounds(GrTextureProvider* provider,
@@ -429,7 +428,7 @@
     }
     paint.addColorFragmentProcessor(GrMorphologyEffect::Make(tex, direction, radius, morphType));
     paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
-    renderTargetContext->fillRectToRect(clip, paint, GrAA::kNo, SkMatrix::I(),
+    renderTargetContext->fillRectToRect(clip, std::move(paint), GrAA::kNo, SkMatrix::I(),
                                         SkRect::Make(dstRect), SkRect::Make(srcRect));
 }
 
diff --git a/src/effects/SkShadowMaskFilter.cpp b/src/effects/SkShadowMaskFilter.cpp
index 38f2591..f1012f5 100755
--- a/src/effects/SkShadowMaskFilter.cpp
+++ b/src/effects/SkShadowMaskFilter.cpp
@@ -42,14 +42,14 @@
                           SkRect* maskRect) const override;
     bool directFilterMaskGPU(GrTextureProvider* texProvider,
                              GrRenderTargetContext* drawContext,
-                             GrPaint* grp,
+                             GrPaint&&,
                              const GrClip&,
                              const SkMatrix& viewMatrix,
                              const SkStrokeRec& strokeRec,
                              const SkPath& path) const override;
     bool directFilterRRectMaskGPU(GrContext*,
                                   GrRenderTargetContext* drawContext,
-                                  GrPaint* grp,
+                                  GrPaint&&,
                                   const GrClip&,
                                   const SkMatrix& viewMatrix,
                                   const SkStrokeRec& strokeRec,
@@ -166,7 +166,7 @@
 
 bool SkShadowMaskFilterImpl::directFilterMaskGPU(GrTextureProvider* texProvider,
                                                  GrRenderTargetContext* drawContext,
-                                                 GrPaint* grp,
+                                                 GrPaint&& paint,
                                                  const GrClip& clip,
                                                  const SkMatrix& viewMatrix,
                                                  const SkStrokeRec& strokeRec,
@@ -179,12 +179,12 @@
     // have our own GeometryProc.
     if (path.isOval(nullptr) && path.getBounds().width() == path.getBounds().height()) {
         SkRRect rrect = SkRRect::MakeOval(path.getBounds());
-        return this->directFilterRRectMaskGPU(nullptr, drawContext, grp, clip, SkMatrix::I(),
-                                              strokeRec, rrect, rrect);
+        return this->directFilterRRectMaskGPU(nullptr, drawContext, std::move(paint), clip,
+                                              SkMatrix::I(), strokeRec, rrect, rrect);
     } else if (path.isRect(nullptr)) {
         SkRRect rrect = SkRRect::MakeRect(path.getBounds());
-        return this->directFilterRRectMaskGPU(nullptr, drawContext, grp, clip, SkMatrix::I(),
-                                              strokeRec, rrect, rrect);
+        return this->directFilterRRectMaskGPU(nullptr, drawContext, std::move(paint), clip,
+                                              SkMatrix::I(), strokeRec, rrect, rrect);
     }
 
     // TODO
@@ -193,7 +193,7 @@
 
 bool SkShadowMaskFilterImpl::directFilterRRectMaskGPU(GrContext*,
                                                       GrRenderTargetContext* renderTargetContext,
-                                                      GrPaint* grp,
+                                                      GrPaint&& paint,
                                                       const GrClip& clip,
                                                       const SkMatrix& viewMatrix,
                                                       const SkStrokeRec& strokeRec,
@@ -252,14 +252,14 @@
 
         const SkScalar devSpaceAmbientRadius = srcSpaceAmbientRadius * scaleFactor;
 
-        GrPaint newPaint(*grp);
+        GrPaint newPaint(paint);
         GrColor4f color = newPaint.getColor4f();
         color.fRGBA[3] *= fAmbientAlpha;
         newPaint.setColor4f(color);
         SkStrokeRec ambientStrokeRec(SkStrokeRec::kHairline_InitStyle);
         ambientStrokeRec.setStrokeStyle(srcSpaceAmbientRadius, false);
 
-        renderTargetContext->drawShadowRRect(clip, newPaint, viewMatrix, ambientRRect,
+        renderTargetContext->drawShadowRRect(clip, std::move(newPaint), viewMatrix, ambientRRect,
                                              devSpaceAmbientRadius,
                                              GrStyle(ambientStrokeRec, nullptr));
     }
@@ -310,11 +310,10 @@
         SkScalar filledArea = (spotShadowRRect.height() + srcSpaceSpotRadius) *
                               (spotShadowRRect.width() + srcSpaceSpotRadius);
 
-        GrPaint newPaint(*grp);
-        GrColor4f color = newPaint.getColor4f();
+        GrColor4f color = paint.getColor4f();
         color.fRGBA[3] *= fSpotAlpha;
-        newPaint.setColor4f(color);
-        
+        paint.setColor4f(color);
+
         SkStrokeRec spotStrokeRec(SkStrokeRec::kFill_InitStyle);
         // If the area of the stroked geometry is larger than the fill geometry,
         // or if the caster is transparent, just fill it.
@@ -337,9 +336,8 @@
 
         spotShadowRRect.offset(spotOffset.fX, spotOffset.fY);
 
-        renderTargetContext->drawShadowRRect(clip, newPaint, viewMatrix, spotShadowRRect,
-                                             devSpaceSpotRadius,
-                                             GrStyle(spotStrokeRec, nullptr));
+        renderTargetContext->drawShadowRRect(clip, std::move(paint), viewMatrix, spotShadowRRect,
+                                             devSpaceSpotRadius, GrStyle(spotStrokeRec, nullptr));
     }
 
     return true;
diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp
index e1627f0..7038db2 100644
--- a/src/effects/SkXfermodeImageFilter.cpp
+++ b/src/effects/SkXfermodeImageFilter.cpp
@@ -305,7 +305,8 @@
 
     SkMatrix matrix;
     matrix.setTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top()));
-    renderTargetContext->drawRect(GrNoClip(), paint, GrAA::kNo, matrix, SkRect::Make(bounds));
+    renderTargetContext->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, matrix,
+                                  SkRect::Make(bounds));
 
     return SkSpecialImage::MakeDeferredFromGpu(context,
                                                SkIRect::MakeWH(bounds.width(), bounds.height()),
diff --git a/src/gpu/GrBlurUtils.cpp b/src/gpu/GrBlurUtils.cpp
index 2a3c0a8..23a3c6c 100644
--- a/src/gpu/GrBlurUtils.cpp
+++ b/src/gpu/GrBlurUtils.cpp
@@ -34,27 +34,26 @@
                       const GrClip& clip,
                       const SkMatrix& viewMatrix,
                       const SkIRect& maskRect,
-                      GrPaint* grp,
+                      GrPaint&& paint,
                       sk_sp<GrTextureProxy> mask) {
-
     // TODO: defer this instantiation
     GrTexture* maskTex = mask->instantiate(textureProvider);
     if (!maskTex) {
         return false;
     }
+    SkMatrix inverse;
+    if (!viewMatrix.invert(&inverse)) {
+        return false;
+    }
 
     SkMatrix matrix;
     matrix.setTranslate(-SkIntToScalar(maskRect.fLeft), -SkIntToScalar(maskRect.fTop));
     // TODO: this divide relies on the instantiated texture's size!
     matrix.postIDiv(maskTex->width(), maskTex->height());
     matrix.preConcat(viewMatrix);
-    grp->addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(maskTex, nullptr, matrix));
+    paint.addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(maskTex, nullptr, matrix));
 
-    SkMatrix inverse;
-    if (!viewMatrix.invert(&inverse)) {
-        return false;
-    }
-    renderTargetContext->fillRectWithLocalMatrix(clip, *grp, GrAA::kNo, SkMatrix::I(),
+    renderTargetContext->fillRectWithLocalMatrix(clip, std::move(paint), GrAA::kNo, SkMatrix::I(),
                                                  SkRect::Make(maskRect), inverse);
     return true;
 }
@@ -66,7 +65,7 @@
                                      const SkPath& devPath,
                                      const SkMaskFilter* filter,
                                      const SkIRect& clipBounds,
-                                     GrPaint* grp,
+                                     GrPaint&& paint,
                                      SkStrokeRec::InitStyle fillOrHairline) {
     SkMask  srcM, dstM;
     if (!SkDraw::DrawToMask(devPath, &clipBounds, filter, &viewMatrix, &srcM,
@@ -109,8 +108,8 @@
     texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
                          dstM.fImage, dstM.fRowBytes);
 
-    return draw_mask(renderTargetContext, context->textureProvider(),
-                     clipData, viewMatrix, dstM.fBounds, grp, sk_ref_sp(proxy->asTextureProxy()));
+    return draw_mask(renderTargetContext, context->textureProvider(), clipData, viewMatrix,
+                     dstM.fBounds, std::move(paint), sk_ref_sp(proxy->asTextureProxy()));
 }
 
 // Create a mask of 'devPath' and place the result in 'mask'.
@@ -134,25 +133,26 @@
 
     rtContext->priv().absClear(nullptr, 0x0);
 
-    GrPaint tempPaint;
-    tempPaint.setCoverageSetOpXPFactory(SkRegion::kReplace_Op);
+    GrPaint maskPaint;
+    maskPaint.setCoverageSetOpXPFactory(SkRegion::kReplace_Op);
 
     // setup new clip
     const SkIRect clipRect = SkIRect::MakeWH(maskRect.width(), maskRect.height());
     GrFixedClip clip(clipRect);
 
     // Draw the mask into maskTexture with the path's integerized top-left at
-    // the origin using tempPaint.
+    // the origin using maskPaint.
     SkMatrix translate;
     translate.setTranslate(-SkIntToScalar(maskRect.fLeft), -SkIntToScalar(maskRect.fTop));
-    rtContext->drawPath(clip, tempPaint, aa, translate, devPath, GrStyle(fillOrHairline));
+    rtContext->drawPath(clip, std::move(maskPaint), aa, translate, devPath,
+                        GrStyle(fillOrHairline));
     return sk_ref_sp(rtContext->asDeferredTexture());
 }
 
 static void draw_path_with_mask_filter(GrContext* context,
                                        GrRenderTargetContext* renderTargetContext,
                                        const GrClip& clip,
-                                       GrPaint* paint,
+                                       GrPaint&& paint,
                                        GrAA aa,
                                        const SkMatrix& viewMatrix,
                                        const SkMaskFilter* maskFilter,
@@ -217,7 +217,7 @@
 
         if (maskFilter->directFilterMaskGPU(context->textureProvider(),
                                             renderTargetContext,
-                                            paint,
+                                            std::move(paint),
                                             clip,
                                             viewMatrix,
                                             SkStrokeRec(fillOrHairline),
@@ -239,8 +239,8 @@
                                                                        viewMatrix,
                                                                        finalIRect);
             if (filtered) {
-                if (draw_mask(renderTargetContext, context->textureProvider(),
-                              clip, viewMatrix, finalIRect, paint, std::move(filtered))) {
+                if (draw_mask(renderTargetContext, context->textureProvider(), clip, viewMatrix,
+                              finalIRect, std::move(paint), std::move(filtered))) {
                     // This path is completely drawn
                     return;
                 }
@@ -248,22 +248,22 @@
         }
     }
 
-    sw_draw_with_mask_filter(context, renderTargetContext, clip, viewMatrix, *path,
-                             maskFilter, clipBounds, paint, fillOrHairline);
+    sw_draw_with_mask_filter(context, renderTargetContext, clip, viewMatrix, *path, maskFilter,
+                             clipBounds, std::move(paint), fillOrHairline);
 }
 
 void GrBlurUtils::drawPathWithMaskFilter(GrContext* context,
                                          GrRenderTargetContext* renderTargetContext,
                                          const GrClip& clip,
                                          const SkPath& path,
-                                         GrPaint* paint,
+                                         GrPaint&& paint,
                                          GrAA aa,
                                          const SkMatrix& viewMatrix,
                                          const SkMaskFilter* mf,
                                          const GrStyle& style,
                                          bool pathIsMutable) {
-    draw_path_with_mask_filter(context, renderTargetContext, clip, paint, aa, viewMatrix, mf,
-                               style, &path, pathIsMutable);
+    draw_path_with_mask_filter(context, renderTargetContext, clip, std::move(paint), aa, viewMatrix,
+                               mf, style, &path, pathIsMutable);
 }
 
 void GrBlurUtils::drawPathWithMaskFilter(GrContext* context,
@@ -310,10 +310,9 @@
     SkMaskFilter* mf = paint.getMaskFilter();
     if (mf && !mf->asFragmentProcessor(nullptr, nullptr, viewMatrix)) {
         // The MaskFilter wasn't already handled in SkPaintToGrPaint
-        draw_path_with_mask_filter(context, renderTargetContext, clip, &grPaint, aa, viewMatrix,
-                                   mf, style,
-                                   path, pathIsMutable);
+        draw_path_with_mask_filter(context, renderTargetContext, clip, std::move(grPaint), aa,
+                                   viewMatrix, mf, style, path, pathIsMutable);
     } else {
-        renderTargetContext->drawPath(clip, grPaint, aa, viewMatrix, *path, style);
+        renderTargetContext->drawPath(clip, std::move(grPaint), aa, viewMatrix, *path, style);
     }
 }
diff --git a/src/gpu/GrBlurUtils.h b/src/gpu/GrBlurUtils.h
index be0d2fb..bf6d638 100644
--- a/src/gpu/GrBlurUtils.h
+++ b/src/gpu/GrBlurUtils.h
@@ -49,13 +49,12 @@
                                 GrRenderTargetContext*,
                                 const GrClip&,
                                 const SkPath& path,
-                                GrPaint*,
+                                GrPaint&&,
                                 GrAA,
                                 const SkMatrix& viewMatrix,
                                 const SkMaskFilter*,
                                 const GrStyle&,
                                 bool pathIsMutable);
-
 };
 
 #endif
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index fd8aba0..10546ba 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -367,7 +367,8 @@
             paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
             paint.setAllowSRGBInputs(true);
             SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
-            renderTargetContext->drawRect(GrNoClip(), paint, GrAA::kNo, matrix, rect, nullptr);
+            renderTargetContext->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, matrix, rect,
+                                          nullptr);
 
             if (kFlushWrites_PixelOp & pixelOpsFlags) {
                 this->flushSurfaceWrites(surface);
@@ -488,7 +489,8 @@
                 paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
                 paint.setAllowSRGBInputs(true);
                 SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
-                tempRTC->drawRect(GrNoClip(), paint, GrAA::kNo, SkMatrix::I(), rect, nullptr);
+                tempRTC->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(), rect,
+                                  nullptr);
                 surfaceToRead.reset(tempRTC->asTexture().release());
                 left = 0;
                 top = 0;
diff --git a/src/gpu/GrPaint.cpp b/src/gpu/GrPaint.cpp
index 8d9347b..122d87e 100644
--- a/src/gpu/GrPaint.cpp
+++ b/src/gpu/GrPaint.cpp
@@ -12,13 +12,6 @@
 #include "effects/GrPorterDuffXferProcessor.h"
 #include "effects/GrSimpleTextureEffect.h"
 
-GrPaint::GrPaint()
-        : fXPFactory(nullptr)
-        , fDisableOutputConversionToSRGB(false)
-        , fAllowSRGBInputs(false)
-        , fUsesDistanceVectorField(false)
-        , fColor(GrColor4f::OpaqueWhite()) {}
-
 void GrPaint::setCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage) {
     fXPFactory = GrCoverageSetOpXPFactory::Get(regionOp, invertCoverage);
 }
diff --git a/src/gpu/GrPathRenderer.h b/src/gpu/GrPathRenderer.h
index 8548087..f1164a9 100644
--- a/src/gpu/GrPathRenderer.h
+++ b/src/gpu/GrPathRenderer.h
@@ -124,20 +124,18 @@
      * fGammaCorrect          true if gamma-correct rendering is to be used.
      */
     struct DrawPathArgs {
-        GrResourceProvider*         fResourceProvider;
-        const GrPaint*              fPaint;
-        const GrUserStencilSettings*fUserStencilSettings;
-
-        GrRenderTargetContext*      fRenderTargetContext;
-        const GrClip*               fClip;
-        const SkMatrix*             fViewMatrix;
-        const GrShape*              fShape;
-        GrAAType                    fAAType;
-        bool                        fGammaCorrect;
+        GrResourceProvider*          fResourceProvider;
+        GrPaint&&                    fPaint;
+        const GrUserStencilSettings* fUserStencilSettings;
+        GrRenderTargetContext*       fRenderTargetContext;
+        const GrClip*                fClip;
+        const SkMatrix*              fViewMatrix;
+        const GrShape*               fShape;
+        GrAAType                     fAAType;
+        bool                         fGammaCorrect;
 #ifdef SK_DEBUG
         void validate() const {
             SkASSERT(fResourceProvider);
-            SkASSERT(fPaint);
             SkASSERT(fUserStencilSettings);
             SkASSERT(fRenderTargetContext);
             SkASSERT(fClip);
@@ -279,15 +277,15 @@
 
         GrPaint paint;
 
-        DrawPathArgs drawArgs;
-        drawArgs.fResourceProvider = args.fResourceProvider;
-        drawArgs.fPaint = &paint;
-        drawArgs.fUserStencilSettings = &kIncrementStencil;
-        drawArgs.fRenderTargetContext = args.fRenderTargetContext;
-        drawArgs.fViewMatrix = args.fViewMatrix;
-        drawArgs.fShape = args.fShape;
-        drawArgs.fAAType = args.fAAType;
-        drawArgs.fGammaCorrect = false;
+        DrawPathArgs drawArgs{args.fResourceProvider,
+                              std::move(paint),
+                              &kIncrementStencil,
+                              args.fRenderTargetContext,
+                              nullptr,  // clip
+                              args.fViewMatrix,
+                              args.fShape,
+                              args.fAAType,
+                              false};
         this->drawPath(drawArgs);
     }
 
diff --git a/src/gpu/GrPathRenderingRenderTargetContext.cpp b/src/gpu/GrPathRenderingRenderTargetContext.cpp
index f2d092a..3319a05 100644
--- a/src/gpu/GrPathRenderingRenderTargetContext.cpp
+++ b/src/gpu/GrPathRenderingRenderTargetContext.cpp
@@ -15,7 +15,7 @@
     SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(this->singleOwner());)
 #define RETURN_IF_ABANDONED        if (this->drawingManager()->wasAbandoned()) { return; }
 
-void GrPathRenderingRenderTargetContext::drawText(const GrClip& clip, const GrPaint& grPaint,
+void GrPathRenderingRenderTargetContext::drawText(const GrClip& clip, GrPaint&& grPaint,
                                                   const SkPaint& skPaint,
                                                   const SkMatrix& viewMatrix, const char text[],
                                                   size_t byteLength, SkScalar x, SkScalar y,
@@ -30,15 +30,15 @@
         fStencilAndCoverTextContext.reset(GrStencilAndCoverTextContext::Create(fallbackContext));
     }
 
-    fStencilAndCoverTextContext->drawText(this->drawingManager()->getContext(), this, clip, grPaint,
-                                          skPaint, viewMatrix, this->surfaceProps(),
-                                          text, byteLength, x, y, clipBounds);
+    fStencilAndCoverTextContext->drawText(this->drawingManager()->getContext(), this, clip,
+                                          std::move(grPaint), skPaint, viewMatrix,
+                                          this->surfaceProps(), text, byteLength, x, y, clipBounds);
 }
 
-void GrPathRenderingRenderTargetContext::drawPosText(const GrClip& clip, const GrPaint& grPaint,
+void GrPathRenderingRenderTargetContext::drawPosText(const GrClip& clip, GrPaint&& grPaint,
                                                      const SkPaint& skPaint,
                                                      const SkMatrix& viewMatrix, const char text[],
-                                                     size_t byteLength,  const SkScalar pos[],
+                                                     size_t byteLength, const SkScalar pos[],
                                                      int scalarsPerPosition, const SkPoint& offset,
                                                      const SkIRect& clipBounds) {
     ASSERT_SINGLE_OWNER
@@ -53,9 +53,9 @@
     }
 
     fStencilAndCoverTextContext->drawPosText(this->drawingManager()->getContext(), this, clip,
-                                             grPaint, skPaint, viewMatrix, this->surfaceProps(),
-                                             text, byteLength, pos, scalarsPerPosition, offset,
-                                             clipBounds);
+                                             std::move(grPaint), skPaint, viewMatrix,
+                                             this->surfaceProps(), text, byteLength, pos,
+                                             scalarsPerPosition, offset, clipBounds);
 }
 
 void GrPathRenderingRenderTargetContext::drawTextBlob(const GrClip& clip, const SkPaint& skPaint,
diff --git a/src/gpu/GrPathRenderingRenderTargetContext.h b/src/gpu/GrPathRenderingRenderTargetContext.h
index 1ad3a0b..0597539 100644
--- a/src/gpu/GrPathRenderingRenderTargetContext.h
+++ b/src/gpu/GrPathRenderingRenderTargetContext.h
@@ -14,13 +14,13 @@
 
 class GrPathRenderingRenderTargetContext : public GrRenderTargetContext {
 public:
-    void drawText(const GrClip&,  const GrPaint&, const SkPaint&,
-                  const SkMatrix& viewMatrix, const char text[], size_t byteLength,
-                  SkScalar x, SkScalar y, const SkIRect& clipBounds) override;
-    void drawPosText(const GrClip&, const GrPaint&, const SkPaint&,
-                     const SkMatrix& viewMatrix, const char text[], size_t byteLength,
-                     const SkScalar pos[], int scalarsPerPosition,
-                     const SkPoint& offset, const SkIRect& clipBounds) override;
+    void drawText(const GrClip&, GrPaint&&, const SkPaint&, const SkMatrix& viewMatrix,
+                  const char text[], size_t byteLength, SkScalar x, SkScalar y,
+                  const SkIRect& clipBounds) override;
+    void drawPosText(const GrClip&, GrPaint&&, const SkPaint&, const SkMatrix& viewMatrix,
+                     const char text[], size_t byteLength, const SkScalar pos[],
+                     int scalarsPerPosition, const SkPoint& offset,
+                     const SkIRect& clipBounds) override;
     void drawTextBlob(const GrClip&, const SkPaint&,
                       const SkMatrix& viewMatrix, const SkTextBlob*,
                       SkScalar x, SkScalar y,
diff --git a/src/gpu/GrPipelineBuilder.cpp b/src/gpu/GrPipelineBuilder.cpp
index 5741471..fc67c33 100644
--- a/src/gpu/GrPipelineBuilder.cpp
+++ b/src/gpu/GrPipelineBuilder.cpp
@@ -15,18 +15,18 @@
 #include "effects/GrPorterDuffXferProcessor.h"
 #include "ops/GrOp.h"
 
-GrPipelineBuilder::GrPipelineBuilder(const GrPaint& paint, GrAAType aaType)
+GrPipelineBuilder::GrPipelineBuilder(GrPaint&& paint, GrAAType aaType)
         : fFlags(0x0)
         , fUserStencilSettings(&GrUserStencilSettings::kUnused)
         , fDrawFace(GrDrawFace::kBoth) {
     SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
 
     for (int i = 0; i < paint.numColorFragmentProcessors(); ++i) {
-        fColorFragmentProcessors.emplace_back(SkRef(paint.getColorFragmentProcessor(i)));
+        fColorFragmentProcessors.emplace_back(paint.fColorFragmentProcessors[i].release());
     }
 
     for (int i = 0; i < paint.numCoverageFragmentProcessors(); ++i) {
-        fCoverageFragmentProcessors.emplace_back(SkRef(paint.getCoverageFragmentProcessor(i)));
+        fCoverageFragmentProcessors.emplace_back(paint.fCoverageFragmentProcessors[i].release());
     }
 
     fXPFactory = paint.getXPFactory();
diff --git a/src/gpu/GrPipelineBuilder.h b/src/gpu/GrPipelineBuilder.h
index 0d039f9..15af681 100644
--- a/src/gpu/GrPipelineBuilder.h
+++ b/src/gpu/GrPipelineBuilder.h
@@ -29,14 +29,13 @@
 
 class GrPipelineBuilder : public SkNoncopyable {
 public:
-//    GrPipelineBuilder();
     /**
      * Initializes the GrPipelineBuilder based on a GrPaint and MSAA availability. Note
      * that GrPipelineBuilder encompasses more than GrPaint. Aspects of GrPipelineBuilder that have
      * no GrPaint equivalents are set to default values with the exception of vertex attribute state
      * which is unmodified by this function and clipping which will be enabled.
      */
-    GrPipelineBuilder(const GrPaint& paint, GrAAType aaType);
+    GrPipelineBuilder(GrPaint&&, GrAAType);
 
     virtual ~GrPipelineBuilder();
 
diff --git a/src/gpu/GrReducedClip.cpp b/src/gpu/GrReducedClip.cpp
index 9f3b225..4dd81c2 100644
--- a/src/gpu/GrReducedClip.cpp
+++ b/src/gpu/GrReducedClip.cpp
@@ -558,19 +558,18 @@
 }
 
 static void draw_element(GrRenderTargetContext* rtc,
-                         const GrClip& clip, // TODO: can this just always be WideOpen?
-                         const GrPaint &paint,
+                         const GrClip& clip,  // TODO: can this just always be WideOpen?
+                         GrPaint&& paint,
                          GrAA aa,
                          const SkMatrix& viewMatrix,
                          const SkClipStack::Element* element) {
-
     // TODO: Draw rrects directly here.
     switch (element->getType()) {
         case Element::kEmpty_Type:
             SkDEBUGFAIL("Should never get here with an empty element.");
             break;
         case Element::kRect_Type:
-            rtc->drawRect(clip, paint, aa, viewMatrix, element->getRect());
+            rtc->drawRect(clip, std::move(paint), aa, viewMatrix, element->getRect());
             break;
         default: {
             SkPath path;
@@ -579,7 +578,7 @@
                 path.toggleInverseFillType();
             }
 
-            rtc->drawPath(clip, paint, aa, viewMatrix, path, GrStyle::SimpleFill());
+            rtc->drawPath(clip, std::move(paint), aa, viewMatrix, path, GrStyle::SimpleFill());
             break;
         }
     }
@@ -645,7 +644,7 @@
             GrPaint paint;
             paint.setCoverageSetOpXPFactory(op, false);
 
-            draw_element(rtc, clip, paint, aa, translate, element);
+            draw_element(rtc, clip, std::move(paint), aa, translate, element);
         }
     }
 
@@ -782,16 +781,15 @@
                         GrPaint paint;
                         paint.setXPFactory(GrDisableColorXPFactory::Get());
 
-                        GrPathRenderer::DrawPathArgs args;
-                        args.fResourceProvider = context->resourceProvider();
-                        args.fPaint = &paint;
-                        args.fUserStencilSettings = &kDrawToStencil;
-                        args.fRenderTargetContext = renderTargetContext;
-                        args.fClip = &stencilClip.fixedClip();
-                        args.fViewMatrix = &viewMatrix;
-                        args.fShape = &shape;
-                        args.fAAType = aaType;
-                        args.fGammaCorrect = false;
+                        GrPathRenderer::DrawPathArgs args{context->resourceProvider(),
+                                                          std::move(paint),
+                                                          &kDrawToStencil,
+                                                          renderTargetContext,
+                                                          &stencilClip.fixedClip(),
+                                                          &viewMatrix,
+                                                          &shape,
+                                                          aaType,
+                                                          false};
                         pr->drawPath(args);
                     } else {
                         GrPathRenderer::StencilPathArgs args;
@@ -818,16 +816,15 @@
                     GrShape shape(clipPath, GrStyle::SimpleFill());
                     GrPaint paint;
                     paint.setXPFactory(GrDisableColorXPFactory::Get());
-                    GrPathRenderer::DrawPathArgs args;
-                    args.fResourceProvider = context->resourceProvider();
-                    args.fPaint = &paint;
-                    args.fUserStencilSettings = *pass;
-                    args.fRenderTargetContext = renderTargetContext;
-                    args.fClip = &stencilClip;
-                    args.fViewMatrix = &viewMatrix;
-                    args.fShape = &shape;
-                    args.fAAType = aaType;
-                    args.fGammaCorrect = false;
+                    GrPathRenderer::DrawPathArgs args{context->resourceProvider(),
+                                                      std::move(paint),
+                                                      *pass,
+                                                      renderTargetContext,
+                                                      &stencilClip,
+                                                      &viewMatrix,
+                                                      &shape,
+                                                      aaType,
+                                                      false};
                     pr->drawPath(args);
                 }
             } else {
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index 5e14f6b..968663c 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -158,37 +158,34 @@
     return this->getOpList()->copySurface(rt.get(), src.get(), srcRect, dstPoint);
 }
 
-void GrRenderTargetContext::drawText(const GrClip& clip, const GrPaint& grPaint,
-                                     const SkPaint& skPaint,
-                                     const SkMatrix& viewMatrix,
-                                     const char text[], size_t byteLength,
-                                     SkScalar x, SkScalar y, const SkIRect& clipBounds) {
+void GrRenderTargetContext::drawText(const GrClip& clip, GrPaint&& grPaint, const SkPaint& skPaint,
+                                     const SkMatrix& viewMatrix, const char text[],
+                                     size_t byteLength, SkScalar x, SkScalar y,
+                                     const SkIRect& clipBounds) {
     ASSERT_SINGLE_OWNER
     RETURN_IF_ABANDONED
     SkDEBUGCODE(this->validate();)
     GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawText");
 
     GrAtlasTextContext* atlasTextContext = fDrawingManager->getAtlasTextContext();
-    atlasTextContext->drawText(fContext, this, clip, grPaint, skPaint, viewMatrix, fSurfaceProps,
-                               text, byteLength, x, y, clipBounds);
+    atlasTextContext->drawText(fContext, this, clip, std::move(grPaint), skPaint, viewMatrix,
+                               fSurfaceProps, text, byteLength, x, y, clipBounds);
 }
 
-void GrRenderTargetContext::drawPosText(const GrClip& clip, const GrPaint& grPaint,
-                                        const SkPaint& skPaint,
-                                        const SkMatrix& viewMatrix,
-                                        const char text[], size_t byteLength,
-                                        const SkScalar pos[], int scalarsPerPosition,
-                                        const SkPoint& offset, const SkIRect& clipBounds) {
+void GrRenderTargetContext::drawPosText(const GrClip& clip, GrPaint&& grPaint,
+                                        const SkPaint& skPaint, const SkMatrix& viewMatrix,
+                                        const char text[], size_t byteLength, const SkScalar pos[],
+                                        int scalarsPerPosition, const SkPoint& offset,
+                                        const SkIRect& clipBounds) {
     ASSERT_SINGLE_OWNER
     RETURN_IF_ABANDONED
     SkDEBUGCODE(this->validate();)
     GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawPosText");
 
     GrAtlasTextContext* atlasTextContext = fDrawingManager->getAtlasTextContext();
-    atlasTextContext->drawPosText(fContext, this, clip, grPaint, skPaint, viewMatrix,
-                                  fSurfaceProps, text, byteLength, pos, scalarsPerPosition,
-                                  offset, clipBounds);
-
+    atlasTextContext->drawPosText(fContext, this, clip, std::move(grPaint), skPaint, viewMatrix,
+                                  fSurfaceProps, text, byteLength, pos, scalarsPerPosition, offset,
+                                  clipBounds);
 }
 
 void GrRenderTargetContext::drawTextBlob(const GrClip& clip, const SkPaint& skPaint,
@@ -272,9 +269,9 @@
 
         // We don't call drawRect() here to avoid the cropping to the, possibly smaller,
         // RenderTargetProxy bounds
-        fRenderTargetContext->drawNonAAFilledRect(GrNoClip(), paint, SkMatrix::I(),
-                                                  SkRect::Make(rtRect),
-                                                  nullptr, nullptr, nullptr, GrAAType::kNone);
+        fRenderTargetContext->drawNonAAFilledRect(GrNoClip(), std::move(paint), SkMatrix::I(),
+                                                  SkRect::Make(rtRect), nullptr, nullptr, nullptr,
+                                                  GrAAType::kNone);
 
     } else {
         if (!fRenderTargetContext->accessRenderTarget()) {
@@ -331,7 +328,7 @@
         paint.setColor4f(GrColor4f::FromGrColor(color));
         paint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
 
-        this->drawRect(clip, paint, GrAA::kNo, SkMatrix::I(), SkRect::Make(clearRect));
+        this->drawRect(clip, std::move(paint), GrAA::kNo, SkMatrix::I(), SkRect::Make(clearRect));
     } else if (isFull) {
         if (this->accessRenderTarget()) {
             this->getOpList()->fullClear(this, color);
@@ -349,7 +346,7 @@
 }
 
 void GrRenderTargetContext::drawPaint(const GrClip& clip,
-                                      const GrPaint& paint,
+                                      GrPaint&& paint,
                                       const SkMatrix& viewMatrix) {
     ASSERT_SINGLE_OWNER
     RETURN_IF_ABANDONED
@@ -369,7 +366,8 @@
     // because they may depend on having correct local coords and this path draws in device space
     // without a local matrix.
     if (!paint.numTotalFragmentProcessors() && clip.isRRect(r, &rrect, &aa) && !rrect.isRect()) {
-        this->drawRRect(GrNoClip(), paint, aa, SkMatrix::I(), rrect, GrStyle::SimpleFill());
+        this->drawRRect(GrNoClip(), std::move(paint), aa, SkMatrix::I(), rrect,
+                        GrStyle::SimpleFill());
         return;
     }
 
@@ -384,7 +382,7 @@
             SkDebugf("Could not invert matrix\n");
             return;
         }
-        this->drawRect(clip, paint, GrAA::kNo, viewMatrix, r);
+        this->drawRect(clip, std::move(paint), GrAA::kNo, viewMatrix, r);
     } else {
         SkMatrix localMatrix;
         if (!viewMatrix.invert(&localMatrix)) {
@@ -394,7 +392,7 @@
 
         AutoCheckFlush acf(fDrawingManager);
 
-        this->drawNonAAFilledRect(clip, paint, SkMatrix::I(), r, nullptr, &localMatrix,
+        this->drawNonAAFilledRect(clip, std::move(paint), SkMatrix::I(), r, nullptr, &localMatrix,
                                   nullptr, GrAAType::kNone);
     }
 }
@@ -454,7 +452,7 @@
 }
 
 bool GrRenderTargetContext::drawFilledRect(const GrClip& clip,
-                                           const GrPaint& paint,
+                                           GrPaint&& paint,
                                            GrAA aa,
                                            const SkMatrix& viewMatrix,
                                            const SkRect& rect,
@@ -472,7 +470,7 @@
         op = ir->recordRect(croppedRect, viewMatrix, paint.getColor(), aa, fInstancedPipelineInfo,
                             &aaType);
         if (op) {
-            GrPipelineBuilder pipelineBuilder(paint, aaType);
+            GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
             if (ss) {
                 pipelineBuilder.setUserStencil(ss);
             }
@@ -489,7 +487,7 @@
 
             op = GrRectOpFactory::MakeAAFill(paint, viewMatrix, rect, croppedRect, devBoundRect);
             if (op) {
-                GrPipelineBuilder pipelineBuilder(paint, aaType);
+                GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
                 if (ss) {
                     pipelineBuilder.setUserStencil(ss);
                 }
@@ -498,8 +496,8 @@
             }
         }
     } else {
-        this->drawNonAAFilledRect(clip, paint, viewMatrix, croppedRect, nullptr, nullptr, ss,
-                                  aaType);
+        this->drawNonAAFilledRect(clip, std::move(paint), viewMatrix, croppedRect, nullptr, nullptr,
+                                  ss, aaType);
         return true;
     }
 
@@ -507,7 +505,7 @@
 }
 
 void GrRenderTargetContext::drawRect(const GrClip& clip,
-                                     const GrPaint& paint,
+                                     GrPaint&& paint,
                                      GrAA aa,
                                      const SkMatrix& viewMatrix,
                                      const SkRect& rect,
@@ -555,7 +553,7 @@
             }
         }
 
-        if (this->drawFilledRect(clip, paint, aa, viewMatrix, rect, nullptr)) {
+        if (this->drawFilledRect(clip, std::move(paint), aa, viewMatrix, rect, nullptr)) {
             return;
         }
     } else if (stroke.getStyle() == SkStrokeRec::kStroke_Style ||
@@ -566,25 +564,26 @@
             // TODO: Move these stroke->fill fallbacks to GrShape?
             switch (stroke.getJoin()) {
                 case SkPaint::kMiter_Join:
-                    this->drawRect(clip, paint, aa, viewMatrix,
-                                   {rect.fLeft - r, rect.fTop - r,
-                                    rect.fRight + r, rect.fBottom + r},
-                                   &GrStyle::SimpleFill());
+                    this->drawRect(
+                            clip, std::move(paint), aa, viewMatrix,
+                            {rect.fLeft - r, rect.fTop - r, rect.fRight + r, rect.fBottom + r},
+                            &GrStyle::SimpleFill());
                     return;
                 case SkPaint::kRound_Join:
                     // Raster draws nothing when both dimensions are empty.
                     if (rect.width() || rect.height()){
                         SkRRect rrect = SkRRect::MakeRectXY(rect.makeOutset(r, r), r, r);
-                        this->drawRRect(clip, paint, aa, viewMatrix, rrect, GrStyle::SimpleFill());
+                        this->drawRRect(clip, std::move(paint), aa, viewMatrix, rrect,
+                                        GrStyle::SimpleFill());
                         return;
                     }
                 case SkPaint::kBevel_Join:
                     if (!rect.width()) {
-                        this->drawRect(clip, paint, aa, viewMatrix,
+                        this->drawRect(clip, std::move(paint), aa, viewMatrix,
                                        {rect.fLeft - r, rect.fTop, rect.fRight + r, rect.fBottom},
                                        &GrStyle::SimpleFill());
                     } else {
-                        this->drawRect(clip, paint, aa, viewMatrix,
+                        this->drawRect(clip, std::move(paint), aa, viewMatrix,
                                        {rect.fLeft, rect.fTop - r, rect.fRight, rect.fBottom + r},
                                        &GrStyle::SimpleFill());
                     }
@@ -613,7 +612,7 @@
         }
 
         if (op) {
-            GrPipelineBuilder pipelineBuilder(paint, aaType);
+            GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
 
             if (snapToPixelCenters) {
                 pipelineBuilder.setState(GrPipelineBuilder::kSnapVerticesToPixelCenters_Flag,
@@ -628,7 +627,7 @@
     SkPath path;
     path.setIsVolatile(true);
     path.addRect(rect);
-    this->internalDrawPath(clip, paint, aa, viewMatrix, path, *style);
+    this->internalDrawPath(clip, std::move(paint), aa, viewMatrix, path, *style);
 }
 
 int GrRenderTargetContextPriv::maxWindowRectangles() const {
@@ -677,8 +676,8 @@
     GrPaint paint;
     paint.setXPFactory(GrDisableColorXPFactory::Get());
 
-    fRenderTargetContext->drawNonAAFilledRect(clip, paint, viewMatrix, rect, nullptr, nullptr, ss,
-                                              aaType);
+    fRenderTargetContext->drawNonAAFilledRect(clip, std::move(paint), viewMatrix, rect, nullptr,
+                                              nullptr, ss, aaType);
 }
 
 bool GrRenderTargetContextPriv::drawAndStencilRect(const GrClip& clip,
@@ -699,7 +698,7 @@
     GrPaint paint;
     paint.setCoverageSetOpXPFactory(op, invert);
 
-    if (fRenderTargetContext->drawFilledRect(clip, paint, aa, viewMatrix, rect, ss)) {
+    if (fRenderTargetContext->drawFilledRect(clip, std::move(paint), aa, viewMatrix, rect, ss)) {
         return true;
     }
     SkPath path;
@@ -709,7 +708,7 @@
 }
 
 void GrRenderTargetContext::fillRectToRect(const GrClip& clip,
-                                           const GrPaint& paint,
+                                           GrPaint&& paint,
                                            GrAA aa,
                                            const SkMatrix& viewMatrix,
                                            const SkRect& rectToDraw,
@@ -735,7 +734,7 @@
                                                     croppedLocalRect, aa, fInstancedPipelineInfo,
                                                     &aaType));
         if (op) {
-            GrPipelineBuilder pipelineBuilder(paint, aaType);
+            GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
             this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
             return;
         }
@@ -743,15 +742,15 @@
 
     aaType = this->decideAAType(aa);
     if (GrAAType::kCoverage != aaType) {
-        this->drawNonAAFilledRect(clip, paint, viewMatrix, croppedRect, &croppedLocalRect, nullptr,
-                                  nullptr, aaType);
+        this->drawNonAAFilledRect(clip, std::move(paint), viewMatrix, croppedRect,
+                                  &croppedLocalRect, nullptr, nullptr, aaType);
         return;
     }
 
     if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
         std::unique_ptr<GrDrawOp> op = GrAAFillRectOp::MakeWithLocalRect(
                 paint.getColor(), viewMatrix, croppedRect, croppedLocalRect);
-        GrPipelineBuilder pipelineBuilder(paint, aaType);
+        GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
         this->addDrawOp(pipelineBuilder, clip, std::move(op));
         return;
     }
@@ -766,11 +765,11 @@
     SkPath path;
     path.setIsVolatile(true);
     path.addRect(localRect);
-    this->internalDrawPath(clip, paint, aa, viewAndUnLocalMatrix, path, GrStyle());
+    this->internalDrawPath(clip, std::move(paint), aa, viewAndUnLocalMatrix, path, GrStyle());
 }
 
 void GrRenderTargetContext::fillRectWithLocalMatrix(const GrClip& clip,
-                                                    const GrPaint& paint,
+                                                    GrPaint&& paint,
                                                     GrAA aa,
                                                     const SkMatrix& viewMatrix,
                                                     const SkRect& rectToDraw,
@@ -794,7 +793,7 @@
                                                     localMatrix, aa, fInstancedPipelineInfo,
                                                     &aaType));
         if (op) {
-            GrPipelineBuilder pipelineBuilder(paint, aaType);
+            GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
             this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
             return;
         }
@@ -802,15 +801,15 @@
 
     aaType = this->decideAAType(aa);
     if (GrAAType::kCoverage != aaType) {
-        this->drawNonAAFilledRect(clip, paint, viewMatrix, croppedRect, nullptr, &localMatrix,
-                                  nullptr, aaType);
+        this->drawNonAAFilledRect(clip, std::move(paint), viewMatrix, croppedRect, nullptr,
+                                  &localMatrix, nullptr, aaType);
         return;
     }
 
     if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
         std::unique_ptr<GrDrawOp> op =
                 GrAAFillRectOp::Make(paint.getColor(), viewMatrix, localMatrix, croppedRect);
-        GrPipelineBuilder pipelineBuilder(paint, aaType);
+        GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
         this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
         return;
     }
@@ -826,11 +825,11 @@
     path.setIsVolatile(true);
     path.addRect(rectToDraw);
     path.transform(localMatrix);
-    this->internalDrawPath(clip, paint, aa, viewAndUnLocalMatrix, path, GrStyle());
+    this->internalDrawPath(clip, std::move(paint), aa, viewAndUnLocalMatrix, path, GrStyle());
 }
 
 void GrRenderTargetContext::drawVertices(const GrClip& clip,
-                                         const GrPaint& paint,
+                                         GrPaint&& paint,
                                          const SkMatrix& viewMatrix,
                                          GrPrimitiveType primitiveType,
                                          int vertexCount,
@@ -859,14 +858,14 @@
             GrDrawVerticesOp::Make(paint.getColor(), primitiveType, viewMatrix, positions,
                                    vertexCount, indices, indexCount, colors, texCoords, bounds);
 
-    GrPipelineBuilder pipelineBuilder(paint, GrAAType::kNone);
+    GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
     this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 void GrRenderTargetContext::drawAtlas(const GrClip& clip,
-                                      const GrPaint& paint,
+                                      GrPaint&& paint,
                                       const SkMatrix& viewMatrix,
                                       int spriteCount,
                                       const SkRSXform xform[],
@@ -881,14 +880,14 @@
 
     std::unique_ptr<GrDrawOp> op =
             GrDrawAtlasOp::Make(paint.getColor(), viewMatrix, spriteCount, xform, texRect, colors);
-    GrPipelineBuilder pipelineBuilder(paint, GrAAType::kNone);
+    GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
     this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 void GrRenderTargetContext::drawRRect(const GrClip& origClip,
-                                      const GrPaint& paint,
+                                      GrPaint&& paint,
                                       GrAA aa,
                                       const SkMatrix& viewMatrix,
                                       const SkRRect& rrect,
@@ -926,7 +925,7 @@
         std::unique_ptr<GrDrawOp> op(ir->recordRRect(rrect, viewMatrix, paint.getColor(), aa,
                                                      fInstancedPipelineInfo, &aaType));
         if (op) {
-            GrPipelineBuilder pipelineBuilder(paint, aaType);
+            GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
             this->getOpList()->addDrawOp(pipelineBuilder, this, *clip, std::move(op));
             return;
         }
@@ -942,7 +941,7 @@
                                                                     stroke,
                                                                     shaderCaps);
         if (op) {
-            GrPipelineBuilder pipelineBuilder(paint, aaType);
+            GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
             this->getOpList()->addDrawOp(pipelineBuilder, this, *clip, std::move(op));
             return;
         }
@@ -951,13 +950,13 @@
     SkPath path;
     path.setIsVolatile(true);
     path.addRRect(rrect);
-    this->internalDrawPath(*clip, paint, aa, viewMatrix, path, style);
+    this->internalDrawPath(*clip, std::move(paint), aa, viewMatrix, path, style);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 void GrRenderTargetContext::drawShadowRRect(const GrClip& clip,
-                                            const GrPaint& paint,
+                                            GrPaint&& paint,
                                             const SkMatrix& viewMatrix,
                                             const SkRRect& rrect,
                                             SkScalar blurRadius,
@@ -980,7 +979,7 @@
     std::unique_ptr<GrDrawOp> op = GrShadowRRectOp::Make(paint.getColor(), viewMatrix, rrect,
                                                          blurRadius, stroke, shaderCaps);
     if (op) {
-        GrPipelineBuilder pipelineBuilder(paint, GrAAType::kNone);
+        GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
         this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
         return;
     }
@@ -989,7 +988,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 bool GrRenderTargetContext::drawFilledDRRect(const GrClip& clip,
-                                             const GrPaint& paintIn,
+                                             GrPaint&& paint,
                                              GrAA aa,
                                              const SkMatrix& viewMatrix,
                                              const SkRRect& origOuter,
@@ -1001,10 +1000,10 @@
     if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport()) {
         InstancedRendering* ir = this->getOpList()->instancedRendering();
         std::unique_ptr<GrDrawOp> op(ir->recordDRRect(origOuter, origInner, viewMatrix,
-                                                      paintIn.getColor(), aa,
-                                                      fInstancedPipelineInfo, &aaType));
+                                                      paint.getColor(), aa, fInstancedPipelineInfo,
+                                                      &aaType));
         if (op) {
-            GrPipelineBuilder pipelineBuilder(paintIn, aaType);
+            GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
             this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
             return true;
         }
@@ -1037,8 +1036,6 @@
         inverseVM.reset();
     }
 
-    GrPaint grPaint(paintIn);
-
     // TODO these need to be a geometry processors
     sk_sp<GrFragmentProcessor> innerEffect(GrRRectEffect::Make(innerEdgeType, *inner));
     if (!innerEffect) {
@@ -1050,20 +1047,21 @@
         return false;
     }
 
-    grPaint.addCoverageFragmentProcessor(std::move(innerEffect));
-    grPaint.addCoverageFragmentProcessor(std::move(outerEffect));
+    paint.addCoverageFragmentProcessor(std::move(innerEffect));
+    paint.addCoverageFragmentProcessor(std::move(outerEffect));
 
     SkRect bounds = outer->getBounds();
     if (GrAAType::kCoverage == aaType) {
         bounds.outset(SK_ScalarHalf, SK_ScalarHalf);
     }
 
-    this->fillRectWithLocalMatrix(clip, grPaint, GrAA::kNo, SkMatrix::I(), bounds, inverseVM);
+    this->fillRectWithLocalMatrix(clip, std::move(paint), GrAA::kNo, SkMatrix::I(), bounds,
+                                  inverseVM);
     return true;
 }
 
 void GrRenderTargetContext::drawDRRect(const GrClip& clip,
-                                       const GrPaint& paint,
+                                       GrPaint&& paint,
                                        GrAA aa,
                                        const SkMatrix& viewMatrix,
                                        const SkRRect& outer,
@@ -1078,7 +1076,7 @@
 
     AutoCheckFlush acf(fDrawingManager);
 
-    if (this->drawFilledDRRect(clip, paint, aa, viewMatrix, outer, inner)) {
+    if (this->drawFilledDRRect(clip, std::move(paint), aa, viewMatrix, outer, inner)) {
         return;
     }
 
@@ -1088,7 +1086,7 @@
     path.addRRect(outer);
     path.setFillType(SkPath::kEvenOdd_FillType);
 
-    this->internalDrawPath(clip, paint, aa, viewMatrix, path, GrStyle::SimpleFill());
+    this->internalDrawPath(clip, std::move(paint), aa, viewMatrix, path, GrStyle::SimpleFill());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1098,7 +1096,7 @@
 }
 
 void GrRenderTargetContext::drawRegion(const GrClip& clip,
-                                       const GrPaint& paint,
+                                       GrPaint&& paint,
                                        GrAA aa,
                                        const SkMatrix& viewMatrix,
                                        const SkRegion& region,
@@ -1121,16 +1119,16 @@
     if (complexStyle || GrAA::kYes == aa) {
         SkPath path;
         region.getBoundaryPath(&path);
-        return this->drawPath(clip, paint, aa, viewMatrix, path, style);
+        return this->drawPath(clip, std::move(paint), aa, viewMatrix, path, style);
     }
 
     std::unique_ptr<GrDrawOp> op = GrRegionOp::Make(paint.getColor(), viewMatrix, region);
-    GrPipelineBuilder pipelineBuilder(paint, GrAAType::kNone);
+    GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
     this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
 }
 
 void GrRenderTargetContext::drawOval(const GrClip& clip,
-                                     const GrPaint& paint,
+                                     GrPaint&& paint,
                                      GrAA aa,
                                      const SkMatrix& viewMatrix,
                                      const SkRect& oval,
@@ -1156,7 +1154,7 @@
         std::unique_ptr<GrDrawOp> op(ir->recordOval(oval, viewMatrix, paint.getColor(), aa,
                                                     fInstancedPipelineInfo, &aaType));
         if (op) {
-            GrPipelineBuilder pipelineBuilder(paint, aaType);
+            GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
             this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
             return;
         }
@@ -1168,7 +1166,7 @@
         std::unique_ptr<GrDrawOp> op =
                 GrOvalOpFactory::MakeOvalOp(paint.getColor(), viewMatrix, oval, stroke, shaderCaps);
         if (op) {
-            GrPipelineBuilder pipelineBuilder(paint, aaType);
+            GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
             this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
             return;
         }
@@ -1177,11 +1175,11 @@
     SkPath path;
     path.setIsVolatile(true);
     path.addOval(oval);
-    this->internalDrawPath(clip, paint, aa, viewMatrix, path, style);
+    this->internalDrawPath(clip, std::move(paint), aa, viewMatrix, path, style);
 }
 
 void GrRenderTargetContext::drawArc(const GrClip& clip,
-                                    const GrPaint& paint,
+                                    GrPaint&& paint,
                                     GrAA aa,
                                     const SkMatrix& viewMatrix,
                                     const SkRect& oval,
@@ -1201,7 +1199,7 @@
                                                                   style,
                                                                   shaderCaps);
         if (op) {
-            GrPipelineBuilder pipelineBuilder(paint, aaType);
+            GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
             this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
             return;
         }
@@ -1209,11 +1207,11 @@
     SkPath path;
     SkPathPriv::CreateDrawArcPath(&path, oval, startAngle, sweepAngle, useCenter,
                                   style.isSimpleFill());
-    this->internalDrawPath(clip, paint, aa, viewMatrix, path, style);
+    this->internalDrawPath(clip, std::move(paint), aa, viewMatrix, path, style);
 }
 
 void GrRenderTargetContext::drawImageLattice(const GrClip& clip,
-                                             const GrPaint& paint,
+                                             GrPaint&& paint,
                                              const SkMatrix& viewMatrix,
                                              int imageWidth,
                                              int imageHeight,
@@ -1229,7 +1227,7 @@
     std::unique_ptr<GrDrawOp> op = GrLatticeOp::MakeNonAA(paint.getColor(), viewMatrix, imageWidth,
                                                           imageHeight, std::move(iter), dst);
 
-    GrPipelineBuilder pipelineBuilder(paint, GrAAType::kNone);
+    GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
     this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
 }
 
@@ -1252,7 +1250,7 @@
 }
 
 void GrRenderTargetContext::drawNonAAFilledRect(const GrClip& clip,
-                                                const GrPaint& paint,
+                                                GrPaint&& paint,
                                                 const SkMatrix& viewMatrix,
                                                 const SkRect& rect,
                                                 const SkRect* localRect,
@@ -1263,7 +1261,7 @@
     SkASSERT(hwOrNoneAAType == GrAAType::kNone || this->isStencilBufferMultisampled());
     std::unique_ptr<GrDrawOp> op = GrRectOpFactory::MakeNonAAFill(paint.getColor(), viewMatrix,
                                                                   rect, localRect, localMatrix);
-    GrPipelineBuilder pipelineBuilder(paint, hwOrNoneAAType);
+    GrPipelineBuilder pipelineBuilder(std::move(paint), hwOrNoneAAType);
     if (ss) {
         pipelineBuilder.setUserStencil(ss);
     }
@@ -1364,7 +1362,7 @@
 }
 
 void GrRenderTargetContext::drawPath(const GrClip& clip,
-                                     const GrPaint& paint,
+                                     GrPaint&& paint,
                                      GrAA aa,
                                      const SkMatrix& viewMatrix,
                                      const SkPath& path,
@@ -1376,7 +1374,7 @@
 
     if (path.isEmpty()) {
        if (path.isInverseFillType()) {
-           this->drawPaint(clip, paint, viewMatrix);
+           this->drawPaint(clip, std::move(paint), viewMatrix);
        }
        return;
     }
@@ -1393,7 +1391,7 @@
                 std::unique_ptr<GrDrawOp> op =
                         GrRectOpFactory::MakeAAFillNestedRects(paint.getColor(), viewMatrix, rects);
                 if (op) {
-                    GrPipelineBuilder pipelineBuilder(paint, aaType);
+                    GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
                     this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
                 }
                 return;
@@ -1407,7 +1405,7 @@
             std::unique_ptr<GrDrawOp> op = GrOvalOpFactory::MakeOvalOp(
                     paint.getColor(), viewMatrix, ovalRect, style.strokeRec(), shaderCaps);
             if (op) {
-                GrPipelineBuilder pipelineBuilder(paint, aaType);
+                GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
                 this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
                 return;
             }
@@ -1419,7 +1417,7 @@
     // cache. This presents a potential hazard for buffered drawing. However,
     // the writePixels that uploads to the scratch will perform a flush so we're
     // OK.
-    this->internalDrawPath(clip, paint, aa, viewMatrix, path, style);
+    this->internalDrawPath(clip, std::move(paint), aa, viewMatrix, path, style);
 }
 
 bool GrRenderTargetContextPriv::drawAndStencilPath(const GrClip& clip,
@@ -1470,17 +1468,16 @@
     GrPaint paint;
     paint.setCoverageSetOpXPFactory(op, invert);
 
-    GrPathRenderer::DrawPathArgs args;
-    args.fResourceProvider =
-        fRenderTargetContext->fDrawingManager->getContext()->resourceProvider();
-    args.fPaint = &paint;
-    args.fUserStencilSettings = ss;
-    args.fRenderTargetContext = fRenderTargetContext;
-    args.fClip = &clip;
-    args.fViewMatrix = &viewMatrix;
-    args.fShape = &shape;
-    args.fAAType = aaType;
-    args.fGammaCorrect = fRenderTargetContext->isGammaCorrect();
+    GrPathRenderer::DrawPathArgs args{
+            fRenderTargetContext->fDrawingManager->getContext()->resourceProvider(),
+            std::move(paint),
+            ss,
+            fRenderTargetContext,
+            &clip,
+            &viewMatrix,
+            &shape,
+            aaType,
+            fRenderTargetContext->isGammaCorrect()};
     pr->drawPath(args);
     return true;
 }
@@ -1498,7 +1495,7 @@
 }
 
 void GrRenderTargetContext::internalDrawPath(const GrClip& clip,
-                                             const GrPaint& paint,
+                                             GrPaint&& paint,
                                              GrAA aa,
                                              const SkMatrix& viewMatrix,
                                              const SkPath& path,
@@ -1569,16 +1566,15 @@
         return;
     }
 
-    GrPathRenderer::DrawPathArgs args;
-    args.fResourceProvider = fDrawingManager->getContext()->resourceProvider();
-    args.fPaint = &paint;
-    args.fUserStencilSettings = &GrUserStencilSettings::kUnused;
-    args.fRenderTargetContext = this;
-    args.fClip = &clip;
-    args.fViewMatrix = &viewMatrix;
-    args.fShape = &shape;
-    args.fAAType = aaType;
-    args.fGammaCorrect = this->isGammaCorrect();
+    GrPathRenderer::DrawPathArgs args{fDrawingManager->getContext()->resourceProvider(),
+                                      std::move(paint),
+                                      &GrUserStencilSettings::kUnused,
+                                      this,
+                                      &clip,
+                                      &viewMatrix,
+                                      &shape,
+                                      aaType,
+                                      this->isGammaCorrect()};
     pr->drawPath(args);
 }
 
diff --git a/src/gpu/GrRenderTargetContextPriv.h b/src/gpu/GrRenderTargetContextPriv.h
index 19ee9da..8a1061c 100644
--- a/src/gpu/GrRenderTargetContextPriv.h
+++ b/src/gpu/GrRenderTargetContextPriv.h
@@ -108,7 +108,7 @@
         return fRenderTargetContext->fRenderTargetProxy->uniqueID();
     }
 
-    void testingOnly_addDrawOp(const GrPaint&,
+    void testingOnly_addDrawOp(GrPaint&&,
                                GrAAType,
                                std::unique_ptr<GrDrawOp>,
                                const GrUserStencilSettings* = nullptr,
diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp
index 10343a3..839ec25 100644
--- a/src/gpu/GrSWMaskHelper.cpp
+++ b/src/gpu/GrSWMaskHelper.cpp
@@ -160,7 +160,7 @@
 
 void GrSWMaskHelper::DrawToTargetWithShapeMask(GrTexture* texture,
                                                GrRenderTargetContext* renderTargetContext,
-                                               const GrPaint& paint,
+                                               GrPaint&& paint,
                                                const GrUserStencilSettings& userStencilSettings,
                                                const GrClip& clip,
                                                const SkMatrix& viewMatrix,
@@ -181,16 +181,14 @@
     maskMatrix.preTranslate(SkIntToScalar(-textureOriginInDeviceSpace.fX),
                             SkIntToScalar(-textureOriginInDeviceSpace.fY));
     maskMatrix.preConcat(viewMatrix);
-    GrPipelineBuilder pipelineBuilder(paint, GrAAType::kNone);
+    std::unique_ptr<GrDrawOp> op = GrRectOpFactory::MakeNonAAFill(paint.getColor(), SkMatrix::I(),
+                                                                  dstRect, nullptr, &invert);
+    GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
     pipelineBuilder.setUserStencil(&userStencilSettings);
-
     pipelineBuilder.addCoverageFragmentProcessor(
                          GrSimpleTextureEffect::Make(texture,
                                                      nullptr,
                                                      maskMatrix,
                                                      GrSamplerParams::kNone_FilterMode));
-
-    std::unique_ptr<GrDrawOp> op = GrRectOpFactory::MakeNonAAFill(paint.getColor(), SkMatrix::I(),
-                                                                  dstRect, nullptr, &invert);
     renderTargetContext->addDrawOp(pipelineBuilder, clip, std::move(op));
 }
diff --git a/src/gpu/GrSWMaskHelper.h b/src/gpu/GrSWMaskHelper.h
index 6ec1c82..89d8842 100644
--- a/src/gpu/GrSWMaskHelper.h
+++ b/src/gpu/GrSWMaskHelper.h
@@ -81,7 +81,7 @@
     // local coords are provided to any fragment processors in the paint.
     static void DrawToTargetWithShapeMask(GrTexture* texture,
                                           GrRenderTargetContext*,
-                                          const GrPaint& paint,
+                                          GrPaint&& paint,
                                           const GrUserStencilSettings& userStencilSettings,
                                           const GrClip&,
                                           const SkMatrix& viewMatrix,
diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp
index 490d00e..695796b 100644
--- a/src/gpu/GrSoftwarePathRenderer.cpp
+++ b/src/gpu/GrSoftwarePathRenderer.cpp
@@ -71,7 +71,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 void GrSoftwarePathRenderer::DrawNonAARect(GrRenderTargetContext* renderTargetContext,
-                                           const GrPaint& paint,
+                                           GrPaint&& paint,
                                            const GrUserStencilSettings& userStencilSettings,
                                            const GrClip& clip,
                                            const SkMatrix& viewMatrix,
@@ -80,13 +80,13 @@
     std::unique_ptr<GrDrawOp> op(GrRectOpFactory::MakeNonAAFill(paint.getColor(), viewMatrix, rect,
                                                                 nullptr, &localMatrix));
 
-    GrPipelineBuilder pipelineBuilder(paint, GrAAType::kNone);
+    GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
     pipelineBuilder.setUserStencil(&userStencilSettings);
     renderTargetContext->addDrawOp(pipelineBuilder, clip, std::move(op));
 }
 
 void GrSoftwarePathRenderer::DrawAroundInvPath(GrRenderTargetContext* renderTargetContext,
-                                               const GrPaint& paint,
+                                               GrPaint&& paint,
                                                const GrUserStencilSettings& userStencilSettings,
                                                const GrClip& clip,
                                                const SkMatrix& viewMatrix,
@@ -101,25 +101,25 @@
     if (devClipBounds.fTop < devPathBounds.fTop) {
         rect.iset(devClipBounds.fLeft, devClipBounds.fTop,
                   devClipBounds.fRight, devPathBounds.fTop);
-        DrawNonAARect(renderTargetContext, paint, userStencilSettings, clip,
-                      SkMatrix::I(), rect, invert);
+        DrawNonAARect(renderTargetContext, GrPaint(paint), userStencilSettings, clip, SkMatrix::I(),
+                      rect, invert);
     }
     if (devClipBounds.fLeft < devPathBounds.fLeft) {
         rect.iset(devClipBounds.fLeft, devPathBounds.fTop,
                   devPathBounds.fLeft, devPathBounds.fBottom);
-        DrawNonAARect(renderTargetContext, paint, userStencilSettings, clip,
-                      SkMatrix::I(), rect, invert);
+        DrawNonAARect(renderTargetContext, GrPaint(paint), userStencilSettings, clip, SkMatrix::I(),
+                      rect, invert);
     }
     if (devClipBounds.fRight > devPathBounds.fRight) {
         rect.iset(devPathBounds.fRight, devPathBounds.fTop,
                   devClipBounds.fRight, devPathBounds.fBottom);
-        DrawNonAARect(renderTargetContext, paint, userStencilSettings, clip,
-                      SkMatrix::I(), rect, invert);
+        DrawNonAARect(renderTargetContext, GrPaint(paint), userStencilSettings, clip, SkMatrix::I(),
+                      rect, invert);
     }
     if (devClipBounds.fBottom > devPathBounds.fBottom) {
         rect.iset(devClipBounds.fLeft, devPathBounds.fBottom,
                   devClipBounds.fRight, devClipBounds.fBottom);
-        DrawNonAARect(renderTargetContext, paint, userStencilSettings, clip,
+        DrawNonAARect(renderTargetContext, std::move(paint), userStencilSettings, clip,
                       SkMatrix::I(), rect, invert);
     }
 }
@@ -152,10 +152,9 @@
                                    &clippedDevShapeBounds,
                                    &devClipBounds)) {
         if (inverseFilled) {
-            DrawAroundInvPath(args.fRenderTargetContext, *args.fPaint, *args.fUserStencilSettings,
-                              *args.fClip,
-                              *args.fViewMatrix, devClipBounds, unclippedDevShapeBounds);
-
+            DrawAroundInvPath(args.fRenderTargetContext, std::move(args.fPaint),
+                              *args.fUserStencilSettings, *args.fClip, *args.fViewMatrix,
+                              devClipBounds, unclippedDevShapeBounds);
         }
         return true;
     }
@@ -223,16 +222,15 @@
             texture->resourcePriv().setUniqueKey(maskKey);
         }
     }
-    GrSWMaskHelper::DrawToTargetWithShapeMask(texture.get(), args.fRenderTargetContext,
-                                              *args.fPaint, *args.fUserStencilSettings,
-                                              *args.fClip, *args.fViewMatrix,
-                                              SkIPoint {boundsForMask->fLeft, boundsForMask->fTop},
-                                              *boundsForMask);
     if (inverseFilled) {
-        DrawAroundInvPath(args.fRenderTargetContext, *args.fPaint, *args.fUserStencilSettings,
-                          *args.fClip,
-                          *args.fViewMatrix, devClipBounds, unclippedDevShapeBounds);
+        DrawAroundInvPath(args.fRenderTargetContext, GrPaint(args.fPaint),
+                          *args.fUserStencilSettings, *args.fClip, *args.fViewMatrix, devClipBounds,
+                          unclippedDevShapeBounds);
     }
+    GrSWMaskHelper::DrawToTargetWithShapeMask(
+            texture.get(), args.fRenderTargetContext, std::move(args.fPaint),
+            *args.fUserStencilSettings, *args.fClip, *args.fViewMatrix,
+            SkIPoint{boundsForMask->fLeft, boundsForMask->fTop}, *boundsForMask);
 
     return true;
 }
diff --git a/src/gpu/GrSoftwarePathRenderer.h b/src/gpu/GrSoftwarePathRenderer.h
index 64ecfb6..7dec4be 100644
--- a/src/gpu/GrSoftwarePathRenderer.h
+++ b/src/gpu/GrSoftwarePathRenderer.h
@@ -23,14 +23,14 @@
             , fAllowCaching(allowCaching) {}
 private:
     static void DrawNonAARect(GrRenderTargetContext* renderTargetContext,
-                              const GrPaint& paint,
+                              GrPaint&& paint,
                               const GrUserStencilSettings& userStencilSettings,
                               const GrClip& clip,
                               const SkMatrix& viewMatrix,
                               const SkRect& rect,
                               const SkMatrix& localMatrix);
     static void DrawAroundInvPath(GrRenderTargetContext* renderTargetContext,
-                                  const GrPaint& paint,
+                                  GrPaint&& paint,
                                   const GrUserStencilSettings& userStencilSettings,
                                   const GrClip& clip,
                                   const SkMatrix& viewMatrix,
diff --git a/src/gpu/GrTextureProducer.cpp b/src/gpu/GrTextureProducer.cpp
index d75aff6..0adae8c 100644
--- a/src/gpu/GrTextureProducer.cpp
+++ b/src/gpu/GrTextureProducer.cpp
@@ -65,7 +65,8 @@
     }
 
     SkRect dstRect = SkRect::MakeIWH(copyParams.fWidth, copyParams.fHeight);
-    copyRTC->fillRectToRect(GrNoClip(), paint, GrAA::kNo, SkMatrix::I(), dstRect, localRect);
+    copyRTC->fillRectToRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(), dstRect,
+                            localRect);
     return copyRTC->asTexture().release();
 }
 
diff --git a/src/gpu/GrTextureToYUVPlanes.cpp b/src/gpu/GrTextureToYUVPlanes.cpp
index 6268bef..7102945 100644
--- a/src/gpu/GrTextureToYUVPlanes.cpp
+++ b/src/gpu/GrTextureToYUVPlanes.cpp
@@ -43,7 +43,8 @@
     GrPaint paint;
     paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
     paint.addColorFragmentProcessor(std::move(fp));
-    dst->drawRect(GrNoClip(), paint, GrAA::kNo, SkMatrix::I(), SkRect::MakeIWH(dstW, dstH));
+    dst->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(),
+                  SkRect::MakeIWH(dstW, dstH));
     return true;
 }
 
diff --git a/src/gpu/GrYUVProvider.cpp b/src/gpu/GrYUVProvider.cpp
index 9f88c72..1330cfe 100644
--- a/src/gpu/GrYUVProvider.cpp
+++ b/src/gpu/GrYUVProvider.cpp
@@ -148,7 +148,7 @@
     const SkRect r = SkRect::MakeIWH(yuvInfo.fSizeInfo.fSizes[SkYUVSizeInfo::kY].fWidth,
             yuvInfo.fSizeInfo.fSizes[SkYUVSizeInfo::kY].fHeight);
 
-    renderTargetContext->drawRect(GrNoClip(), paint, GrAA::kNo, SkMatrix::I(), r);
+    renderTargetContext->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(), r);
 
     return renderTargetContext->asTexture();
 }
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 2230100..3e94d32 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -280,7 +280,7 @@
         return;
     }
 
-    fRenderTargetContext->drawPaint(fClip, grPaint, *draw.fMatrix);
+    fRenderTargetContext->drawPaint(fClip, std::move(grPaint), *draw.fMatrix);
 }
 
 // must be in SkCanvas::PointMode order
@@ -339,7 +339,7 @@
         path.setIsVolatile(true);
         path.moveTo(pts[0]);
         path.lineTo(pts[1]);
-        fRenderTargetContext->drawPath(fClip, grPaint, GrBoolToAA(paint.isAntiAlias()),
+        fRenderTargetContext->drawPath(fClip, std::move(grPaint), GrBoolToAA(paint.isAntiAlias()),
                                        *draw.fMatrix, path, style);
         return;
     }
@@ -378,7 +378,7 @@
     }
 
     fRenderTargetContext->drawVertices(fClip,
-                                       grPaint,
+                                       std::move(grPaint),
                                        *viewMatrix,
                                        primitiveType,
                                        SkToS32(count),
@@ -416,8 +416,8 @@
     }
 
     GrStyle style(paint);
-    fRenderTargetContext->drawRect(fClip, grPaint, GrBoolToAA(paint.isAntiAlias()), *draw.fMatrix,
-                                   rect, &style);
+    fRenderTargetContext->drawRect(fClip, std::move(grPaint), GrBoolToAA(paint.isAntiAlias()),
+                                   *draw.fMatrix, rect, &style);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -455,7 +455,7 @@
                         return;
                     }
                     if (mf->directFilterRRectMaskGPU(fContext.get(), fRenderTargetContext.get(),
-                                                     &grPaint, fClip, *draw.fMatrix,
+                                                     std::move(grPaint), fClip, *draw.fMatrix,
                                                      style.strokeRec(), rrect, devRRect)) {
                         return;
                     }
@@ -481,8 +481,8 @@
 
     SkASSERT(!style.pathEffect());
 
-    fRenderTargetContext->drawRRect(fClip, grPaint, GrBoolToAA(paint.isAntiAlias()), *draw.fMatrix,
-                                    rrect, style);
+    fRenderTargetContext->drawRRect(fClip, std::move(grPaint), GrBoolToAA(paint.isAntiAlias()),
+                                    *draw.fMatrix, rrect, style);
 }
 
 
@@ -509,7 +509,7 @@
             return;
         }
 
-        fRenderTargetContext->drawDRRect(fClip, grPaint, GrBoolToAA(paint.isAntiAlias()),
+        fRenderTargetContext->drawDRRect(fClip, std::move(grPaint), GrBoolToAA(paint.isAntiAlias()),
                                          *draw.fMatrix, outer, inner);
         return;
     }
@@ -542,8 +542,8 @@
         return;
     }
 
-    fRenderTargetContext->drawRegion(fClip, grPaint, GrBoolToAA(paint.isAntiAlias()), *draw.fMatrix,
-                                     region, GrStyle(paint));
+    fRenderTargetContext->drawRegion(fClip, std::move(grPaint), GrBoolToAA(paint.isAntiAlias()),
+                                     *draw.fMatrix, region, GrStyle(paint));
 }
 
 void SkGpuDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPaint& paint) {
@@ -572,8 +572,8 @@
         return;
     }
 
-    fRenderTargetContext->drawOval(fClip, grPaint, GrBoolToAA(paint.isAntiAlias()), *draw.fMatrix,
-                                   oval, GrStyle(paint));
+    fRenderTargetContext->drawOval(fClip, std::move(grPaint), GrBoolToAA(paint.isAntiAlias()),
+                                   *draw.fMatrix, oval, GrStyle(paint));
 }
 
 void SkGpuDevice::drawArc(const SkDraw& draw, const SkRect& oval, SkScalar startAngle,
@@ -592,8 +592,9 @@
         return;
     }
 
-    fRenderTargetContext->drawArc(fClip, grPaint, GrBoolToAA(paint.isAntiAlias()), *draw.fMatrix,
-                                  oval, startAngle, sweepAngle, useCenter, GrStyle(paint));
+    fRenderTargetContext->drawArc(fClip, std::move(grPaint), GrBoolToAA(paint.isAntiAlias()),
+                                  *draw.fMatrix, oval, startAngle, sweepAngle, useCenter,
+                                  GrStyle(paint));
 }
 
 #include "SkMaskFilter.h"
@@ -649,9 +650,8 @@
         return;
     }
 
-    fRenderTargetContext->fillRectWithLocalMatrix(fClip, grPaint,
-                                                  GrBoolToAA(newPaint.isAntiAlias()), m, rect,
-                                                  local);
+    fRenderTargetContext->fillRectWithLocalMatrix(
+            fClip, std::move(grPaint), GrBoolToAA(newPaint.isAntiAlias()), m, rect, local);
 }
 
 void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
@@ -1103,7 +1103,7 @@
     // Coverage-based AA would cause seams between tiles.
     GrAA aa = GrBoolToAA(paint.isAntiAlias() &&
                          fRenderTargetContext->isStencilBufferMultisampled());
-    fRenderTargetContext->drawRect(fClip, grPaint, aa, viewMatrix, dstRect);
+    fRenderTargetContext->drawRect(fClip, std::move(grPaint), aa, viewMatrix, dstRect);
 }
 
 void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
@@ -1195,19 +1195,17 @@
 
     const SkIRect& subset = result->subset();
 
-    fRenderTargetContext->fillRectToRect(fClip,
-                                         grPaint,
-                                         GrBoolToAA(paint.isAntiAlias()),
-                                         SkMatrix::I(),
-                                         SkRect::Make(SkIRect::MakeXYWH(left + offset.fX,
-                                                                        top + offset.fY,
-                                                                        subset.width(),
-                                                                        subset.height())),
-                                        SkRect::MakeXYWH(
-                                            SkIntToScalar(subset.fLeft) / texture->width(),
-                                            SkIntToScalar(subset.fTop) / texture->height(),
-                                            SkIntToScalar(subset.width()) / texture->width(),
-                                            SkIntToScalar(subset.height()) / texture->height()));
+    fRenderTargetContext->fillRectToRect(
+            fClip,
+            std::move(grPaint),
+            GrBoolToAA(paint.isAntiAlias()),
+            SkMatrix::I(),
+            SkRect::Make(SkIRect::MakeXYWH(
+                    left + offset.fX, top + offset.fY, subset.width(), subset.height())),
+            SkRect::MakeXYWH(SkIntToScalar(subset.fLeft) / texture->width(),
+                             SkIntToScalar(subset.fTop) / texture->height(),
+                             SkIntToScalar(subset.width()) / texture->width(),
+                             SkIntToScalar(subset.height()) / texture->height()));
 }
 
 void SkGpuDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
@@ -1476,8 +1474,9 @@
 
     std::unique_ptr<SkLatticeIter> iter(
             new SkLatticeIter(producer->width(), producer->height(), center, dst));
-    fRenderTargetContext->drawImageLattice(fClip, grPaint, *draw.fMatrix, producer->width(),
-                                           producer->height(), std::move(iter), dst);
+    fRenderTargetContext->drawImageLattice(fClip, std::move(grPaint), *draw.fMatrix,
+                                           producer->width(), producer->height(), std::move(iter),
+                                           dst);
 }
 
 void SkGpuDevice::drawImageNine(const SkDraw& draw, const SkImage* image,
@@ -1529,8 +1528,9 @@
 
     std::unique_ptr<SkLatticeIter> iter(
             new SkLatticeIter(lattice, dst));
-    fRenderTargetContext->drawImageLattice(fClip, grPaint, *draw.fMatrix, producer->width(),
-                                           producer->height(), std::move(iter), dst);
+    fRenderTargetContext->drawImageLattice(fClip, std::move(grPaint), *draw.fMatrix,
+                                           producer->width(), producer->height(), std::move(iter),
+                                           dst);
 }
 
 void SkGpuDevice::drawImageLattice(const SkDraw& draw, const SkImage* image,
@@ -1627,7 +1627,7 @@
             i += 6;
         }
         fRenderTargetContext->drawVertices(fClip,
-                                           grPaint,
+                                           std::move(grPaint),
                                            *draw.fMatrix,
                                            kLines_GrPrimitiveType,
                                            vertexCount,
@@ -1684,7 +1684,7 @@
     }
 
     fRenderTargetContext->drawVertices(fClip,
-                                       grPaint,
+                                       std::move(grPaint),
                                        *draw.fMatrix,
                                        primType,
                                        vertexCount,
@@ -1726,7 +1726,8 @@
     }
 
     SkDEBUGCODE(this->validate();)
-    fRenderTargetContext->drawAtlas(fClip, grPaint, *draw.fMatrix, count, xform, texRect, colors);
+    fRenderTargetContext->drawAtlas(fClip, std::move(grPaint), *draw.fMatrix, count, xform, texRect,
+                                    colors);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1746,8 +1747,8 @@
 
     SkDEBUGCODE(this->validate();)
 
-    fRenderTargetContext->drawText(fClip, grPaint, paint, *draw.fMatrix,
-                                   (const char *)text, byteLength, x, y, draw.fRC->getBounds());
+    fRenderTargetContext->drawText(fClip, std::move(grPaint), paint, *draw.fMatrix,
+                                   (const char*)text, byteLength, x, y, draw.fRC->getBounds());
 }
 
 void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text, size_t byteLength,
@@ -1765,8 +1766,8 @@
 
     SkDEBUGCODE(this->validate();)
 
-    fRenderTargetContext->drawPosText(fClip, grPaint, paint, *draw.fMatrix,
-                                      (const char *)text, byteLength, pos, scalarsPerPos, offset,
+    fRenderTargetContext->drawPosText(fClip, std::move(grPaint), paint, *draw.fMatrix,
+                                      (const char*)text, byteLength, pos, scalarsPerPos, offset,
                                       draw.fRC->getBounds());
 }
 
diff --git a/src/gpu/SkGpuDevice_drawTexture.cpp b/src/gpu/SkGpuDevice_drawTexture.cpp
index 9556146..cff26b4 100644
--- a/src/gpu/SkGpuDevice_drawTexture.cpp
+++ b/src/gpu/SkGpuDevice_drawTexture.cpp
@@ -215,13 +215,13 @@
     }
     GrAA aa = GrBoolToAA(paint.isAntiAlias());
     if (canUseTextureCoordsAsLocalCoords) {
-        fRenderTargetContext->fillRectToRect(clip, grPaint, aa, viewMatrix, clippedDstRect,
-                                             clippedSrcRect);
+        fRenderTargetContext->fillRectToRect(clip, std::move(grPaint), aa, viewMatrix,
+                                             clippedDstRect, clippedSrcRect);
         return;
     }
 
     if (!mf) {
-        fRenderTargetContext->drawRect(clip, grPaint, aa, viewMatrix, clippedDstRect);
+        fRenderTargetContext->drawRect(clip, std::move(grPaint), aa, viewMatrix, clippedDstRect);
         return;
     }
 
@@ -233,7 +233,7 @@
         SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
         if (mf->directFilterRRectMaskGPU(fContext.get(),
                                          fRenderTargetContext.get(),
-                                         &grPaint,
+                                         std::move(grPaint),
                                          clip,
                                          viewMatrix,
                                          rec,
@@ -247,6 +247,6 @@
     rectPath.addRect(clippedDstRect);
     rectPath.setIsVolatile(true);
     GrBlurUtils::drawPathWithMaskFilter(this->context(), fRenderTargetContext.get(), fClip,
-                                        rectPath, &grPaint, aa, viewMatrix, mf,
+                                        rectPath, std::move(grPaint), aa, viewMatrix, mf,
                                         GrStyle::SimpleFill(), true);
 }
diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp
index f6f8334..8405fcb 100644
--- a/src/gpu/effects/GrConfigConversionEffect.cpp
+++ b/src/gpu/effects/GrConfigConversionEffect.cpp
@@ -237,19 +237,22 @@
         paint1.addColorFragmentProcessor(std::move(pmToUPM1));
         paint1.setPorterDuffXPFactory(SkBlendMode::kSrc);
 
-        readRTC->fillRectToRect(GrNoClip(), paint1, GrAA::kNo, SkMatrix::I(), kDstRect, kSrcRect);
+        readRTC->fillRectToRect(GrNoClip(), std::move(paint1), GrAA::kNo, SkMatrix::I(), kDstRect,
+                                kSrcRect);
 
         readRTC->asTexture()->readPixels(0, 0, kSize, kSize, kConfig, firstRead);
 
         paint2.addColorFragmentProcessor(std::move(upmToPM));
         paint2.setPorterDuffXPFactory(SkBlendMode::kSrc);
 
-        tempRTC->fillRectToRect(GrNoClip(), paint2, GrAA::kNo, SkMatrix::I(), kDstRect, kSrcRect);
+        tempRTC->fillRectToRect(GrNoClip(), std::move(paint2), GrAA::kNo, SkMatrix::I(), kDstRect,
+                                kSrcRect);
 
         paint3.addColorFragmentProcessor(std::move(pmToUPM2));
         paint3.setPorterDuffXPFactory(SkBlendMode::kSrc);
 
-        readRTC->fillRectToRect(GrNoClip(), paint3, GrAA::kNo, SkMatrix::I(), kDstRect, kSrcRect);
+        readRTC->fillRectToRect(GrNoClip(), std::move(paint3), GrAA::kNo, SkMatrix::I(), kDstRect,
+                                kSrcRect);
 
         readRTC->asTexture()->readPixels(0, 0, kSize, kSize, kConfig, secondRead);
 
diff --git a/src/gpu/ops/GrAAConvexPathRenderer.cpp b/src/gpu/ops/GrAAConvexPathRenderer.cpp
index e260d27..e845e5e 100644
--- a/src/gpu/ops/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/ops/GrAAConvexPathRenderer.cpp
@@ -970,9 +970,9 @@
     args.fShape->asPath(&path);
 
     std::unique_ptr<GrDrawOp> op =
-            AAConvexPathOp::Make(args.fPaint->getColor(), *args.fViewMatrix, path);
+            AAConvexPathOp::Make(args.fPaint.getColor(), *args.fViewMatrix, path);
 
-    GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fAAType);
+    GrPipelineBuilder pipelineBuilder(std::move(args.fPaint), args.fAAType);
     pipelineBuilder.setUserStencil(args.fUserStencilSettings);
 
     args.fRenderTargetContext->addDrawOp(pipelineBuilder, *args.fClip, std::move(op));
diff --git a/src/gpu/ops/GrAADistanceFieldPathRenderer.cpp b/src/gpu/ops/GrAADistanceFieldPathRenderer.cpp
index 616b69f..0cf4c00 100644
--- a/src/gpu/ops/GrAADistanceFieldPathRenderer.cpp
+++ b/src/gpu/ops/GrAADistanceFieldPathRenderer.cpp
@@ -530,9 +530,9 @@
     }
 
     std::unique_ptr<GrDrawOp> op = AADistanceFieldPathOp::Make(
-            args.fPaint->getColor(), *args.fShape, *args.fViewMatrix, fAtlas.get(), &fShapeCache,
+            args.fPaint.getColor(), *args.fShape, *args.fViewMatrix, fAtlas.get(), &fShapeCache,
             &fShapeList, args.fGammaCorrect);
-    GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fAAType);
+    GrPipelineBuilder pipelineBuilder(std::move(args.fPaint), args.fAAType);
     pipelineBuilder.setUserStencil(args.fUserStencilSettings);
 
     args.fRenderTargetContext->addDrawOp(pipelineBuilder, *args.fClip, std::move(op));
diff --git a/src/gpu/ops/GrAAHairLinePathRenderer.cpp b/src/gpu/ops/GrAAHairLinePathRenderer.cpp
index 29ad4ec..958eb57 100644
--- a/src/gpu/ops/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/ops/GrAAHairLinePathRenderer.cpp
@@ -952,9 +952,9 @@
                                       &devClipBounds);
     SkPath path;
     args.fShape->asPath(&path);
-    std::unique_ptr<GrDrawOp> op = AAHairlineOp::Make(args.fPaint->getColor(), *args.fViewMatrix,
+    std::unique_ptr<GrDrawOp> op = AAHairlineOp::Make(args.fPaint.getColor(), *args.fViewMatrix,
                                                       path, args.fShape->style(), devClipBounds);
-    GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fAAType);
+    GrPipelineBuilder pipelineBuilder(std::move(args.fPaint), args.fAAType);
     pipelineBuilder.setUserStencil(args.fUserStencilSettings);
     args.fRenderTargetContext->addDrawOp(pipelineBuilder, *args.fClip, std::move(op));
     return true;
diff --git a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp b/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
index 74f355e..caa086e 100644
--- a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
+++ b/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
@@ -336,10 +336,10 @@
     SkScalar miterLimit = stroke.getMiter();
 
     std::unique_ptr<GrDrawOp> op =
-            AAFlatteningConvexPathOp::Make(args.fPaint->getColor(), *args.fViewMatrix, path,
+            AAFlatteningConvexPathOp::Make(args.fPaint.getColor(), *args.fViewMatrix, path,
                                            strokeWidth, stroke.getStyle(), join, miterLimit);
 
-    GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fAAType);
+    GrPipelineBuilder pipelineBuilder(std::move(args.fPaint), args.fAAType);
     pipelineBuilder.setUserStencil(args.fUserStencilSettings);
 
     args.fRenderTargetContext->addDrawOp(pipelineBuilder, *args.fClip, std::move(op));
diff --git a/src/gpu/ops/GrDashLinePathRenderer.cpp b/src/gpu/ops/GrDashLinePathRenderer.cpp
index e381165..1c43cb5 100644
--- a/src/gpu/ops/GrDashLinePathRenderer.cpp
+++ b/src/gpu/ops/GrDashLinePathRenderer.cpp
@@ -46,12 +46,12 @@
     SkPoint pts[2];
     SkAssertResult(args.fShape->asLine(pts, nullptr));
     std::unique_ptr<GrDrawOp> op = GrDashOp::MakeDashLineOp(
-            args.fPaint->getColor(), *args.fViewMatrix, pts, aaMode, args.fShape->style());
+            args.fPaint.getColor(), *args.fViewMatrix, pts, aaMode, args.fShape->style());
     if (!op) {
         return false;
     }
 
-    GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fAAType);
+    GrPipelineBuilder pipelineBuilder(std::move(args.fPaint), args.fAAType);
     pipelineBuilder.setUserStencil(args.fUserStencilSettings);
 
     args.fRenderTargetContext->addDrawOp(pipelineBuilder, *args.fClip, std::move(op));
diff --git a/src/gpu/ops/GrDefaultPathRenderer.cpp b/src/gpu/ops/GrDefaultPathRenderer.cpp
index cbad5f2..270dc09 100644
--- a/src/gpu/ops/GrDefaultPathRenderer.cpp
+++ b/src/gpu/ops/GrDefaultPathRenderer.cpp
@@ -405,7 +405,7 @@
 };
 
 bool GrDefaultPathRenderer::internalDrawPath(GrRenderTargetContext* renderTargetContext,
-                                             const GrPaint& paint,
+                                             GrPaint&& paint,
                                              GrAAType aaType,
                                              const GrUserStencilSettings& userStencilSettings,
                                              const GrClip& clip,
@@ -550,15 +550,16 @@
                     paint.getColor(), viewM, bounds, nullptr, &localMatrix));
 
             SkASSERT(GrDrawFace::kBoth == drawFace[p]);
-            GrPipelineBuilder pipelineBuilder(paint, aaType);
+            GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
             pipelineBuilder.setDrawFace(drawFace[p]);
             pipelineBuilder.setUserStencil(passes[p]);
             renderTargetContext->addDrawOp(pipelineBuilder, clip, std::move(op));
         } else {
             std::unique_ptr<GrDrawOp> op =
                     DefaultPathOp::Make(paint.getColor(), path, srcSpaceTol, newCoverage,
+
                                         viewMatrix, isHairline, devBounds);
-            GrPipelineBuilder pipelineBuilder(paint, aaType);
+            GrPipelineBuilder pipelineBuilder(GrPaint::MoveOrNew(paint, lastPassIsBounds), aaType);
             pipelineBuilder.setDrawFace(drawFace[p]);
             pipelineBuilder.setUserStencil(passes[p]);
             if (passCount > 1) {
@@ -581,7 +582,7 @@
     GR_AUDIT_TRAIL_AUTO_FRAME(args.fRenderTargetContext->auditTrail(),
                               "GrDefaultPathRenderer::onDrawPath");
     return this->internalDrawPath(args.fRenderTargetContext,
-                                  *args.fPaint,
+                                  std::move(args.fPaint),
                                   args.fAAType,
                                   *args.fUserStencilSettings,
                                   *args.fClip,
@@ -598,7 +599,7 @@
     GrPaint paint;
     paint.setXPFactory(GrDisableColorXPFactory::Get());
 
-    this->internalDrawPath(args.fRenderTargetContext, paint, args.fAAType,
+    this->internalDrawPath(args.fRenderTargetContext, std::move(paint), args.fAAType,
                            GrUserStencilSettings::kUnused, *args.fClip, *args.fViewMatrix,
                            *args.fShape, true);
 }
diff --git a/src/gpu/ops/GrDefaultPathRenderer.h b/src/gpu/ops/GrDefaultPathRenderer.h
index 8e19247..0a84eb9 100644
--- a/src/gpu/ops/GrDefaultPathRenderer.h
+++ b/src/gpu/ops/GrDefaultPathRenderer.h
@@ -31,7 +31,7 @@
     void onStencilPath(const StencilPathArgs&) override;
 
     bool internalDrawPath(GrRenderTargetContext*,
-                          const GrPaint&,
+                          GrPaint&&,
                           GrAAType,
                           const GrUserStencilSettings&,
                           const GrClip&,
diff --git a/src/gpu/ops/GrMSAAPathRenderer.cpp b/src/gpu/ops/GrMSAAPathRenderer.cpp
index 53e4690..5c1c110 100644
--- a/src/gpu/ops/GrMSAAPathRenderer.cpp
+++ b/src/gpu/ops/GrMSAAPathRenderer.cpp
@@ -563,7 +563,7 @@
 };
 
 bool GrMSAAPathRenderer::internalDrawPath(GrRenderTargetContext* renderTargetContext,
-                                          const GrPaint& paint,
+                                          GrPaint&& paint,
                                           GrAAType aaType,
                                           const GrUserStencilSettings& userStencilSettings,
                                           const GrClip& clip,
@@ -574,21 +574,15 @@
     SkPath path;
     shape.asPath(&path);
 
-    static const int kMaxNumPasses = 2;
-
-    int                          passCount = 0;
-    const GrUserStencilSettings* passes[kMaxNumPasses];
+    const GrUserStencilSettings* passes[2] = {nullptr, nullptr};
     bool                         reverse = false;
-    bool                         lastPassIsBounds;
 
     if (single_pass_shape(shape)) {
-        passCount = 1;
         if (stencilOnly) {
             passes[0] = &gDirectToStencil;
         } else {
             passes[0] = &userStencilSettings;
         }
-        lastPassIsBounds = false;
     } else {
         switch (path.getFillType()) {
             case SkPath::kInverseEvenOdd_FillType:
@@ -596,17 +590,8 @@
                 // fallthrough
             case SkPath::kEvenOdd_FillType:
                 passes[0] = &gEOStencilPass;
-                if (stencilOnly) {
-                    passCount = 1;
-                    lastPassIsBounds = false;
-                } else {
-                    passCount = 2;
-                    lastPassIsBounds = true;
-                    if (reverse) {
-                        passes[1] = &gInvEOColorPass;
-                    } else {
-                        passes[1] = &gEOColorPass;
-                    }
+                if (!stencilOnly) {
+                    passes[1] = reverse ? &gInvEOColorPass : &gEOColorPass;
                 }
                 break;
 
@@ -615,17 +600,8 @@
                 // fallthrough
             case SkPath::kWinding_FillType:
                 passes[0] = &gWindStencilSeparateWithWrap;
-                passCount = 2;
-                if (stencilOnly) {
-                    lastPassIsBounds = false;
-                    passCount = 1;
-                } else {
-                    lastPassIsBounds = true;
-                    if (reverse) {
-                        passes[1] = &gInvWindColorPass;
-                    } else {
-                        passes[1] = &gWindColorPass;
-                    }
+                if (!stencilOnly) {
+                    passes[1] = reverse ? &gInvWindColorPass : &gWindColorPass;
                 }
                 break;
             default:
@@ -637,50 +613,48 @@
     SkRect devBounds;
     GetPathDevBounds(path, renderTargetContext->width(), renderTargetContext->height(), viewMatrix,
                      &devBounds);
+    SkASSERT(passes[0]);
 
-    SkASSERT(passCount <= kMaxNumPasses);
+    std::unique_ptr<GrDrawOp> op = MSAAPathOp::Make(paint.getColor(), path, viewMatrix, devBounds);
+    if (!op) {
+        return false;
+    }
+    // If we have a cover pass then we ignore the paint in the first pass and apply it in the
+    // second.
+    GrPipelineBuilder pipelineBuilder(GrPaint::MoveOrNew(paint, passes[1]), aaType);
+    pipelineBuilder.setUserStencil(passes[0]);
+    if (passes[1]) {
+        pipelineBuilder.setDisableColorXPFactory();
+    }
+    renderTargetContext->addDrawOp(pipelineBuilder, clip, std::move(op));
 
-    for (int p = 0; p < passCount; ++p) {
-        if (lastPassIsBounds && (p == passCount-1)) {
-            SkRect bounds;
-            SkMatrix localMatrix = SkMatrix::I();
-            if (reverse) {
-                // draw over the dev bounds (which will be the whole dst surface for inv fill).
-                bounds = devBounds;
-                SkMatrix vmi;
-                // mapRect through persp matrix may not be correct
-                if (!viewMatrix.hasPerspective() && viewMatrix.invert(&vmi)) {
-                    vmi.mapRect(&bounds);
-                } else {
-                    if (!viewMatrix.invert(&localMatrix)) {
-                        return false;
-                    }
-                }
+    if (passes[1]) {
+        SkRect bounds;
+        SkMatrix localMatrix = SkMatrix::I();
+        if (reverse) {
+            // draw over the dev bounds (which will be the whole dst surface for inv fill).
+            bounds = devBounds;
+            SkMatrix vmi;
+            // mapRect through persp matrix may not be correct
+            if (!viewMatrix.hasPerspective() && viewMatrix.invert(&vmi)) {
+                vmi.mapRect(&bounds);
             } else {
-                bounds = path.getBounds();
+                if (!viewMatrix.invert(&localMatrix)) {
+                    return false;
+                }
             }
-            const SkMatrix& viewM = (reverse && viewMatrix.hasPerspective()) ? SkMatrix::I() :
-                                                                               viewMatrix;
-            std::unique_ptr<GrDrawOp> op(GrRectOpFactory::MakeNonAAFill(
-                    paint.getColor(), viewM, bounds, nullptr, &localMatrix));
-
-            GrPipelineBuilder pipelineBuilder(paint, aaType);
-            pipelineBuilder.setUserStencil(passes[p]);
-
-            renderTargetContext->addDrawOp(pipelineBuilder, clip, std::move(op));
         } else {
-            std::unique_ptr<GrDrawOp> op =
-                    MSAAPathOp::Make(paint.getColor(), path, viewMatrix, devBounds);
-            if (!op) {
-                return false;
-            }
-            GrPipelineBuilder pipelineBuilder(paint, aaType);
-            pipelineBuilder.setUserStencil(passes[p]);
-            if (passCount > 1) {
-                pipelineBuilder.setDisableColorXPFactory();
-            }
-            renderTargetContext->addDrawOp(pipelineBuilder, clip, std::move(op));
+            bounds = path.getBounds();
         }
+        const SkMatrix& viewM =
+                (reverse && viewMatrix.hasPerspective()) ? SkMatrix::I() : viewMatrix;
+        std::unique_ptr<GrDrawOp> op(GrRectOpFactory::MakeNonAAFill(paint.getColor(), viewM, bounds,
+                                                                    nullptr, &localMatrix));
+
+        GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
+        pipelineBuilder.setUserStencil(passes[1]);
+
+        renderTargetContext->addDrawOp(pipelineBuilder, clip, std::move(op));
     }
     return true;
 }
@@ -703,7 +677,7 @@
         shape = tmpShape.get();
     }
     return this->internalDrawPath(args.fRenderTargetContext,
-                                  *args.fPaint,
+                                  std::move(args.fPaint),
                                   args.fAAType,
                                   *args.fUserStencilSettings,
                                   *args.fClip,
@@ -721,7 +695,7 @@
     GrPaint paint;
     paint.setXPFactory(GrDisableColorXPFactory::Get());
 
-    this->internalDrawPath(args.fRenderTargetContext, paint, args.fAAType,
+    this->internalDrawPath(args.fRenderTargetContext, std::move(paint), args.fAAType,
                            GrUserStencilSettings::kUnused, *args.fClip, *args.fViewMatrix,
                            *args.fShape, true);
 }
diff --git a/src/gpu/ops/GrMSAAPathRenderer.h b/src/gpu/ops/GrMSAAPathRenderer.h
index a112c62..13d3e15 100644
--- a/src/gpu/ops/GrMSAAPathRenderer.h
+++ b/src/gpu/ops/GrMSAAPathRenderer.h
@@ -22,7 +22,7 @@
     void onStencilPath(const StencilPathArgs&) override;
 
     bool internalDrawPath(GrRenderTargetContext*,
-                          const GrPaint&,
+                          GrPaint&&,
                           GrAAType,
                           const GrUserStencilSettings&,
                           const GrClip&,
diff --git a/src/gpu/ops/GrPLSPathRenderer.cpp b/src/gpu/ops/GrPLSPathRenderer.cpp
index 0e70634..545d12b 100644
--- a/src/gpu/ops/GrPLSPathRenderer.cpp
+++ b/src/gpu/ops/GrPLSPathRenderer.cpp
@@ -926,9 +926,8 @@
     SkPath path;
     args.fShape->asPath(&path);
 
-    std::unique_ptr<GrDrawOp> op =
-            PLSPathOp::Make(args.fPaint->getColor(), path, *args.fViewMatrix);
-    GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fAAType);
+    std::unique_ptr<GrDrawOp> op = PLSPathOp::Make(args.fPaint.getColor(), path, *args.fViewMatrix);
+    GrPipelineBuilder pipelineBuilder(std::move(args.fPaint), args.fAAType);
     pipelineBuilder.setUserStencil(args.fUserStencilSettings);
 
     args.fRenderTargetContext->addDrawOp(pipelineBuilder, *args.fClip, std::move(op));
diff --git a/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp b/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp
index 5a83e0e..77d8d23 100644
--- a/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp
+++ b/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp
@@ -113,7 +113,7 @@
         const SkMatrix& viewM = viewMatrix.hasPerspective() ? SkMatrix::I() : viewMatrix;
 
         std::unique_ptr<GrDrawOp> coverOp(GrRectOpFactory::MakeNonAAFill(
-                args.fPaint->getColor(), viewM, bounds, nullptr, &invert));
+                args.fPaint.getColor(), viewM, bounds, nullptr, &invert));
 
         // fake inverse with a stencil and cover
         args.fRenderTargetContext->priv().stencilPath(*args.fClip, args.fAAType, viewMatrix,
@@ -138,7 +138,7 @@
             if (GrAAType::kMixedSamples == coverAAType) {
                 coverAAType = GrAAType::kNone;
             }
-            GrPipelineBuilder pipelineBuilder(*args.fPaint, coverAAType);
+            GrPipelineBuilder pipelineBuilder(std::move(args.fPaint), coverAAType);
             pipelineBuilder.setUserStencil(&kInvertedCoverPass);
 
             args.fRenderTargetContext->addDrawOp(pipelineBuilder, *args.fClip, std::move(coverOp));
@@ -155,9 +155,9 @@
         );
 
         std::unique_ptr<GrDrawOp> op =
-                GrDrawPathOp::Make(viewMatrix, args.fPaint->getColor(), path.get());
+                GrDrawPathOp::Make(viewMatrix, args.fPaint.getColor(), path.get());
 
-        GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fAAType);
+        GrPipelineBuilder pipelineBuilder(std::move(args.fPaint), args.fAAType);
         pipelineBuilder.setUserStencil(&kCoverPass);
         args.fRenderTargetContext->addDrawOp(pipelineBuilder, *args.fClip, std::move(op));
     }
diff --git a/src/gpu/ops/GrTessellatingPathRenderer.cpp b/src/gpu/ops/GrTessellatingPathRenderer.cpp
index a40127a..bd474a2 100644
--- a/src/gpu/ops/GrTessellatingPathRenderer.cpp
+++ b/src/gpu/ops/GrTessellatingPathRenderer.cpp
@@ -354,12 +354,12 @@
     args.fClip->getConservativeBounds(args.fRenderTargetContext->width(),
                                       args.fRenderTargetContext->height(),
                                       &clipBoundsI);
-    std::unique_ptr<GrDrawOp> op = TessellatingPathOp::Make(args.fPaint->getColor(),
+    std::unique_ptr<GrDrawOp> op = TessellatingPathOp::Make(args.fPaint.getColor(),
                                                             *args.fShape,
                                                             *args.fViewMatrix,
                                                             clipBoundsI,
                                                             GrAAType::kCoverage == args.fAAType);
-    GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fAAType);
+    GrPipelineBuilder pipelineBuilder(std::move(args.fPaint), args.fAAType);
     pipelineBuilder.setUserStencil(args.fUserStencilSettings);
     args.fRenderTargetContext->addDrawOp(pipelineBuilder, *args.fClip, std::move(op));
     return true;
diff --git a/src/gpu/text/GrAtlasTextBlob.cpp b/src/gpu/text/GrAtlasTextBlob.cpp
index d4e4f5f..5e3b4bf 100644
--- a/src/gpu/text/GrAtlasTextBlob.cpp
+++ b/src/gpu/text/GrAtlasTextBlob.cpp
@@ -297,14 +297,14 @@
     return std::move(op);
 }
 
-inline
-void GrAtlasTextBlob::flushRun(GrRenderTargetContext* rtc, const GrPaint& grPaint,
-                               const GrClip& clip, int run, const SkMatrix& viewMatrix, SkScalar x,
-                               SkScalar y,
-                               const SkPaint& skPaint, const SkSurfaceProps& props,
-                               const GrDistanceFieldAdjustTable* distanceAdjustTable,
-                               GrAtlasGlyphCache* cache) {
-    for (int subRun = 0; subRun < fRuns[run].fSubRunInfo.count(); subRun++) {
+inline void GrAtlasTextBlob::flushRun(GrRenderTargetContext* rtc, GrPaint&& grPaint,
+                                      const GrClip& clip, int run, const SkMatrix& viewMatrix,
+                                      SkScalar x, SkScalar y, const SkPaint& skPaint,
+                                      const SkSurfaceProps& props,
+                                      const GrDistanceFieldAdjustTable* distanceAdjustTable,
+                                      GrAtlasGlyphCache* cache) {
+    int lastRun = fRuns[run].fSubRunInfo.count() - 1;
+    for (int subRun = 0; subRun <= lastRun; subRun++) {
         const Run::SubRunInfo& info = fRuns[run].fSubRunInfo[subRun];
         int glyphCount = info.glyphCount();
         if (0 == glyphCount) {
@@ -316,7 +316,8 @@
         std::unique_ptr<GrDrawOp> op(this->makeOp(info, glyphCount, run, subRun, viewMatrix, x, y,
                                                   color, skPaint, props, distanceAdjustTable,
                                                   rtc->isGammaCorrect(), cache));
-        GrPipelineBuilder pipelineBuilder(grPaint, GrAAType::kNone);
+        GrPipelineBuilder pipelineBuilder(GrPaint::MoveOrClone(grPaint, subRun < lastRun),
+                                          GrAAType::kNone);
 
         rtc->addDrawOp(pipelineBuilder, clip, std::move(op));
     }
@@ -403,18 +404,13 @@
     }
 }
 
-void GrAtlasTextBlob::flushCached(GrContext* context,
-                                  GrRenderTargetContext* rtc,
-                                  const SkTextBlob* blob,
-                                  const SkSurfaceProps& props,
+void GrAtlasTextBlob::flushCached(GrContext* context, GrRenderTargetContext* rtc,
+                                  const SkTextBlob* blob, const SkSurfaceProps& props,
                                   const GrDistanceFieldAdjustTable* distanceAdjustTable,
-                                  const SkPaint& skPaint,
-                                  const GrPaint& grPaint,
-                                  SkDrawFilter* drawFilter,
-                                  const GrClip& clip,
-                                  const SkMatrix& viewMatrix,
-                                  const SkIRect& clipBounds,
-                                  SkScalar x, SkScalar y) {
+                                  const SkPaint& skPaint, GrPaint&& grPaint,
+                                  SkDrawFilter* drawFilter, const GrClip& clip,
+                                  const SkMatrix& viewMatrix, const SkIRect& clipBounds, SkScalar x,
+                                  SkScalar y) {
     // We loop through the runs of the blob, flushing each.  If any run is too large, then we flush
     // it as paths
     SkTextBlobRunIterator it(blob);
@@ -424,27 +420,24 @@
                                   drawFilter, viewMatrix, clipBounds, x, y);
             continue;
         }
-        this->flushRun(rtc, grPaint, clip, run, viewMatrix, x, y, skPaint, props,
-                       distanceAdjustTable, context->getAtlasGlyphCache());
+        this->flushRun(rtc, GrPaint::MoveOrClone(grPaint, !it.done()), clip, run, viewMatrix, x, y,
+                       skPaint, props, distanceAdjustTable, context->getAtlasGlyphCache());
     }
 
     // Now flush big glyphs
     this->flushBigGlyphs(context, rtc, clip, skPaint, viewMatrix, x, y, clipBounds);
 }
 
-void GrAtlasTextBlob::flushThrowaway(GrContext* context,
-                                     GrRenderTargetContext* rtc,
+void GrAtlasTextBlob::flushThrowaway(GrContext* context, GrRenderTargetContext* rtc,
                                      const SkSurfaceProps& props,
                                      const GrDistanceFieldAdjustTable* distanceAdjustTable,
-                                     const SkPaint& skPaint,
-                                     const GrPaint& grPaint,
-                                     const GrClip& clip,
-                                     const SkMatrix& viewMatrix,
-                                     const SkIRect& clipBounds,
+                                     const SkPaint& skPaint, GrPaint&& grPaint, const GrClip& clip,
+                                     const SkMatrix& viewMatrix, const SkIRect& clipBounds,
                                      SkScalar x, SkScalar y) {
     for (int run = 0; run < fRunCount; run++) {
-        this->flushRun(rtc, grPaint, clip, run, viewMatrix, x, y, skPaint, props,
-                       distanceAdjustTable, context->getAtlasGlyphCache());
+        this->flushRun(rtc, GrPaint::MoveOrClone(grPaint, run + 1 != fRunCount), clip, run,
+                       viewMatrix, x, y, skPaint, props, distanceAdjustTable,
+                       context->getAtlasGlyphCache());
     }
 
     // Now flush big glyphs
diff --git a/src/gpu/text/GrAtlasTextBlob.h b/src/gpu/text/GrAtlasTextBlob.h
index 340b52a..f4e149f 100644
--- a/src/gpu/text/GrAtlasTextBlob.h
+++ b/src/gpu/text/GrAtlasTextBlob.h
@@ -181,30 +181,18 @@
                         const SkMatrix& viewMatrix, SkScalar x, SkScalar y);
 
     // flush a GrAtlasTextBlob associated with a SkTextBlob
-    void flushCached(GrContext* context,
-                     GrRenderTargetContext* rtc,
-                     const SkTextBlob* blob,
+    void flushCached(GrContext* context, GrRenderTargetContext* rtc, const SkTextBlob* blob,
                      const SkSurfaceProps& props,
-                     const GrDistanceFieldAdjustTable* distanceAdjustTable,
-                     const SkPaint& skPaint,
-                     const GrPaint& grPaint,
-                     SkDrawFilter* drawFilter,
-                     const GrClip& clip,
-                     const SkMatrix& viewMatrix,
-                     const SkIRect& clipBounds,
-                     SkScalar x, SkScalar y);
+                     const GrDistanceFieldAdjustTable* distanceAdjustTable, const SkPaint& skPaint,
+                     GrPaint&& grPaint, SkDrawFilter* drawFilter, const GrClip& clip,
+                     const SkMatrix& viewMatrix, const SkIRect& clipBounds, SkScalar x, SkScalar y);
 
     // flush a throwaway GrAtlasTextBlob *not* associated with an SkTextBlob
-    void flushThrowaway(GrContext* context,
-                        GrRenderTargetContext* rtc,
-                        const SkSurfaceProps& props,
+    void flushThrowaway(GrContext* context, GrRenderTargetContext* rtc, const SkSurfaceProps& props,
                         const GrDistanceFieldAdjustTable* distanceAdjustTable,
-                        const SkPaint& skPaint,
-                        const GrPaint& grPaint,
-                        const GrClip& clip,
-                        const SkMatrix& viewMatrix,
-                        const SkIRect& clipBounds,
-                        SkScalar x, SkScalar y);
+                        const SkPaint& skPaint, GrPaint&& grPaint, const GrClip& clip,
+                        const SkMatrix& viewMatrix, const SkIRect& clipBounds, SkScalar x,
+                        SkScalar y);
 
     void computeSubRunBounds(SkRect* outBounds, int runIndex, int subRunIndex,
                              const SkMatrix& viewMatrix, SkScalar x, SkScalar y) {
@@ -295,9 +283,9 @@
     void appendLargeGlyph(GrGlyph* glyph, SkGlyphCache* cache, const SkGlyph& skGlyph,
                           SkScalar x, SkScalar y, SkScalar scale, bool treatAsBMP);
 
-    inline void flushRun(GrRenderTargetContext* rtc, const GrPaint&, const GrClip&,
-                         int run, const SkMatrix& viewMatrix, SkScalar x, SkScalar y,
-                         const SkPaint& skPaint, const SkSurfaceProps& props,
+    inline void flushRun(GrRenderTargetContext* rtc, GrPaint&&, const GrClip&, int run,
+                         const SkMatrix& viewMatrix, SkScalar x, SkScalar y, const SkPaint& skPaint,
+                         const SkSurfaceProps& props,
                          const GrDistanceFieldAdjustTable* distanceAdjustTable,
                          GrAtlasGlyphCache* cache);
 
diff --git a/src/gpu/text/GrAtlasTextContext.cpp b/src/gpu/text/GrAtlasTextContext.cpp
index 3c155e3..1d8571c 100644
--- a/src/gpu/text/GrAtlasTextContext.cpp
+++ b/src/gpu/text/GrAtlasTextContext.cpp
@@ -168,7 +168,7 @@
     }
 
     cacheBlob->flushCached(context, rtc, blob, props, fDistanceAdjustTable.get(), skPaint,
-                           grPaint, drawFilter, clip, viewMatrix, clipBounds, x, y);
+                           std::move(grPaint), drawFilter, clip, viewMatrix, clipBounds, x, y);
 }
 
 void GrAtlasTextContext::RegenerateTextBlob(GrAtlasTextBlob* cacheBlob,
@@ -312,14 +312,11 @@
     return blob;
 }
 
-void GrAtlasTextContext::drawText(GrContext* context,
-                                  GrRenderTargetContext* rtc,
-                                  const GrClip& clip,
-                                  const GrPaint& paint, const SkPaint& skPaint,
-                                  const SkMatrix& viewMatrix,
-                                  const SkSurfaceProps& props,
-                                  const char text[], size_t byteLength,
-                                  SkScalar x, SkScalar y, const SkIRect& regionClipBounds) {
+void GrAtlasTextContext::drawText(GrContext* context, GrRenderTargetContext* rtc,
+                                  const GrClip& clip, GrPaint&& paint, const SkPaint& skPaint,
+                                  const SkMatrix& viewMatrix, const SkSurfaceProps& props,
+                                  const char text[], size_t byteLength, SkScalar x, SkScalar y,
+                                  const SkIRect& regionClipBounds) {
     if (context->abandoned()) {
         return;
     } else if (this->canDraw(skPaint, viewMatrix, props, *context->caps()->shaderCaps())) {
@@ -330,8 +327,8 @@
                                ComputeScalerContextFlags(rtc),
                                viewMatrix, props,
                                text, byteLength, x, y));
-        blob->flushThrowaway(context, rtc, props, fDistanceAdjustTable.get(), skPaint, paint,
-                             clip, viewMatrix, regionClipBounds, x, y);
+        blob->flushThrowaway(context, rtc, props, fDistanceAdjustTable.get(), skPaint,
+                             std::move(paint), clip, viewMatrix, regionClipBounds, x, y);
         return;
     }
 
@@ -340,15 +337,12 @@
                                 regionClipBounds);
 }
 
-void GrAtlasTextContext::drawPosText(GrContext* context,
-                                     GrRenderTargetContext* rtc,
-                                     const GrClip& clip,
-                                     const GrPaint& paint, const SkPaint& skPaint,
-                                     const SkMatrix& viewMatrix,
-                                     const SkSurfaceProps& props,
-                                     const char text[], size_t byteLength,
-                                     const SkScalar pos[], int scalarsPerPosition,
-                                     const SkPoint& offset, const SkIRect& regionClipBounds) {
+void GrAtlasTextContext::drawPosText(GrContext* context, GrRenderTargetContext* rtc,
+                                     const GrClip& clip, GrPaint&& paint, const SkPaint& skPaint,
+                                     const SkMatrix& viewMatrix, const SkSurfaceProps& props,
+                                     const char text[], size_t byteLength, const SkScalar pos[],
+                                     int scalarsPerPosition, const SkPoint& offset,
+                                     const SkIRect& regionClipBounds) {
     if (context->abandoned()) {
         return;
     } else if (this->canDraw(skPaint, viewMatrix, props, *context->caps()->shaderCaps())) {
@@ -362,8 +356,9 @@
                                   text, byteLength,
                                   pos, scalarsPerPosition,
                                   offset));
-        blob->flushThrowaway(context, rtc, props, fDistanceAdjustTable.get(), skPaint, paint,
-                             clip, viewMatrix, regionClipBounds, offset.fX, offset.fY);
+        blob->flushThrowaway(context, rtc, props, fDistanceAdjustTable.get(), skPaint,
+                             std::move(paint), clip, viewMatrix, regionClipBounds, offset.fX,
+                             offset.fY);
         return;
     }
 
diff --git a/src/gpu/text/GrAtlasTextContext.h b/src/gpu/text/GrAtlasTextContext.h
index 0417935..27560d4 100644
--- a/src/gpu/text/GrAtlasTextContext.h
+++ b/src/gpu/text/GrAtlasTextContext.h
@@ -32,14 +32,12 @@
 
     bool canDraw(const SkPaint&, const SkMatrix& viewMatrix, const SkSurfaceProps&,
                  const GrShaderCaps&);
-    void drawText(GrContext*, GrRenderTargetContext*, const GrClip&, const GrPaint&, const SkPaint&,
+    void drawText(GrContext*, GrRenderTargetContext*, const GrClip&, GrPaint&&, const SkPaint&,
                   const SkMatrix& viewMatrix, const SkSurfaceProps&, const char text[],
-                  size_t byteLength, SkScalar x, SkScalar y,
-                  const SkIRect& regionClipBounds);
-    void drawPosText(GrContext*, GrRenderTargetContext*, const GrClip&, const GrPaint&,
-                     const SkPaint&, const SkMatrix& viewMatrix, const SkSurfaceProps&,
-                     const char text[], size_t byteLength,
-                     const SkScalar pos[], int scalarsPerPosition,
+                  size_t byteLength, SkScalar x, SkScalar y, const SkIRect& regionClipBounds);
+    void drawPosText(GrContext*, GrRenderTargetContext*, const GrClip&, GrPaint&&, const SkPaint&,
+                     const SkMatrix& viewMatrix, const SkSurfaceProps&, const char text[],
+                     size_t byteLength, const SkScalar pos[], int scalarsPerPosition,
                      const SkPoint& offset, const SkIRect& regionClipBounds);
     void drawTextBlob(GrContext*, GrRenderTargetContext*, const GrClip&, const SkPaint&,
                       const SkMatrix& viewMatrix, const SkSurfaceProps&, const SkTextBlob*,
diff --git a/src/gpu/text/GrStencilAndCoverTextContext.cpp b/src/gpu/text/GrStencilAndCoverTextContext.cpp
index e58b082..7440223 100644
--- a/src/gpu/text/GrStencilAndCoverTextContext.cpp
+++ b/src/gpu/text/GrStencilAndCoverTextContext.cpp
@@ -69,25 +69,25 @@
 }
 
 void GrStencilAndCoverTextContext::drawText(GrContext* context, GrRenderTargetContext* rtc,
-                                            const GrClip& clip, const GrPaint& paint,
+                                            const GrClip& clip, GrPaint&& paint,
                                             const SkPaint& skPaint, const SkMatrix& viewMatrix,
-                                            const SkSurfaceProps& props,
-                                            const char text[], size_t byteLength,
-                                            SkScalar x, SkScalar y, const SkIRect& clipBounds) {
+                                            const SkSurfaceProps& props, const char text[],
+                                            size_t byteLength, SkScalar x, SkScalar y,
+                                            const SkIRect& clipBounds) {
     if (context->abandoned()) {
         return;
     } else if (this->canDraw(skPaint, viewMatrix)) {
         if (skPaint.getTextSize() > 0) {
             TextRun run(skPaint);
             run.setText(text, byteLength, x, y);
-            run.draw(context, rtc, paint, clip, viewMatrix, props, 0, 0,
-                     clipBounds, fFallbackTextContext, skPaint);
+            run.draw(context, rtc, std::move(paint), clip, viewMatrix, props, 0, 0, clipBounds,
+                     fFallbackTextContext, skPaint);
         }
         return;
     } else if (fFallbackTextContext->canDraw(skPaint, viewMatrix, props,
                                              *context->caps()->shaderCaps())) {
-        fFallbackTextContext->drawText(context, rtc, clip, paint, skPaint, viewMatrix, props, text,
-                                       byteLength, x, y, clipBounds);
+        fFallbackTextContext->drawText(context, rtc, clip, std::move(paint), skPaint, viewMatrix,
+                                       props, text, byteLength, x, y, clipBounds);
         return;
     }
 
@@ -97,16 +97,11 @@
 }
 
 void GrStencilAndCoverTextContext::drawPosText(GrContext* context, GrRenderTargetContext* rtc,
-                                               const GrClip& clip,
-                                               const GrPaint& paint,
-                                               const SkPaint& skPaint,
-                                               const SkMatrix& viewMatrix,
-                                               const SkSurfaceProps& props,
-                                               const char text[],
-                                               size_t byteLength,
-                                               const SkScalar pos[],
-                                               int scalarsPerPosition,
-                                               const SkPoint& offset,
+                                               const GrClip& clip, GrPaint&& paint,
+                                               const SkPaint& skPaint, const SkMatrix& viewMatrix,
+                                               const SkSurfaceProps& props, const char text[],
+                                               size_t byteLength, const SkScalar pos[],
+                                               int scalarsPerPosition, const SkPoint& offset,
                                                const SkIRect& clipBounds) {
     if (context->abandoned()) {
         return;
@@ -114,15 +109,15 @@
         if (skPaint.getTextSize() > 0) {
             TextRun run(skPaint);
             run.setPosText(text, byteLength, pos, scalarsPerPosition, offset);
-            run.draw(context, rtc, paint, clip, viewMatrix, props, 0, 0,
-                     clipBounds, fFallbackTextContext, skPaint);
+            run.draw(context, rtc, std::move(paint), clip, viewMatrix, props, 0, 0, clipBounds,
+                     fFallbackTextContext, skPaint);
         }
         return;
     } else if (fFallbackTextContext->canDraw(skPaint, viewMatrix, props,
                                              *context->caps()->shaderCaps())) {
-        fFallbackTextContext->drawPosText(context, rtc, clip, paint, skPaint, viewMatrix, props,
-                                          text, byteLength, pos,
-                                          scalarsPerPosition, offset, clipBounds);
+        fFallbackTextContext->drawPosText(context, rtc, clip, std::move(paint), skPaint, viewMatrix,
+                                          props, text, byteLength, pos, scalarsPerPosition, offset,
+                                          clipBounds);
         return;
     }
 
@@ -167,20 +162,19 @@
 
         switch (it.positioning()) {
             case SkTextBlob::kDefault_Positioning:
-                this->drawText(context, rtc, clip, grPaint, runPaint, viewMatrix, props,
-                               (const char *)it.glyphs(),
-                               textLen, x + offset.x(), y + offset.y(), clipBounds);
+                this->drawText(context, rtc, clip, std::move(grPaint), runPaint, viewMatrix, props,
+                               (const char*)it.glyphs(), textLen, x + offset.x(), y + offset.y(),
+                               clipBounds);
                 break;
             case SkTextBlob::kHorizontal_Positioning:
-                this->drawPosText(context, rtc, clip, grPaint, runPaint, viewMatrix, props,
-                                  (const char*)it.glyphs(),
-                                  textLen, it.pos(), 1, SkPoint::Make(x, y + offset.y()),
-                                  clipBounds);
+                this->drawPosText(context, rtc, clip, std::move(grPaint), runPaint, viewMatrix,
+                                  props, (const char*)it.glyphs(), textLen, it.pos(), 1,
+                                  SkPoint::Make(x, y + offset.y()), clipBounds);
                 break;
             case SkTextBlob::kFull_Positioning:
-                this->drawPosText(context, rtc, clip, grPaint, runPaint, viewMatrix, props,
-                                  (const char*)it.glyphs(),
-                                  textLen, it.pos(), 2, SkPoint::Make(x, y), clipBounds);
+                this->drawPosText(context, rtc, clip, std::move(grPaint), runPaint, viewMatrix,
+                                  props, (const char*)it.glyphs(), textLen, it.pos(), 2,
+                                  SkPoint::Make(x, y), clipBounds);
                 break;
         }
 
@@ -223,9 +217,10 @@
     const TextBlob& blob = this->findOrCreateTextBlob(skBlob, skPaint);
 
     TextBlob::Iter iter(blob);
-    for (TextRun* run = iter.get(); run; run = iter.next()) {
-        run->draw(context, rtc, paint, clip, viewMatrix, props,  x, y, clipBounds,
-                  fFallbackTextContext, skPaint);
+    for (TextRun *run = iter.get(), *nextRun; run; run = nextRun) {
+        nextRun = iter.next();
+        run->draw(context, rtc, GrPaint::MoveOrClone(paint, nextRun), clip, viewMatrix, props, x, y,
+                  clipBounds, fFallbackTextContext, skPaint);
         run->releaseGlyphCache();
     }
 }
@@ -593,16 +588,11 @@
     }
 }
 
-void GrStencilAndCoverTextContext::TextRun::draw(GrContext* ctx,
-                                                 GrRenderTargetContext* renderTargetContext,
-                                                 const GrPaint& grPaint,
-                                                 const GrClip& clip,
-                                                 const SkMatrix& viewMatrix,
-                                                 const SkSurfaceProps& props,
-                                                 SkScalar x, SkScalar y,
-                                                 const SkIRect& clipBounds,
-                                                 GrAtlasTextContext* fallbackTextContext,
-                                                 const SkPaint& originalSkPaint) const {
+void GrStencilAndCoverTextContext::TextRun::draw(
+        GrContext* ctx, GrRenderTargetContext* renderTargetContext, GrPaint&& grPaint,
+        const GrClip& clip, const SkMatrix& viewMatrix, const SkSurfaceProps& props, SkScalar x,
+        SkScalar y, const SkIRect& clipBounds, GrAtlasTextContext* fallbackTextContext,
+        const SkPaint& originalSkPaint) const {
     GrAA runAA = this->isAntiAlias();
     SkASSERT(fInstanceData);
     SkASSERT(renderTargetContext->isStencilBufferMultisampled() || GrAA::kNo == runAA);
@@ -647,7 +637,7 @@
                 aaType = GrAAType::kMixedSamples;
             }
         }
-        GrPipelineBuilder pipelineBuilder(grPaint, aaType);
+        GrPipelineBuilder pipelineBuilder(std::move(grPaint), aaType);
         pipelineBuilder.setUserStencil(&kCoverPass);
 
         renderTargetContext->addDrawOp(pipelineBuilder, clip, std::move(op));
diff --git a/src/gpu/text/GrStencilAndCoverTextContext.h b/src/gpu/text/GrStencilAndCoverTextContext.h
index 719d338..0597225 100644
--- a/src/gpu/text/GrStencilAndCoverTextContext.h
+++ b/src/gpu/text/GrStencilAndCoverTextContext.h
@@ -31,16 +31,12 @@
 public:
     static GrStencilAndCoverTextContext* Create(GrAtlasTextContext* fallbackTextContext);
 
-    void drawText(GrContext*, GrRenderTargetContext* rtc,
-                  const GrClip&,  const GrPaint&, const SkPaint&,
+    void drawText(GrContext*, GrRenderTargetContext* rtc, const GrClip&, GrPaint&&, const SkPaint&,
                   const SkMatrix& viewMatrix, const SkSurfaceProps&, const char text[],
-                  size_t byteLength, SkScalar x,
-                  SkScalar y, const SkIRect& clipBounds);
-    void drawPosText(GrContext*, GrRenderTargetContext*,
-                     const GrClip&, const GrPaint&, const SkPaint&,
-                     const SkMatrix& viewMatrix, const SkSurfaceProps&,
-                     const char text[], size_t byteLength,
-                     const SkScalar pos[], int scalarsPerPosition,
+                  size_t byteLength, SkScalar x, SkScalar y, const SkIRect& clipBounds);
+    void drawPosText(GrContext*, GrRenderTargetContext*, const GrClip&, GrPaint&&, const SkPaint&,
+                     const SkMatrix& viewMatrix, const SkSurfaceProps&, const char text[],
+                     size_t byteLength, const SkScalar pos[], int scalarsPerPosition,
                      const SkPoint& offset, const SkIRect& clipBounds);
     void drawTextBlob(GrContext*, GrRenderTargetContext*, const GrClip&, const SkPaint&,
                       const SkMatrix& viewMatrix, const SkSurfaceProps&, const SkTextBlob*,
@@ -79,9 +75,8 @@
         void setPosText(const char text[], size_t byteLength, const SkScalar pos[],
                         int scalarsPerPosition, const SkPoint& offset);
 
-        void draw(GrContext*, GrRenderTargetContext*, const GrPaint&, const GrClip&,
-                  const SkMatrix&, const SkSurfaceProps&,
-                  SkScalar x, SkScalar y, const SkIRect& clipBounds,
+        void draw(GrContext*, GrRenderTargetContext*, GrPaint&&, const GrClip&, const SkMatrix&,
+                  const SkSurfaceProps&, SkScalar x, SkScalar y, const SkIRect& clipBounds,
                   GrAtlasTextContext* fallbackTextContext, const SkPaint& originalSkPaint) const;
 
         void releaseGlyphCache() const;
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index cdbdd7c..2912f00 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -298,7 +298,7 @@
 
     const SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
 
-    renderTargetContext->drawRect(GrNoClip(), paint, GrAA::kNo, SkMatrix::I(), rect);
+    renderTargetContext->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(), rect);
 
     if (!renderTargetContext->accessRenderTarget()) {
         return nullptr;
diff --git a/tests/DFPathRendererTest.cpp b/tests/DFPathRendererTest.cpp
index ca437da..7fb8c8a 100644
--- a/tests/DFPathRendererTest.cpp
+++ b/tests/DFPathRendererTest.cpp
@@ -45,16 +45,15 @@
     paint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
 
     GrNoClip noClip;
-    GrPathRenderer::DrawPathArgs args;
-    args.fPaint = &paint;
-    args.fUserStencilSettings = &GrUserStencilSettings::kUnused;
-    args.fRenderTargetContext = renderTargetContext;
-    args.fClip = &noClip;
-    args.fResourceProvider = rp;
-    args.fViewMatrix = &matrix;
-    args.fShape = &shape;
-    args.fAAType = GrAAType::kCoverage;
-    args.fGammaCorrect = false;
+    GrPathRenderer::DrawPathArgs args{rp,
+                                      std::move(paint),
+                                      &GrUserStencilSettings::kUnused,
+                                      renderTargetContext,
+                                      &noClip,
+                                      &matrix,
+                                      &shape,
+                                      GrAAType::kCoverage,
+                                      false};
     pr->drawPath(args);
 }
 
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
index 94abd1c..ce79d0e 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -339,8 +339,8 @@
         static constexpr GrAAType kAATypes[] = {GrAAType::kNone, GrAAType::kCoverage};
         GrAAType aaType = kAATypes[random.nextULessThan(SK_ARRAY_COUNT(kAATypes))];
 
-        renderTargetContext->priv().testingOnly_addDrawOp(grPaint, aaType, std::move(op), uss,
-                                                          snapToCenters);
+        renderTargetContext->priv().testingOnly_addDrawOp(std::move(grPaint), aaType, std::move(op),
+                                                          uss, snapToCenters);
     }
     // Flush everything, test passes if flush is successful(ie, no asserts are hit, no crashes)
     drawingManager->flush();
@@ -374,7 +374,7 @@
                 BlockInputFragmentProcessor::Make(std::move(fp)));
             grPaint.addColorFragmentProcessor(std::move(blockFP));
 
-            renderTargetContext->priv().testingOnly_addDrawOp(grPaint, GrAAType::kNone,
+            renderTargetContext->priv().testingOnly_addDrawOp(std::move(grPaint), GrAAType::kNone,
                                                               std::move(op));
             drawingManager->flush();
         }
diff --git a/tests/ImageStorageTest.cpp b/tests/ImageStorageTest.cpp
index 835aec5..8ffb82d 100644
--- a/tests/ImageStorageTest.cpp
+++ b/tests/ImageStorageTest.cpp
@@ -139,7 +139,7 @@
                 GrPaint paint;
                 paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
                 paint.addColorFragmentProcessor(TestFP::Make(imageStorageTexture, mm, restrict));
-                rtContext->drawPaint(GrNoClip(), paint, SkMatrix::I());
+                rtContext->drawPaint(GrNoClip(), std::move(paint), SkMatrix::I());
                 std::unique_ptr<uint32_t[]> readData(new uint32_t[kS * kS]);
                 SkImageInfo info = SkImageInfo::Make(kS, kS, kRGBA_8888_SkColorType,
                                                      kPremul_SkAlphaType);
diff --git a/tests/IntTextureTest.cpp b/tests/IntTextureTest.cpp
index ee0b0a8..a3e17bf 100644
--- a/tests/IntTextureTest.cpp
+++ b/tests/IntTextureTest.cpp
@@ -219,7 +219,7 @@
         GrPaint paint;
         paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
         paint.addColorFragmentProcessor(fp);
-        rtContext->drawPaint(GrNoClip(), paint, SkMatrix::I());
+        rtContext->drawPaint(GrNoClip(), std::move(paint), SkMatrix::I());
         SkImageInfo readInfo = SkImageInfo::Make(kS, kS, kRGBA_8888_SkColorType,
                                                  kPremul_SkAlphaType);
         rtContext->readPixels(readInfo, actualData.get(), 0, 0, 0);
diff --git a/tests/PrimitiveProcessorTest.cpp b/tests/PrimitiveProcessorTest.cpp
index c4c4a9b..a0b3a35 100644
--- a/tests/PrimitiveProcessorTest.cpp
+++ b/tests/PrimitiveProcessorTest.cpp
@@ -125,7 +125,7 @@
 #endif
     GrPaint grPaint;
     // This one should succeed.
-    renderTargetContext->priv().testingOnly_addDrawOp(grPaint, GrAAType::kNone,
+    renderTargetContext->priv().testingOnly_addDrawOp(GrPaint(grPaint), GrAAType::kNone,
                                                       Op::Make(attribCnt));
     context->flush();
 #if GR_GPU_STATS
@@ -133,7 +133,7 @@
     REPORTER_ASSERT(reporter, context->getGpu()->stats()->numFailedDraws() == 0);
 #endif
     context->resetGpuStats();
-    renderTargetContext->priv().testingOnly_addDrawOp(grPaint, GrAAType::kNone,
+    renderTargetContext->priv().testingOnly_addDrawOp(std::move(grPaint), GrAAType::kNone,
                                                       Op::Make(attribCnt + 1));
     context->flush();
 #if GR_GPU_STATS
diff --git a/tests/ProcessorTest.cpp b/tests/ProcessorTest.cpp
index b6caccc..8b7f99b 100644
--- a/tests/ProcessorTest.cpp
+++ b/tests/ProcessorTest.cpp
@@ -163,7 +163,7 @@
                     fp = TestFP::Make(std::move(fp));
                 }
                 paint.addColorFragmentProcessor(std::move(fp));
-                renderTargetContext->priv().testingOnly_addDrawOp(paint, GrAAType::kNone,
+                renderTargetContext->priv().testingOnly_addDrawOp(std::move(paint), GrAAType::kNone,
                                                                   std::move(op));
             }
             int refCnt, readCnt, writeCnt;
diff --git a/tests/RectangleTextureTest.cpp b/tests/RectangleTextureTest.cpp
index 5871604..a0c5409 100644
--- a/tests/RectangleTextureTest.cpp
+++ b/tests/RectangleTextureTest.cpp
@@ -118,7 +118,7 @@
         GrPaint paint;
         paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
         paint.addColorFragmentProcessor(std::move(fp));
-        rtContext->drawPaint(GrNoClip(), paint, SkMatrix::I());
+        rtContext->drawPaint(GrNoClip(), std::move(paint), SkMatrix::I());
         test_read_pixels(reporter, context, rtContext->asTexture().get(), expectedPixelValues);
     }
 }
diff --git a/tests/SRGBMipMapTest.cpp b/tests/SRGBMipMapTest.cpp
index afe8167..79d8691 100644
--- a/tests/SRGBMipMapTest.cpp
+++ b/tests/SRGBMipMapTest.cpp
@@ -136,13 +136,13 @@
 
     // 1) Draw texture to S32 surface (should generate/use sRGB mips)
     paint.setGammaCorrect(true);
-    s32RenderTargetContext->drawRect(noClip, paint, GrAA::kNo, SkMatrix::I(), rect);
+    s32RenderTargetContext->drawRect(noClip, GrPaint(paint), GrAA::kNo, SkMatrix::I(), rect);
     read_and_check_pixels(reporter, s32RenderTargetContext->asTexture().get(), expectedSRGB, error,
                           "first render of sRGB");
 
     // 2) Draw texture to L32 surface (should generate/use linear mips)
     paint.setGammaCorrect(false);
-    l32RenderTargetContext->drawRect(noClip, paint, GrAA::kNo, SkMatrix::I(), rect);
+    l32RenderTargetContext->drawRect(noClip, GrPaint(paint), GrAA::kNo, SkMatrix::I(), rect);
 
     // Right now, this test only runs on GL (because Vulkan doesn't support legacy mip-mapping
     // skbug.com/5048). On GL, we may not have sRGB decode support. In that case, rendering sRGB
@@ -162,7 +162,7 @@
 
     // 3) Go back to sRGB
     paint.setGammaCorrect(true);
-    s32RenderTargetContext->drawRect(noClip, paint, GrAA::kNo, SkMatrix::I(), rect);
+    s32RenderTargetContext->drawRect(noClip, std::move(paint), GrAA::kNo, SkMatrix::I(), rect);
     read_and_check_pixels(reporter, s32RenderTargetContext->asTexture().get(), expectedSRGB, error,
                           "re-render as sRGB");
 }
diff --git a/tests/TessellatingPathRendererTests.cpp b/tests/TessellatingPathRendererTests.cpp
index fc93772..b03db18 100644
--- a/tests/TessellatingPathRendererTests.cpp
+++ b/tests/TessellatingPathRendererTests.cpp
@@ -258,16 +258,16 @@
 
     GrNoClip noClip;
     GrStyle style(SkStrokeRec::kFill_InitStyle);
-    GrPathRenderer::DrawPathArgs args;
-    args.fPaint = &paint;
-    args.fUserStencilSettings = &GrUserStencilSettings::kUnused;
-    args.fRenderTargetContext = renderTargetContext;
-    args.fClip = &noClip;
-    args.fResourceProvider = rp;
-    args.fViewMatrix = &SkMatrix::I();
     GrShape shape(path, style);
-    args.fShape = &shape;
-    args.fAAType = GrAAType::kNone;
+    GrPathRenderer::DrawPathArgs args{rp,
+                                      std::move(paint),
+                                      &GrUserStencilSettings::kUnused,
+                                      renderTargetContext,
+                                      &noClip,
+                                      &SkMatrix::I(),
+                                      &shape,
+                                      GrAAType::kNone,
+                                      false};
     tess.drawPath(args);
 }
 
diff --git a/tools/gpu/GrTest.cpp b/tools/gpu/GrTest.cpp
index 95ee6b8..b1c179b 100644
--- a/tools/gpu/GrTest.cpp
+++ b/tools/gpu/GrTest.cpp
@@ -241,7 +241,7 @@
     SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fRenderTargetContext->fSingleOwner);)
 #define RETURN_IF_ABANDONED        if (fRenderTargetContext->fDrawingManager->wasAbandoned()) { return; }
 
-void GrRenderTargetContextPriv::testingOnly_addDrawOp(const GrPaint& paint,
+void GrRenderTargetContextPriv::testingOnly_addDrawOp(GrPaint&& paint,
                                                       GrAAType aaType,
                                                       std::unique_ptr<GrDrawOp>
                                                               op,
@@ -253,7 +253,7 @@
     GR_AUDIT_TRAIL_AUTO_FRAME(fRenderTargetContext->fAuditTrail,
                               "GrRenderTargetContext::testingOnly_addDrawOp");
 
-    GrPipelineBuilder pipelineBuilder(paint, aaType);
+    GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
     if (uss) {
         pipelineBuilder.setUserStencil(uss);
     }