Stop creating GrODS for stencilPath commands.

Review URL: https://codereview.chromium.org/816513003
diff --git a/gyp/tools.gyp b/gyp/tools.gyp
index 3b1d2f5..1341666 100644
--- a/gyp/tools.gyp
+++ b/gyp/tools.gyp
@@ -1,4 +1,4 @@
-# GYP file to build various tools.
+    # GYP file to build various tools.
 #
 # To build on Linux:
 #  ./gyp_skia tools.gyp && make tools
diff --git a/include/gpu/GrTypesPriv.h b/include/gpu/GrTypesPriv.h
index d5227ae..b22f480 100644
--- a/include/gpu/GrTypesPriv.h
+++ b/include/gpu/GrTypesPriv.h
@@ -10,6 +10,7 @@
 
 #include "GrTypes.h"
 #include "SkTArray.h"
+#include "SkRect.h"
 
 /**
  * Types of shader-language-specific boxed variables we can create. (Currently only GrGLShaderVars,
@@ -240,4 +241,16 @@
     kRW_GrIOType
 };
 
+struct GrScissorState {
+    GrScissorState() : fEnabled(false) {}
+    void set(const SkIRect& rect) { fRect = rect; fEnabled = true; }
+    bool operator==(const GrScissorState& other) const {
+        return fEnabled == other.fEnabled &&
+                (false == fEnabled || fRect == other.fRect);
+    }
+    bool operator!=(const GrScissorState& other) const { return !(*this == other); }
+    bool    fEnabled;
+    SkIRect fRect;
+};
+
 #endif
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index d663c79..3bd458c 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -202,7 +202,7 @@
 bool GrClipMaskManager::setupClipping(GrDrawState* drawState,
                                       GrDrawState::AutoRestoreEffects* are,
                                       GrDrawState::AutoRestoreStencil* ars,
-                                      ScissorState* scissorState,
+                                      GrScissorState* scissorState,
                                       const GrClipData* clipDataIn,
                                       const SkRect* devBounds) {
     fCurrClipMaskType = kNone_ClipMaskType;
diff --git a/src/gpu/GrClipMaskManager.h b/src/gpu/GrClipMaskManager.h
index 3aec257..c17231e 100644
--- a/src/gpu/GrClipMaskManager.h
+++ b/src/gpu/GrClipMaskManager.h
@@ -41,21 +41,6 @@
         , fClipMode(kIgnoreClip_StencilClipMode) {
     }
 
-    // The state of the scissor is controlled by the clip manager, no one else should set
-    // Scissor state.  This should really be on Gpu itself.  We should revist this when GPU
-    // and drawtarget are separate
-    struct ScissorState {
-        ScissorState() : fEnabled(false) {}
-        void set(const SkIRect& rect) { fRect = rect; fEnabled = true; }
-        bool operator==(const ScissorState& other) const {
-            return fEnabled == other.fEnabled &&
-                    (false == fEnabled || fRect == other.fRect);
-        }
-        bool operator!=(const ScissorState& other) const { return !(*this == other); }
-        bool    fEnabled;
-        SkIRect fRect;
-    };
-
     /**
      * Creates a clip mask if necessary as a stencil buffer or alpha texture
      * and sets the GrGpu's scissor and stencil state. If the return is false
@@ -66,7 +51,7 @@
     bool setupClipping(GrDrawState*,
                        GrDrawState::AutoRestoreEffects*,
                        GrDrawState::AutoRestoreStencil*,
-                       ScissorState*,
+                       GrScissorState*,
                        const GrClipData* clipDataIn,
                        const SkRect* devBounds);
 
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index 96594b1..9ba9265 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -446,7 +446,7 @@
         this->checkDraw(*ds, gp, type, startVertex, startIndex, vertexCount, indexCount)) {
 
         // Setup clip
-        GrClipMaskManager::ScissorState scissorState;
+        GrScissorState scissorState;
         GrDrawState::AutoRestoreEffects are;
         GrDrawState::AutoRestoreStencil ars;
         if (!this->setupClip(devBounds, &are, &ars, ds, &scissorState)) {
@@ -489,7 +489,7 @@
     if (vertexCount > 0 && this->checkDraw(*ds, gp, type, startVertex, -1, vertexCount, -1)) {
 
         // Setup clip
-        GrClipMaskManager::ScissorState scissorState;
+        GrScissorState scissorState;
         GrDrawState::AutoRestoreEffects are;
         GrDrawState::AutoRestoreStencil ars;
         if (!this->setupClip(devBounds, &are, &ars, ds, &scissorState)) {
@@ -568,7 +568,7 @@
     SkASSERT(ds);
 
     // Setup clip
-    GrClipMaskManager::ScissorState scissorState;
+    GrScissorState scissorState;
     GrDrawState::AutoRestoreEffects are;
     GrDrawState::AutoRestoreStencil ars;
     if (!this->setupClip(NULL, &are, &ars, ds, &scissorState)) {
@@ -598,7 +598,7 @@
     viewM.mapRect(&devBounds);
 
     // Setup clip
-    GrClipMaskManager::ScissorState scissorState;
+    GrScissorState scissorState;
     GrDrawState::AutoRestoreEffects are;
     GrDrawState::AutoRestoreStencil ars;
     if (!this->setupClip(&devBounds, &are, &ars, ds, &scissorState)) {
@@ -637,7 +637,7 @@
     SkASSERT(ds);
 
     // Setup clip
-    GrClipMaskManager::ScissorState scissorState;
+    GrScissorState scissorState;
     GrDrawState::AutoRestoreEffects are;
     GrDrawState::AutoRestoreStencil ars;
 
@@ -748,7 +748,7 @@
     }
 
     // Setup clip
-    GrClipMaskManager::ScissorState scissorState;
+    GrScissorState scissorState;
     GrDrawState::AutoRestoreEffects are;
     GrDrawState::AutoRestoreStencil ars;
     if (!this->setupClip(devBounds, &are, &ars, ds, &scissorState)) {
@@ -1214,7 +1214,7 @@
                              GrDrawState::AutoRestoreEffects* are,
                              GrDrawState::AutoRestoreStencil* ars,
                              GrDrawState* ds,
-                             GrClipMaskManager::ScissorState* scissorState) {
+                             GrScissorState* scissorState) {
     return fClipMaskManager.setupClipping(ds,
                                           are,
                                           ars,
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index 26de867..64cbc87 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -702,7 +702,7 @@
     virtual void onDraw(const GrDrawState&,
                         const GrGeometryProcessor*,
                         const DrawInfo&,
-                        const GrClipMaskManager::ScissorState&,
+                        const GrScissorState&,
                         const GrDeviceCoordTexture* dstCopy) = 0;
     // TODO copy in order drawbuffer onDrawRect to here
     virtual void onDrawRect(GrDrawState*,
@@ -714,12 +714,12 @@
     virtual void onStencilPath(const GrDrawState&,
                                const GrPathProcessor*,
                                const GrPath*,
-                               const GrClipMaskManager::ScissorState&,
+                               const GrScissorState&,
                                const GrStencilSettings&) = 0;
     virtual void onDrawPath(const GrDrawState&,
                             const GrPathProcessor*,
                             const GrPath*,
-                            const GrClipMaskManager::ScissorState&,
+                            const GrScissorState&,
                             const GrStencilSettings&,
                             const GrDeviceCoordTexture* dstCopy) = 0;
     virtual void onDrawPaths(const GrDrawState&,
@@ -730,7 +730,7 @@
                              const float transformValues[],
                              PathTransformType,
                              int count,
-                             const GrClipMaskManager::ScissorState&,
+                             const GrScissorState&,
                              const GrStencilSettings&,
                              const GrDeviceCoordTexture*) = 0;
 
@@ -790,7 +790,7 @@
                            GrDrawState::AutoRestoreEffects* are,
                            GrDrawState::AutoRestoreStencil* ars,
                            GrDrawState*,
-                           GrClipMaskManager::ScissorState* scissorState) = 0;
+                           GrScissorState* scissorState) = 0;
 
     enum {
         kPreallocGeoSrcStateStackCnt = 4,
@@ -850,7 +850,7 @@
                            GrDrawState::AutoRestoreEffects* are,
                            GrDrawState::AutoRestoreStencil* ars,
                            GrDrawState*,
-                           GrClipMaskManager::ScissorState* scissorState) SK_OVERRIDE;
+                           GrScissorState* scissorState) SK_OVERRIDE;
 
     typedef GrDrawTarget INHERITED;
 };
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index 297f2bf..de9e26f 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -280,11 +280,9 @@
     this->onDraw(ds, info);
 }
 
-void GrGpu::stencilPath(const GrOptDrawState& ds,
-                        const GrPath* path,
-                        const GrStencilSettings& stencilSettings) {
+void GrGpu::stencilPath(const GrPath* path, const StencilPathState& state) {
     this->handleDirtyContext();
-    this->onStencilPath(ds, path, stencilSettings);
+    this->onStencilPath(path, state);
 }
 
 void GrGpu::drawPath(const GrOptDrawState& ds,
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 611b7a5..a657d17 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -303,7 +303,6 @@
         kDrawPoints_DrawType,
         kDrawLines_DrawType,
         kDrawTriangles_DrawType,
-        kStencilPath_DrawType,
         kDrawPath_DrawType,
         kDrawPaths_DrawType,
     };
@@ -358,7 +357,18 @@
                              const SkIPoint& dstPoint) = 0;
 
     void draw(const GrOptDrawState&, const GrDrawTarget::DrawInfo&);
-    void stencilPath(const GrOptDrawState&, const GrPath*, const GrStencilSettings&);
+
+    /** None of these params are optional, pointers used just to avoid making copies. */
+    struct StencilPathState {
+        bool fUseHWAA;
+        GrRenderTarget* fRenderTarget;
+        const SkMatrix* fViewMatrix;
+        const GrStencilSettings* fStencil;
+        const GrScissorState* fScissor;
+    };
+
+    void stencilPath(const GrPath*, const StencilPathState&);
+
     void drawPath(const GrOptDrawState&, const GrPath*, const GrStencilSettings&);
     void drawPaths(const GrOptDrawState&,
                    const GrPathRange*,
@@ -436,7 +446,8 @@
 
     // overridden by backend-specific derived class to perform the draw call.
     virtual void onDraw(const GrOptDrawState&, const GrDrawTarget::DrawInfo&) = 0;
-    virtual void onStencilPath(const GrOptDrawState&, const GrPath*, const GrStencilSettings&) = 0;
+    virtual void onStencilPath(const GrPath*, const StencilPathState&) = 0;
+
     virtual void onDrawPath(const GrOptDrawState&, const GrPath*, const GrStencilSettings&) = 0;
     virtual void onDrawPaths(const GrOptDrawState&,
                              const GrPathRange*,
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index 83e0926..dc074b7 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -222,7 +222,7 @@
 void GrInOrderDrawBuffer::onDraw(const GrDrawState& ds,
                                  const GrGeometryProcessor* gp,
                                  const DrawInfo& info,
-                                 const ScissorState& scissorState,
+                                 const GrScissorState& scissorState,
                                  const GrDeviceCoordTexture* dstCopy) {
     SkASSERT(info.vertexBuffer() && (!info.isIndexed() || info.indexBuffer()));
 
@@ -250,22 +250,21 @@
 void GrInOrderDrawBuffer::onStencilPath(const GrDrawState& ds,
                                         const GrPathProcessor* pathProc,
                                         const GrPath* path,
-                                        const GrClipMaskManager::ScissorState& scissorState,
+                                        const GrScissorState& scissorState,
                                         const GrStencilSettings& stencilSettings) {
-    // Only compare the subset of GrDrawState relevant to path stenciling?
-    if (!this->recordStateAndShouldDraw(ds, NULL, pathProc, GrGpu::kStencilPath_DrawType,
-                                        scissorState, NULL)) {
-        return;
-    }
-    StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, (path));
-    sp->fStencilSettings = stencilSettings;
+    StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath,
+                                               (path, ds.getRenderTarget()));
+    sp->fScissor = scissorState;
+    sp->fUseHWAA = ds.isHWAntialias();
+    sp->fViewMatrix = ds.getViewMatrix();
+    sp->fStencil = stencilSettings;
     this->recordTraceMarkersIfNecessary();
 }
 
 void GrInOrderDrawBuffer::onDrawPath(const GrDrawState& ds,
                                      const GrPathProcessor* pathProc,
                                      const GrPath* path,
-                                     const GrClipMaskManager::ScissorState& scissorState,
+                                     const GrScissorState& scissorState,
                                      const GrStencilSettings& stencilSettings,
                                      const GrDeviceCoordTexture* dstCopy) {
     // TODO: Only compare the subset of GrDrawState relevant to path covering?
@@ -286,7 +285,7 @@
                                       const float transformValues[],
                                       PathTransformType transformType,
                                       int count,
-                                      const GrClipMaskManager::ScissorState& scissorState,
+                                      const GrScissorState& scissorState,
                                       const GrStencilSettings& stencilSettings,
                                       const GrDeviceCoordTexture* dstCopy) {
     SkASSERT(pathRange);
@@ -435,10 +434,15 @@
     buf->getGpu()->draw(*optState, fInfo);
 }
 
-void GrInOrderDrawBuffer::StencilPath::execute(GrInOrderDrawBuffer* buf,
-                                               const GrOptDrawState* optState) {
-    SkASSERT(optState);
-    buf->getGpu()->stencilPath(*optState, this->path(), fStencilSettings);
+void GrInOrderDrawBuffer::StencilPath::execute(GrInOrderDrawBuffer* buf, const GrOptDrawState*) {
+    GrGpu::StencilPathState state;
+    state.fRenderTarget = fRenderTarget.get();
+    state.fScissor = &fScissor;
+    state.fStencil = &fStencil;
+    state.fUseHWAA = fUseHWAA;
+    state.fViewMatrix = &fViewMatrix;
+
+    buf->getGpu()->stencilPath(this->path(), state);
 }
 
 void GrInOrderDrawBuffer::DrawPath::execute(GrInOrderDrawBuffer* buf,
@@ -493,7 +497,7 @@
                                                    const GrGeometryProcessor* gp,
                                                    const GrPathProcessor* pathProc,
                                                    GrGpu::DrawType drawType,
-                                                   const GrClipMaskManager::ScissorState& scissor,
+                                                   const GrScissorState& scissor,
                                                    const GrDeviceCoordTexture* dstCopy) {
     SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState,
                                             (ds, gp, pathProc, *this->getGpu()->caps(), scissor,
diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h
index e2916dd..ec73e4c 100644
--- a/src/gpu/GrInOrderDrawBuffer.h
+++ b/src/gpu/GrInOrderDrawBuffer.h
@@ -51,7 +51,6 @@
     void discard(GrRenderTarget*) SK_OVERRIDE;
 
 private:
-    typedef GrClipMaskManager::ScissorState ScissorState;
     enum {
         kDraw_Cmd           = 1,
         kStencilPath_Cmd    = 2,
@@ -80,16 +79,22 @@
     };
 
     struct StencilPath : public Cmd {
-        StencilPath(const GrPath* path) : Cmd(kStencilPath_Cmd), fPath(path) {}
+        StencilPath(const GrPath* path, GrRenderTarget* rt)
+            : Cmd(kStencilPath_Cmd)
+            , fRenderTarget(rt)
+            , fPath(path) {}
 
         const GrPath* path() const { return fPath.get(); }
 
         void execute(GrInOrderDrawBuffer*, const GrOptDrawState*) SK_OVERRIDE;
 
-        GrStencilSettings fStencilSettings;
-
+        SkMatrix                                                fViewMatrix;
+        bool                                                    fUseHWAA;
+        GrStencilSettings                                       fStencil;
+        GrScissorState                                          fScissor;
     private:
-        GrPendingIOResource<const GrPath, kRead_GrIOType>   fPath;
+        GrPendingIOResource<GrRenderTarget, kWrite_GrIOType>    fRenderTarget;
+        GrPendingIOResource<const GrPath, kRead_GrIOType>       fPath;
     };
 
     struct DrawPath : public Cmd {
@@ -173,7 +178,7 @@
     struct SetState : public Cmd {
         SetState(const GrDrawState& drawState, const GrGeometryProcessor* gp,
                  const GrPathProcessor* pp, const GrDrawTargetCaps& caps,
-                 const ScissorState& scissor, const GrDeviceCoordTexture* dstCopy,
+                 const GrScissorState& scissor, const GrDeviceCoordTexture* dstCopy,
                  GrGpu::DrawType drawType)
         : Cmd(kSetState_Cmd)
         , fState(drawState, gp, pp, caps, scissor, dstCopy, drawType) {}
@@ -193,7 +198,7 @@
     void onDraw(const GrDrawState&,
                 const GrGeometryProcessor*,
                 const DrawInfo&,
-                const ScissorState&,
+                const GrScissorState&,
                 const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
     void onDrawRect(GrDrawState*,
                     GrColor,
@@ -204,12 +209,12 @@
     void onStencilPath(const GrDrawState&,
                        const GrPathProcessor*,
                        const GrPath*,
-                       const ScissorState&,
+                       const GrScissorState&,
                        const GrStencilSettings&) SK_OVERRIDE;
     void onDrawPath(const GrDrawState&,
                     const GrPathProcessor*,
                     const GrPath*,
-                    const ScissorState&,
+                    const GrScissorState&,
                     const GrStencilSettings&,
                     const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
     void onDrawPaths(const GrDrawState&,
@@ -220,7 +225,7 @@
                      const float transformValues[],
                      PathTransformType,
                      int count,
-                     const ScissorState&,
+                     const GrScissorState&,
                      const GrStencilSettings&,
                      const GrDeviceCoordTexture*) SK_OVERRIDE;
     void onClear(const SkIRect* rect,
@@ -243,7 +248,7 @@
                                                         const GrGeometryProcessor*,
                                                         const GrPathProcessor*,
                                                         GrGpu::DrawType,
-                                                        const GrClipMaskManager::ScissorState&,
+                                                        const GrScissorState&,
                                                         const GrDeviceCoordTexture*);
     // We lazily record clip changes in order to skip clips that have no effect.
     void recordClipIfNecessary();
diff --git a/src/gpu/GrOptDrawState.cpp b/src/gpu/GrOptDrawState.cpp
index 93d90b0..d12cf0c 100644
--- a/src/gpu/GrOptDrawState.cpp
+++ b/src/gpu/GrOptDrawState.cpp
@@ -17,7 +17,7 @@
                                const GrGeometryProcessor* gp,
                                const GrPathProcessor* pathProc,
                                const GrDrawTargetCaps& caps,
-                               const ScissorState& scissorState,
+                               const GrScissorState& scissorState,
                                const GrDeviceCoordTexture* dstCopy,
                                GrGpu::DrawType drawType)
     : fFinalized(false) {
@@ -26,13 +26,11 @@
     // Copy GeometryProcesssor from DS or ODS
     if (gp) {
         SkASSERT(!pathProc);
-        SkASSERT(!(GrGpu::IsPathRenderingDrawType(drawType) ||
-                   GrGpu::kStencilPath_DrawType == drawType));
+        SkASSERT(!GrGpu::IsPathRenderingDrawType(drawType));
         fGeometryProcessor.reset(gp);
         fPrimitiveProcessor.reset(gp);
     } else {
-        SkASSERT(!gp && pathProc && (GrGpu::IsPathRenderingDrawType(drawType) ||
-                 GrGpu::kStencilPath_DrawType == drawType));
+        SkASSERT(!gp && pathProc && GrGpu::IsPathRenderingDrawType(drawType));
         fPrimitiveProcessor.reset(pathProc);
     }
 
@@ -64,8 +62,7 @@
     // When path rendering the stencil settings are not always set on the draw state
     // so we must check the draw type. In cases where we will skip drawing we simply return a
     // null GrOptDrawState.
-    if (!xferProcessor || ((GrXferProcessor::kSkipDraw_OptFlag & optFlags) &&
-                           GrGpu::kStencilPath_DrawType != drawType)) {
+    if (!xferProcessor || (GrXferProcessor::kSkipDraw_OptFlag & optFlags)) {
         // Set the fields that don't default init and return. The lack of a render target will
         // indicate that this can be skipped.
         fFlags = 0;
diff --git a/src/gpu/GrOptDrawState.h b/src/gpu/GrOptDrawState.h
index 95f7fa9..9c42b7c 100644
--- a/src/gpu/GrOptDrawState.h
+++ b/src/gpu/GrOptDrawState.h
@@ -29,10 +29,8 @@
 public:
     SK_DECLARE_INST_COUNT(GrOptDrawState)
 
-    typedef GrClipMaskManager::ScissorState ScissorState;
-
     GrOptDrawState(const GrDrawState& drawState, const GrGeometryProcessor*, const GrPathProcessor*,
-                   const GrDrawTargetCaps&, const ScissorState&,
+                   const GrDrawTargetCaps&, const GrScissorState&,
                    const GrDeviceCoordTexture* dstCopy, GrGpu::DrawType);
 
     /*
@@ -123,7 +121,7 @@
     /// @name ScissorState
     ////
 
-    const ScissorState& getScissorState() const { return fScissorState; }
+    const GrScissorState& getScissorState() const { return fScissorState; }
 
     /// @}
 
@@ -190,7 +188,7 @@
     typedef GrPendingProgramElement<const GrPrimitiveProcessor> ProgramPrimitiveProcessor;
     typedef GrPendingProgramElement<const GrXferProcessor> ProgramXferProcessor;
     RenderTarget                        fRenderTarget;
-    ScissorState                        fScissorState;
+    GrScissorState                      fScissorState;
     SkMatrix                            fViewMatrix;
     GrStencilSettings                   fStencilSettings;
     GrDrawState::DrawFace               fDrawFace;
diff --git a/src/gpu/GrTest.cpp b/src/gpu/GrTest.cpp
index 7f2848f..ec31307 100644
--- a/src/gpu/GrTest.cpp
+++ b/src/gpu/GrTest.cpp
@@ -115,8 +115,7 @@
 
     void onDraw(const GrOptDrawState&, const GrDrawTarget::DrawInfo&) SK_OVERRIDE {}
 
-    void onStencilPath(const GrOptDrawState&, const GrPath*, const GrStencilSettings&) SK_OVERRIDE {
-    }
+    void onStencilPath(const GrPath* path, const StencilPathState& state) SK_OVERRIDE {}
 
     void onDrawPath(const GrOptDrawState&, const GrPath*, const GrStencilSettings&) SK_OVERRIDE {}
 
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index 44514b8..92b00c3 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -1313,7 +1313,7 @@
     }
 }
 
-void GrGLGpu::flushScissor(const GrClipMaskManager::ScissorState& scissorState,
+void GrGLGpu::flushScissor(const GrScissorState& scissorState,
                            const GrGLIRect& rtViewport,
                            GrSurfaceOrigin rtOrigin) {
     if (scissorState.fEnabled) {
@@ -1344,8 +1344,9 @@
 }
 
 bool GrGLGpu::flushGLState(const GrOptDrawState& optState) {
-    SkASSERT(kStencilPath_DrawType != optState.drawType());
-    this->flushMiscFixedFunctionState(optState);
+    this->flushDither(optState.isDitherState());
+    this->flushColorWriteDisable(optState.isColorWriteDisabled());
+    this->flushDrawFace(optState.getDrawFace());
 
     fCurrentProgram.reset(fProgramCache->getProgram(optState));
     if (NULL == fCurrentProgram.get()) {
@@ -1366,9 +1367,10 @@
     fCurrentProgram->setData(optState);
 
     GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(optState.getRenderTarget());
-    this->flushStencil(optState.getStencil(), optState.drawType());
+    this->flushStencil(optState.getStencil());
     this->flushScissor(optState.getScissorState(), glRT->getViewport(), glRT->origin());
-    this->flushAAState(optState);
+    this->flushHWAAState(glRT, optState.isHWAntialiasState(),
+                         kDrawLines_DrawType == optState.drawType());
 
     // This must come after textures are flushed because a texture may need
     // to be msaa-resolved (which will modify bound FBO state).
@@ -1471,7 +1473,7 @@
     }
 
     this->flushRenderTarget(glRT, rect);
-    GrClipMaskManager::ScissorState scissorState;
+    GrScissorState scissorState;
     scissorState.fEnabled = SkToBool(rect);
     if (scissorState.fEnabled) {
         scissorState.fRect = *rect;
@@ -1584,7 +1586,7 @@
     GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
     this->flushRenderTarget(glRT, &SkIRect::EmptyIRect());
 
-    GrClipMaskManager::ScissorState scissorState;
+    GrScissorState scissorState;
     scissorState.fEnabled = true;
     scissorState.fRect = rect;
     this->flushScissor(scissorState, glRT->getViewport(), glRT->origin());
@@ -1861,19 +1863,18 @@
 #endif
 }
 
-void GrGLGpu::onStencilPath(const GrOptDrawState& ds,
-                            const GrPath* path,
-                            const GrStencilSettings& stencil) {
-    this->flushMiscFixedFunctionState(ds);
-    GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(ds.getRenderTarget());
+void GrGLGpu::onStencilPath(const GrPath* path, const StencilPathState& state) {
+    this->flushColorWriteDisable(true);
+    this->flushDrawFace(GrDrawState::kBoth_DrawFace);
+
+    GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(state.fRenderTarget);
     SkISize size = SkISize::Make(rt->width(), rt->height());
-    this->glPathRendering()->setProjectionMatrix(ds.getViewMatrix(), size, rt->origin());
-    this->flushStencil(ds.getStencil(), ds.drawType());
-    this->flushScissor(ds.getScissorState(), rt->getViewport(), rt->origin());
-    this->flushAAState(ds);
+    this->glPathRendering()->setProjectionMatrix(*state.fViewMatrix, size, rt->origin());
+    this->flushScissor(*state.fScissor, rt->getViewport(), rt->origin());
+    this->flushHWAAState(rt, state.fUseHWAA, false);
     this->flushRenderTarget(rt, NULL);
 
-    fPathRendering->stencilPath(path, stencil);
+    fPathRendering->stencilPath(path, *state.fStencil);
 }
 
 void GrGLGpu::onDrawPath(const GrOptDrawState& ds, const GrPath* path,
@@ -1920,7 +1921,7 @@
 
             if (GrGLCaps::kES_Apple_MSFBOType == this->glCaps().msFBOType()) {
                 // Apple's extension uses the scissor as the blit bounds.
-                GrClipMaskManager::ScissorState scissorState;
+                GrScissorState scissorState;
                 scissorState.fEnabled = true;
                 scissorState.fRect = dirtyRect;
                 this->flushScissor(scissorState, rt->getViewport(), rt->origin());
@@ -1993,9 +1994,8 @@
 }
 }
 
-void GrGLGpu::flushStencil(const GrStencilSettings& stencilSettings, DrawType type) {
-    // TODO figure out why we need to flush stencil settings on path draws at all
-    if (kStencilPath_DrawType != type && fHWStencilSettings != stencilSettings) {
+void GrGLGpu::flushStencil(const GrStencilSettings& stencilSettings) {
+    if (fHWStencilSettings != stencilSettings) {
         if (stencilSettings.isDisabled()) {
             if (kNo_TriState != fHWStencilTestEnabled) {
                 GL_CALL(Disable(GR_GL_STENCIL_TEST));
@@ -2028,21 +2028,19 @@
     }
 }
 
-void GrGLGpu::flushAAState(const GrOptDrawState& optState) {
+void GrGLGpu::flushHWAAState(GrRenderTarget* rt, bool useHWAA, bool isLineDraw) {
 // At least some ATI linux drivers will render GL_LINES incorrectly when MSAA state is enabled but
 // the target is not multisampled. Single pixel wide lines are rendered thicker than 1 pixel wide.
 #if 0
     // Replace RT_HAS_MSAA with this definition once this driver bug is no longer a relevant concern
     #define RT_HAS_MSAA rt->isMultisampled()
 #else
-    #define RT_HAS_MSAA (rt->isMultisampled() || kDrawLines_DrawType == optState.drawType())
+    #define RT_HAS_MSAA (rt->isMultisampled() || isLineDraw)
 #endif
 
-    const GrRenderTarget* rt = optState.getRenderTarget();
     if (kGL_GrGLStandard == this->glStandard()) {
         if (RT_HAS_MSAA) {
-            bool enableMSAA = optState.isHWAntialiasState();
-            if (enableMSAA) {
+            if (useHWAA) {
                 if (kYes_TriState != fMSAAEnabled) {
                     GL_CALL(Enable(GR_GL_MULTISAMPLE));
                     fMSAAEnabled = kYes_TriState;
@@ -2210,8 +2208,8 @@
     texture->setCachedTexParams(newTexParams, this->getResetTimestamp());
 }
 
-void GrGLGpu::flushMiscFixedFunctionState(const GrOptDrawState& optState) {
-    if (optState.isDitherState()) {
+void GrGLGpu::flushDither(bool dither) {
+    if (dither) {
         if (kYes_TriState != fHWDitherEnabled) {
             GL_CALL(Enable(GR_GL_DITHER));
             fHWDitherEnabled = kYes_TriState;
@@ -2222,8 +2220,10 @@
             fHWDitherEnabled = kNo_TriState;
         }
     }
+}
 
-    if (optState.isColorWriteDisabled()) {
+void GrGLGpu::flushColorWriteDisable(bool disableColorWrites) {
+    if (disableColorWrites) {
         if (kNo_TriState != fHWWriteToColor) {
             GL_CALL(ColorMask(GR_GL_FALSE, GR_GL_FALSE,
                               GR_GL_FALSE, GR_GL_FALSE));
@@ -2235,9 +2235,11 @@
             fHWWriteToColor = kYes_TriState;
         }
     }
+}
 
-    if (fHWDrawFace != optState.getDrawFace()) {
-        switch (optState.getDrawFace()) {
+void GrGLGpu::flushDrawFace(GrDrawState::DrawFace face) {
+    if (fHWDrawFace != face) {
+        switch (face) {
             case GrDrawState::kCCW_DrawFace:
                 GL_CALL(Enable(GR_GL_CULL_FACE));
                 GL_CALL(CullFace(GR_GL_BACK));
@@ -2252,7 +2254,7 @@
             default:
                 SkFAIL("Unknown draw face.");
         }
-        fHWDrawFace = optState.getDrawFace();
+        fHWDrawFace = face;
     }
 }
 
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index 7137bc7..93564fc 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -146,7 +146,7 @@
     void onResolveRenderTarget(GrRenderTarget* target) SK_OVERRIDE;
 
     void onDraw(const GrOptDrawState&, const GrDrawTarget::DrawInfo&) SK_OVERRIDE;
-    void onStencilPath(const GrOptDrawState&, const GrPath*, const GrStencilSettings&) SK_OVERRIDE;
+    void onStencilPath(const GrPath*, const StencilPathState&) SK_OVERRIDE;
     void onDrawPath(const GrOptDrawState&, const GrPath*, const GrStencilSettings&) SK_OVERRIDE;
     void onDrawPaths(const GrOptDrawState&,
                      const GrPathRange*,
@@ -223,12 +223,13 @@
 #endif
     };
 
-    // flushes dithering, color-mask, and face culling stat
-    void flushMiscFixedFunctionState(const GrOptDrawState&);
+    void flushDither(bool dither);
+    void flushColorWriteDisable(bool disableColorWrites);
+    void flushDrawFace(GrDrawState::DrawFace face);
 
     // flushes the scissor. see the note on flushBoundTextureAndParams about
     // flushing the scissor after that function is called.
-    void flushScissor(const GrClipMaskManager::ScissorState&,
+    void flushScissor(const GrScissorState&,
                       const GrGLIRect& rtViewport,
                       GrSurfaceOrigin rtOrigin);
 
@@ -248,8 +249,8 @@
     // NULL means whole target. Can be an empty rect.
     void flushRenderTarget(GrGLRenderTarget*, const SkIRect* bounds);
 
-    void flushStencil(const GrStencilSettings&, DrawType);
-    void flushAAState(const GrOptDrawState&);
+    void flushStencil(const GrStencilSettings&);
+    void flushHWAAState(GrRenderTarget* rt, bool useHWAA, bool isLineDraw);
 
     bool configToGLFormats(GrPixelConfig config,
                            bool getSizedInternal,
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
index 57ddf86..dd562dd 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -239,7 +239,7 @@
     GrTexture* dummyTextures[] = {dummyTexture1.get(), dummyTexture2.get()};
 
     // dummy scissor state
-    GrClipMaskManager::ScissorState scissor;
+    GrScissorState scissor;
 
     // Setup texture cache id key
     const GrCacheID::Domain glProgramsDomain = GrCacheID::GenerateDomain();