Revert "Some scissor state cleanup."

This reverts commit a219419c9d76432dca74494b611ff1f59086d139.

Reason for revert: breaking things
Original change's description:
> Some scissor state cleanup.
> 
> Separate flushing the enablement of scissor from the rect in GrGLGpu.
> 
> Move GrPipeline::ScissorState to a global enum and use more broadly.
> Rename to GrScissorTest to avoid name conflict with existing
> GrScissorState.
> 
> Change-Id: Ib32160b3300bc12de2d2e1761d152fd1bba8b683
> Reviewed-on: https://skia-review.googlesource.com/137395
> Commit-Queue: Brian Salomon <bsalomon@google.com>
> Reviewed-by: Chris Dalton <csmartdalton@google.com>

TBR=bsalomon@google.com,csmartdalton@google.com

Change-Id: If71a5c5efc86d4239b40675bad2a6cb1f77460f8
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/138900
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/include/private/GrTypesPriv.h b/include/private/GrTypesPriv.h
index a5ee508..16f3c4a 100644
--- a/include/private/GrTypesPriv.h
+++ b/include/private/GrTypesPriv.h
@@ -73,11 +73,6 @@
     #error "SK_*32_SHIFT values must correspond to GL_BGRA or GL_RGBA format."
 #endif
 
-enum class GrScissorTest : bool {
-    kDisabled = false,
-    kEnabled = true
-};
-
 /**
  * Geometric primitives used for drawing.
  */
diff --git a/samplecode/SampleCCPRGeometry.cpp b/samplecode/SampleCCPRGeometry.cpp
index 1da048e..13cc0a0 100644
--- a/samplecode/SampleCCPRGeometry.cpp
+++ b/samplecode/SampleCCPRGeometry.cpp
@@ -348,7 +348,8 @@
         }
     }
 
-    GrPipeline pipeline(state->drawOpArgs().fProxy, GrScissorTest::kDisabled, SkBlendMode::kPlus);
+    GrPipeline pipeline(state->drawOpArgs().fProxy, GrPipeline::ScissorState::kDisabled,
+                        SkBlendMode::kPlus);
 
     if (glGpu) {
         glGpu->handleDirtyContext();
diff --git a/src/gpu/GrAppliedClip.h b/src/gpu/GrAppliedClip.h
index 9006866..bfe3383 100644
--- a/src/gpu/GrAppliedClip.h
+++ b/src/gpu/GrAppliedClip.h
@@ -11,8 +11,10 @@
 #include "GrFragmentProcessor.h"
 #include "GrScissorState.h"
 #include "GrWindowRectsState.h"
+
 #include "SkClipStack.h"
 
+
 /**
  * Produced by GrHardClip. It provides a set of modifications to the hardware drawing state that
  * implement the clip.
@@ -53,8 +55,7 @@
     }
 
     bool doesClip() const {
-        return fScissorState.scissorTest() == GrScissorTest::kEnabled || this->hasStencilClip() ||
-               fWindowRectsState.enabled();
+        return fScissorState.enabled() || this->hasStencilClip() || fWindowRectsState.enabled();
     }
 
     bool operator==(const GrAppliedHardClip& that) const {
diff --git a/src/gpu/GrFixedClip.cpp b/src/gpu/GrFixedClip.cpp
index 7eee394..94a89fd 100644
--- a/src/gpu/GrFixedClip.cpp
+++ b/src/gpu/GrFixedClip.cpp
@@ -14,13 +14,12 @@
     if (fWindowRectsState.enabled()) {
         return false;
     }
-    return fScissorState.scissorTest() == GrScissorTest::kDisabled ||
-           GrClip::IsInsideClip(fScissorState.rect(), rect);
+    return !fScissorState.enabled() || GrClip::IsInsideClip(fScissorState.rect(), rect);
 }
 
 void GrFixedClip::getConservativeBounds(int w, int h, SkIRect* devResult, bool* iior) const {
     devResult->setXYWH(0, 0, w, h);
-    if (fScissorState.scissorTest() == GrScissorTest::kEnabled) {
+    if (fScissorState.enabled()) {
         if (!devResult->intersect(fScissorState.rect())) {
             devResult->setEmpty();
         }
@@ -34,7 +33,7 @@
     if (fWindowRectsState.enabled()) {
         return false;
     }
-    if (fScissorState.scissorTest() == GrScissorTest::kEnabled) {
+    if (fScissorState.enabled()) {
         SkRect rect = SkRect::Make(fScissorState.rect());
         if (!rect.intersects(rtBounds)) {
             return false;
@@ -47,7 +46,7 @@
 };
 
 bool GrFixedClip::apply(int rtWidth, int rtHeight, GrAppliedHardClip* out, SkRect* bounds) const {
-    if (fScissorState.scissorTest() == GrScissorTest::kEnabled) {
+    if (fScissorState.enabled()) {
         SkIRect tightScissor = SkIRect::MakeWH(rtWidth, rtHeight);
         if (!tightScissor.intersect(fScissorState.rect())) {
             return false;
diff --git a/src/gpu/GrFixedClip.h b/src/gpu/GrFixedClip.h
index 2e466af..d44c1e8 100644
--- a/src/gpu/GrFixedClip.h
+++ b/src/gpu/GrFixedClip.h
@@ -21,15 +21,14 @@
     explicit GrFixedClip(const SkIRect& scissorRect) : fScissorState(scissorRect) {}
 
     const GrScissorState& scissorState() const { return fScissorState; }
-    GrScissorTest scissorTest() const { return fScissorState.scissorTest(); }
-    const SkIRect& scissorRect() const {
-        SkASSERT(this->scissorTest() == GrScissorTest::kEnabled);
-        return fScissorState.rect();
-    }
+    bool scissorEnabled() const { return fScissorState.enabled(); }
+    const SkIRect& scissorRect() const { SkASSERT(scissorEnabled()); return fScissorState.rect(); }
 
     void disableScissor() { fScissorState.setDisabled(); }
 
-    void setScissor(const SkIRect& irect) { fScissorState = GrScissorState(irect); }
+    void setScissor(const SkIRect& irect) {
+        fScissorState.set(irect);
+    }
     bool SK_WARN_UNUSED_RESULT intersect(const SkIRect& irect) {
         return fScissorState.intersect(irect);
     }
diff --git a/src/gpu/GrGpuCommandBuffer.cpp b/src/gpu/GrGpuCommandBuffer.cpp
index 1cedd0c..42e00f3 100644
--- a/src/gpu/GrGpuCommandBuffer.cpp
+++ b/src/gpu/GrGpuCommandBuffer.cpp
@@ -39,7 +39,7 @@
         SkASSERT(primProc.hasInstanceAttributes() == meshes[i].isInstanced());
     }
 #endif
-    SkASSERT(pipeline.scissorTest() == GrScissorTest::kDisabled || fixedDynamicState ||
+    SkASSERT(!pipeline.isScissorEnabled() || fixedDynamicState ||
              (dynamicStateArrays && dynamicStateArrays->fScissorRects));
 
     auto resourceProvider = this->gpu()->getContext()->contextPriv().resourceProvider();
diff --git a/src/gpu/GrPipeline.cpp b/src/gpu/GrPipeline.cpp
index 3f68fe0..6608d7c 100644
--- a/src/gpu/GrPipeline.cpp
+++ b/src/gpu/GrPipeline.cpp
@@ -28,7 +28,7 @@
     if (appliedClip.hasStencilClip()) {
         fFlags |= kHasStencilClip_Flag;
     }
-    if (appliedClip.scissorState().scissorTest() == GrScissorTest::kEnabled) {
+    if (appliedClip.scissorState().enabled()) {
         fFlags |= kScissorEnabled_Flag;
     }
 
@@ -99,7 +99,7 @@
     return this->getXferProcessor().xferBarrierType(caps);
 }
 
-GrPipeline::GrPipeline(GrRenderTargetProxy* proxy, GrScissorTest scissorTest, SkBlendMode blendmode)
+GrPipeline::GrPipeline(GrRenderTargetProxy* proxy, ScissorState scissorState, SkBlendMode blendmode)
         : fProxy(proxy)
         , fWindowRectsState()
         , fUserStencilSettings(&GrUserStencilSettings::kUnused)
@@ -108,7 +108,7 @@
         , fFragmentProcessors()
         , fNumColorProcessors(0) {
     SkASSERT(proxy);
-    if (scissorTest == GrScissorTest::kEnabled) {
+    if (scissorState) {
         fFlags |= kScissorEnabled_Flag;
     }
 }
diff --git a/src/gpu/GrPipeline.h b/src/gpu/GrPipeline.h
index 2325528..f60a6d4 100644
--- a/src/gpu/GrPipeline.h
+++ b/src/gpu/GrPipeline.h
@@ -64,6 +64,11 @@
         return flags;
     }
 
+    enum ScissorState : bool {
+        kEnabled = true,
+        kDisabled = false
+    };
+
     struct InitArgs {
         uint32_t fFlags = 0;
         const GrUserStencilSettings* fUserStencil = &GrUserStencilSettings::kUnused;
@@ -98,7 +103,7 @@
      * must be "Porter Duff" (<= kLastCoeffMode). If using ScissorState::kEnabled, the caller must
      * specify a scissor rectangle through the DynamicState struct.
      **/
-    GrPipeline(GrRenderTargetProxy*, GrScissorTest, SkBlendMode);
+    GrPipeline(GrRenderTargetProxy*, ScissorState, SkBlendMode);
 
     GrPipeline(const InitArgs&, GrProcessorSet&&, GrAppliedClip&&);
 
@@ -174,8 +179,8 @@
 
     const GrUserStencilSettings* getUserStencil() const { return fUserStencilSettings; }
 
-    GrScissorTest scissorTest() const {
-        return GrScissorTest(SkToBool(fFlags & kScissorEnabled_Flag));
+    ScissorState isScissorEnabled() const {
+        return ScissorState(SkToBool(fFlags & kScissorEnabled_Flag));
     }
 
     const GrWindowRectsState& getWindowRectsState() const { return fWindowRectsState; }
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index 9e52558..1dbde17 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -329,7 +329,7 @@
                                           CanClearFullscreen canClearFullscreen) {
     bool isFull = false;
     if (!clip.hasWindowRectangles()) {
-        isFull = clip.scissorTest() == GrScissorTest::kDisabled ||
+        isFull = !clip.scissorEnabled() ||
                  (CanClearFullscreen::kYes == canClearFullscreen &&
                   this->caps()->preferFullscreenClears()) ||
                  clip.scissorRect().contains(SkIRect::MakeWH(this->width(), this->height()));
diff --git a/src/gpu/GrScissorState.h b/src/gpu/GrScissorState.h
index a395aef..59ea088 100644
--- a/src/gpu/GrScissorState.h
+++ b/src/gpu/GrScissorState.h
@@ -8,29 +8,32 @@
 #ifndef GrScissorState_DEFINED
 #define GrScissorState_DEFINED
 
+#include "SkRect.h"
+
 class GrScissorState {
 public:
-    GrScissorState() = default;
-    GrScissorState(const SkIRect& rect) : fScissorTest(GrScissorTest::kEnabled), fRect(rect) {}
-    void setDisabled() { fScissorTest = GrScissorTest::kDisabled; }
+    GrScissorState() : fEnabled(false) {}
+    GrScissorState(const SkIRect& rect) : fEnabled(true), fRect(rect) {}
+    void setDisabled() { fEnabled = false; }
+    void set(const SkIRect& rect) { fRect = rect; fEnabled = true; }
     bool SK_WARN_UNUSED_RESULT intersect(const SkIRect& rect) {
-        if (fScissorTest == GrScissorTest::kDisabled) {
-            *this = GrScissorState(rect);
+        if (!fEnabled) {
+            this->set(rect);
             return true;
         }
         return fRect.intersect(rect);
     }
     bool operator==(const GrScissorState& other) const {
-        return fScissorTest == other.fScissorTest &&
-               (fScissorTest == GrScissorTest::kDisabled || fRect == other.fRect);
+        return fEnabled == other.fEnabled &&
+                (false == fEnabled || fRect == other.fRect);
     }
     bool operator!=(const GrScissorState& other) const { return !(*this == other); }
 
-    GrScissorTest scissorTest() const { return fScissorTest; }
+    bool enabled() const { return fEnabled; }
     const SkIRect& rect() const { return fRect; }
 
 private:
-    GrScissorTest fScissorTest = GrScissorTest::kDisabled;
+    bool    fEnabled;
     SkIRect fRect;
 };
 
diff --git a/src/gpu/ccpr/GrCCPathParser.cpp b/src/gpu/ccpr/GrCCPathParser.cpp
index d013b57..1935385 100644
--- a/src/gpu/ccpr/GrCCPathParser.cpp
+++ b/src/gpu/ccpr/GrCCPathParser.cpp
@@ -530,7 +530,7 @@
 
     const PrimitiveTallies& batchTotalCounts = fCoverageCountBatches[batchID].fTotalPrimitiveCounts;
 
-    GrPipeline pipeline(flushState->drawOpArgs().fProxy, GrScissorTest::kEnabled,
+    GrPipeline pipeline(flushState->drawOpArgs().fProxy, GrPipeline::ScissorState::kEnabled,
                         SkBlendMode::kPlus);
 
     if (batchTotalCounts.fTriangles) {
@@ -564,7 +564,7 @@
                                     GrCCCoverageProcessor::PrimitiveType primitiveType,
                                     int PrimitiveTallies::*instanceType,
                                     const SkIRect& drawBounds) const {
-    SkASSERT(pipeline.scissorTest() == GrScissorTest::kEnabled);
+    SkASSERT(pipeline.isScissorEnabled());
 
     // Don't call reset(), as that also resets the reserve count.
     fMeshesScratchBuffer.pop_back_n(fMeshesScratchBuffer.count());
diff --git a/src/gpu/ccpr/GrCCPerFlushResources.cpp b/src/gpu/ccpr/GrCCPerFlushResources.cpp
index c4e2861..dd0bf1b 100644
--- a/src/gpu/ccpr/GrCCPerFlushResources.cpp
+++ b/src/gpu/ccpr/GrCCPerFlushResources.cpp
@@ -64,7 +64,8 @@
 
     void onExecute(GrOpFlushState* flushState) override {
         SkASSERT(fStashedAtlasProxy);
-        GrPipeline pipeline(flushState->proxy(), GrScissorTest::kDisabled, SkBlendMode::kSrc);
+        GrPipeline pipeline(flushState->proxy(), GrPipeline::ScissorState::kDisabled,
+                            SkBlendMode::kSrc);
         GrCCPathProcessor pathProc(flushState->resourceProvider(), std::move(fStashedAtlasProxy));
         pathProc.drawPaths(flushState, pipeline, nullptr, *fResources, fBaseInstance, fEndInstance,
                            this->bounds());
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 02f2f37..40915a3 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -1358,7 +1358,7 @@
             GrGLIRect viewport;
             this->bindSurfaceFBOForPixelOps(tex.get(), GR_GL_FRAMEBUFFER, &viewport,
                                             kDst_TempFBOTarget);
-            this->flushScissorTest(GrScissorTest::kDisabled);
+            this->disableScissor();
             this->disableWindowRectangles();
             GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
             fHWWriteToColor = kYes_TriState;
@@ -1605,45 +1605,29 @@
     return GrGLBuffer::Create(this, size, intendedType, accessPattern, data);
 }
 
-void GrGLGpu::flushScissorTest(GrScissorTest test) {
-    if (test == GrScissorTest::kEnabled) {
-        if (kYes_TriState != fHWScissorSettings.fEnabled) {
-            GL_CALL(Enable(GR_GL_SCISSOR_TEST));
-            fHWScissorSettings.fEnabled = kYes_TriState;
-        }
-    } else {
-        if (kNo_TriState != fHWScissorSettings.fEnabled) {
-            GL_CALL(Disable(GR_GL_SCISSOR_TEST));
-            fHWScissorSettings.fEnabled = kNo_TriState;
-        }
-    }
-}
-
-void GrGLGpu::flushScissorRect(const SkIRect& scissorRect, const GrGLIRect& viewport,
-                               GrSurfaceOrigin origin) {
-    GrGLIRect scissor;
-    scissor.setRelativeTo(viewport, scissorRect, origin);
-    if (fHWScissorSettings.fRect != scissor) {
-        scissor.pushToGLScissor(this->glInterface());
-        fHWScissorSettings.fRect = scissor;
-    }
-}
-
-void GrGLGpu::flushScissorState(const GrScissorState& clipScissor, const GrGLIRect& viewport,
-                                GrSurfaceOrigin origin) {
-    if (clipScissor.scissorTest() == GrScissorTest::kEnabled) {
-        GrGLIRect scissorRect;
-        scissorRect.setRelativeTo(viewport, clipScissor.rect(), origin);
-        if (!scissorRect.contains(viewport)) {
-            this->flushScissorTest(GrScissorTest::kEnabled);
-            if (fHWScissorSettings.fRect != scissorRect) {
-                scissorRect.pushToGLScissor(this->glInterface());
-                fHWScissorSettings.fRect = scissorRect;
+void GrGLGpu::flushScissor(const GrScissorState& scissorState,
+                           const GrGLIRect& rtViewport,
+                           GrSurfaceOrigin rtOrigin) {
+    if (scissorState.enabled()) {
+        GrGLIRect scissor;
+        scissor.setRelativeTo(rtViewport, scissorState.rect(), rtOrigin);
+        // if the scissor fully contains the viewport then we fall through and
+        // disable the scissor test.
+        if (!scissor.contains(rtViewport)) {
+            if (fHWScissorSettings.fRect != scissor) {
+                scissor.pushToGLScissor(this->glInterface());
+                fHWScissorSettings.fRect = scissor;
+            }
+            if (kYes_TriState != fHWScissorSettings.fEnabled) {
+                GL_CALL(Enable(GR_GL_SCISSOR_TEST));
+                fHWScissorSettings.fEnabled = kYes_TriState;
             }
             return;
         }
     }
-    this->flushScissorTest(GrScissorTest::kDisabled);
+
+    // See fall through note above
+    this->disableScissor();
 }
 
 void GrGLGpu::flushWindowRectangles(const GrWindowRectsState& windowState,
@@ -1737,10 +1721,12 @@
                       glRT->renderTargetPriv().numStencilBits());
     }
     this->flushStencil(stencil);
-    this->flushScissorTest(pipeline.scissorTest());
-    if (pipeline.scissorTest() == GrScissorTest::kEnabled && fixedDynamicState) {
-        this->flushScissorRect(fixedDynamicState->fScissorRect, glRT->getViewport(),
-                               pipeline.proxy()->origin());
+    if (pipeline.isScissorEnabled()) {
+        static constexpr SkIRect kBogusScissor{0, 0, 1, 1};
+        GrScissorState state(fixedDynamicState ? fixedDynamicState->fScissorRect : kBogusScissor);
+        this->flushScissor(state, glRT->getViewport(), pipeline.proxy()->origin());
+    } else {
+        this->disableScissor();
     }
     this->flushWindowRectangles(pipeline.getWindowRectsState(), glRT, pipeline.proxy()->origin());
     this->flushHWAAState(glRT, pipeline.isHWAntialiasState(), !stencil.isDisabled());
@@ -1874,6 +1860,14 @@
     }
 }
 
+void GrGLGpu::disableScissor() {
+    if (kNo_TriState != fHWScissorSettings.fEnabled) {
+        GL_CALL(Disable(GR_GL_SCISSOR_TEST));
+        fHWScissorSettings.fEnabled = kNo_TriState;
+        return;
+    }
+}
+
 void GrGLGpu::clear(const GrFixedClip& clip, GrColor color,
                     GrRenderTarget* target, GrSurfaceOrigin origin) {
     // parent class should never let us get here with no RT
@@ -1896,12 +1890,12 @@
 
     GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
 
-    if (clip.scissorTest() == GrScissorTest::kEnabled) {
+    if (clip.scissorEnabled()) {
         this->flushRenderTarget(glRT, origin, clip.scissorRect());
     } else {
         this->flushRenderTarget(glRT);
     }
-    this->flushScissorState(clip.scissorState(), glRT->getViewport(), origin);
+    this->flushScissor(clip.scissorState(), glRT->getViewport(), origin);
     this->flushWindowRectangles(clip.windowRectsState(), glRT, origin);
 
     GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
@@ -1930,7 +1924,7 @@
     GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
     this->flushRenderTargetNoColorWrites(glRT);
 
-    this->flushScissorTest(GrScissorTest::kDisabled);
+    this->disableScissor();
     this->disableWindowRectangles();
 
     GL_CALL(StencilMask(0xffffffff));
@@ -1978,7 +1972,7 @@
     GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
     this->flushRenderTargetNoColorWrites(glRT);
 
-    this->flushScissorState(clip.scissorState(), glRT->getViewport(), origin);
+    this->flushScissor(clip.scissorState(), glRT->getViewport(), origin);
     this->flushWindowRectangles(clip.windowRectsState(), glRT, origin);
 
     GL_CALL(StencilMask((uint32_t) clipStencilMask));
@@ -2260,8 +2254,8 @@
         return;
     }
 
-    bool dynamicScissor = pipeline.scissorTest() == GrScissorTest::kEnabled && dynamicStateArrays &&
-                          dynamicStateArrays->fScissorRects;
+    bool dynamicScissor =
+            pipeline.isScissorEnabled() && dynamicStateArrays && dynamicStateArrays->fScissorRects;
     for (int i = 0; i < meshCount; ++i) {
         if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*this->caps())) {
             this->xferBarrier(pipeline.renderTarget(), barrierType);
@@ -2269,8 +2263,8 @@
 
         if (dynamicScissor) {
             GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.renderTarget());
-            this->flushScissorRect(dynamicStateArrays->fScissorRects[i], glRT->getViewport(),
-                                   pipeline.proxy()->origin());
+            this->flushScissor(GrScissorState(dynamicStateArrays->fScissorRects[i]),
+                               glRT->getViewport(), pipeline.proxy()->origin());
         }
         if (this->glCaps().requiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines() &&
             GrIsPrimTypeLines(meshes[i].primitiveType()) &&
@@ -2414,7 +2408,9 @@
             static constexpr auto kDirtyRectOrigin = kTopLeft_GrSurfaceOrigin;
             if (GrGLCaps::kES_Apple_MSFBOType == this->glCaps().msFBOType()) {
                 // Apple's extension uses the scissor as the blit bounds.
-                this->flushScissorState(GrScissorState(dirtyRect), vp, kDirtyRectOrigin);
+                GrScissorState scissorState;
+                scissorState.set(dirtyRect);
+                this->flushScissor(scissorState, vp, kDirtyRectOrigin);
                 this->disableWindowRectangles();
                 GL_CALL(ResolveMultisampleFramebuffer());
             } else {
@@ -2435,7 +2431,7 @@
                 }
 
                 // BlitFrameBuffer respects the scissor, so disable it.
-                this->flushScissorTest(GrScissorTest::kDisabled);
+                this->disableScissor();
                 this->disableWindowRectangles();
                 GL_CALL(BlitFramebuffer(l, b, r, t, l, b, r, t,
                                         GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST));
@@ -3459,7 +3455,7 @@
     this->flushBlend(blendInfo, GrSwizzle::RGBA());
     this->flushColorWrite(false);
     this->flushHWAAState(glRT, false, false);
-    this->flushScissorState(clip.scissorState(), glRT->getViewport(), origin);
+    this->flushScissor(clip.scissorState(), glRT->getViewport(), origin);
     this->flushWindowRectangles(clip.windowRectsState(), glRT, origin);
     GrStencilAttachment* sb = rt->renderTargetPriv().getStencilAttachment();
     // This should only be called internally when we know we have a stencil buffer.
@@ -3567,7 +3563,7 @@
                  2 * sizeof(GrGLfloat), 0);
 
     GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(dst);
-    this->flushScissorState(clip.scissorState(), glrt->getViewport(), origin);
+    this->flushScissor(clip.scissorState(), glrt->getViewport(), origin);
     this->flushWindowRectangles(clip.windowRectsState(), glrt, origin);
 
     GL_CALL(Uniform4f(fClearColorProgram.fColorUniform, r, g, b, a));
@@ -3584,9 +3580,7 @@
 
     GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4));
     this->unbindTextureFBOForPixelOps(GR_GL_FRAMEBUFFER, dst);
-    const auto* rect =
-            clip.scissorTest() == GrScissorTest::kEnabled ? &clip.scissorRect() : nullptr;
-    this->didWriteToSurface(dst, origin, rect);
+    this->didWriteToSurface(dst, origin, clip.scissorEnabled() ? &clip.scissorRect() : nullptr);
 }
 
 bool GrGLGpu::copySurfaceAsDraw(GrSurface* dst, GrSurfaceOrigin dstOrigin,
@@ -3666,7 +3660,7 @@
     this->flushBlend(blendInfo, GrSwizzle::RGBA());
     this->flushColorWrite(true);
     this->flushHWAAState(nullptr, false, false);
-    this->flushScissorTest(GrScissorTest::kDisabled);
+    this->disableScissor();
     this->disableWindowRectangles();
     this->disableStencil();
     if (this->glCaps().srgbWriteControl()) {
@@ -3738,7 +3732,7 @@
     dstGLRect.setRelativeTo(dstVP, dstRect, dstOrigin);
 
     // BlitFrameBuffer respects the scissor, so disable it.
-    this->flushScissorTest(GrScissorTest::kDisabled);
+    this->disableScissor();
     this->disableWindowRectangles();
 
     GrGLint srcY0;
@@ -3833,7 +3827,7 @@
     this->flushBlend(blendInfo, GrSwizzle::RGBA());
     this->flushColorWrite(true);
     this->flushHWAAState(nullptr, false, false);
-    this->flushScissorTest(GrScissorTest::kDisabled);
+    this->disableScissor();
     this->disableWindowRectangles();
     this->disableStencil();
 
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 0448f11..765d5f6 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -328,9 +328,14 @@
 
     void flushColorWrite(bool writeColor);
 
-    void flushScissorTest(GrScissorTest);
-    void flushScissorRect(const SkIRect& scissorRect, const GrGLIRect& viewport, GrSurfaceOrigin);
-    void flushScissorState(const GrScissorState&, const GrGLIRect& viewport, GrSurfaceOrigin);
+    // flushes the scissor. see the note on flushBoundTextureAndParams about
+    // flushing the scissor after that function is called.
+    void flushScissor(const GrScissorState&,
+                      const GrGLIRect& rtViewport,
+                      GrSurfaceOrigin rtOrigin);
+
+    // disables the scissor
+    void disableScissor();
 
     void flushWindowRectangles(const GrWindowRectsState&, const GrGLRenderTarget*, GrSurfaceOrigin);
     void disableWindowRectangles();
diff --git a/src/gpu/gl/GrGLPathRendering.cpp b/src/gpu/gl/GrGLPathRendering.cpp
index dbadd58..85c129f 100644
--- a/src/gpu/gl/GrGLPathRendering.cpp
+++ b/src/gpu/gl/GrGLPathRendering.cpp
@@ -90,7 +90,7 @@
     GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(args.fProxy->priv().peekRenderTarget());
     SkISize size = SkISize::Make(rt->width(), rt->height());
     this->setProjectionMatrix(*args.fViewMatrix, size, args.fProxy->origin());
-    gpu->flushScissorState(*args.fScissor, rt->getViewport(), args.fProxy->origin());
+    gpu->flushScissor(*args.fScissor, rt->getViewport(), args.fProxy->origin());
     gpu->flushHWAAState(rt, args.fUseHWAA, true);
     gpu->flushRenderTarget(rt);
 
diff --git a/src/gpu/ops/GrClearOp.cpp b/src/gpu/ops/GrClearOp.cpp
index 52360db..612ff20 100644
--- a/src/gpu/ops/GrClearOp.cpp
+++ b/src/gpu/ops/GrClearOp.cpp
@@ -17,8 +17,7 @@
                                            GrColor color,
                                            GrSurfaceProxy* dstProxy) {
     const SkIRect rect = SkIRect::MakeWH(dstProxy->width(), dstProxy->height());
-    if (clip.scissorTest() == GrScissorTest::kEnabled &&
-        !SkIRect::Intersects(clip.scissorRect(), rect)) {
+    if (clip.scissorEnabled() && !SkIRect::Intersects(clip.scissorRect(), rect)) {
         return nullptr;
     }
 
@@ -43,7 +42,7 @@
         , fClip(clip)
         , fColor(color) {
     const SkIRect rtRect = SkIRect::MakeWH(proxy->width(), proxy->height());
-    if (fClip.scissorTest() == GrScissorTest::kEnabled) {
+    if (fClip.scissorEnabled()) {
         // Don't let scissors extend outside the RT. This may improve op combining.
         if (!fClip.intersect(rtRect)) {
             SkASSERT(0);  // should be caught upstream
@@ -54,10 +53,8 @@
             fClip.disableScissor();
         }
     }
-    this->setBounds(
-            SkRect::Make(fClip.scissorTest() == GrScissorTest::kEnabled ? fClip.scissorRect()
-                                                                        : rtRect),
-            HasAABloat::kNo, IsZeroArea::kNo);
+    this->setBounds(SkRect::Make(fClip.scissorEnabled() ? fClip.scissorRect() : rtRect),
+                    HasAABloat::kNo, IsZeroArea::kNo);
 }
 
 void GrClearOp::onExecute(GrOpFlushState* state) {
diff --git a/src/gpu/ops/GrClearOp.h b/src/gpu/ops/GrClearOp.h
index 59929b2..6e76191 100644
--- a/src/gpu/ops/GrClearOp.h
+++ b/src/gpu/ops/GrClearOp.h
@@ -33,7 +33,7 @@
         SkString string;
         string.append(INHERITED::dumpInfo());
         string.appendf("Scissor [ ");
-        if (fClip.scissorTest() == GrScissorTest::kEnabled) {
+        if (fClip.scissorEnabled()) {
             const SkIRect& r = fClip.scissorRect();
             string.appendf("L: %d, T: %d, R: %d, B: %d", r.fLeft, r.fTop, r.fRight, r.fBottom);
         } else {
@@ -83,11 +83,9 @@
 
     bool contains(const GrClearOp* that) const {
         // The constructor ensures that scissor gets disabled on any clip that fills the entire RT.
-        if (fClip.scissorTest() == GrScissorTest::kDisabled) {
-            return true;
-        }
-        return that->fClip.scissorTest() == GrScissorTest::kEnabled &&
-               fClip.scissorRect().contains(that->fClip.scissorRect());
+        return !fClip.scissorEnabled() ||
+               (that->fClip.scissorEnabled() &&
+                fClip.scissorRect().contains(that->fClip.scissorRect()));
     }
 
     void onPrepare(GrOpFlushState*) override {}
diff --git a/src/gpu/ops/GrClearStencilClipOp.h b/src/gpu/ops/GrClearStencilClipOp.h
index 09c05e1..3e7ad50 100644
--- a/src/gpu/ops/GrClearStencilClipOp.h
+++ b/src/gpu/ops/GrClearStencilClipOp.h
@@ -27,7 +27,7 @@
 
     SkString dumpInfo() const override {
         SkString string("Scissor [");
-        if (fClip.scissorTest() == GrScissorTest::kEnabled) {
+        if (fClip.scissorEnabled()) {
             const SkIRect& r = fClip.scissorRect();
             string.appendf("L: %d, T: %d, R: %d, B: %d", r.fLeft, r.fTop, r.fRight, r.fBottom);
         } else {
@@ -46,9 +46,9 @@
             : INHERITED(ClassID())
             , fClip(clip)
             , fInsideStencilMask(insideStencilMask) {
-        const SkRect& bounds = fClip.scissorTest() == GrScissorTest::kEnabled
-                                       ? SkRect::Make(fClip.scissorRect())
-                                       : SkRect::MakeIWH(proxy->width(), proxy->height());
+        const SkRect& bounds = fClip.scissorEnabled()
+                                            ? SkRect::Make(fClip.scissorRect())
+                                            : SkRect::MakeIWH(proxy->width(), proxy->height());
         this->setBounds(bounds, HasAABloat::kNo, IsZeroArea::kNo);
     }
 
diff --git a/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp b/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp
index 6b56183..f395927 100644
--- a/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp
+++ b/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp
@@ -109,7 +109,7 @@
             return true;
         }
         GrStencilClip stencilClip(appliedClip.stencilStackID());
-        if (appliedClip.scissorState().scissorTest() == GrScissorTest::kEnabled) {
+        if (appliedClip.scissorState().enabled()) {
             stencilClip.fixedClip().setScissor(appliedClip.scissorState().rect());
         }
         if (appliedClip.windowRectsState().enabled()) {
diff --git a/src/gpu/vk/GrVkGpuCommandBuffer.cpp b/src/gpu/vk/GrVkGpuCommandBuffer.cpp
index 63ebba0..91adb5a 100644
--- a/src/gpu/vk/GrVkGpuCommandBuffer.cpp
+++ b/src/gpu/vk/GrVkGpuCommandBuffer.cpp
@@ -305,7 +305,7 @@
     VkClearRect clearRect;
     // Flip rect if necessary
     SkIRect vkRect;
-    if (clip.scissorTest() == GrScissorTest::kDisabled) {
+    if (!clip.scissorEnabled()) {
         vkRect.setXYWH(0, 0, fRenderTarget->width(), fRenderTarget->height());
     } else if (kBottomLeft_GrSurfaceOrigin != fOrigin) {
         vkRect = clip.scissorRect();
@@ -333,7 +333,7 @@
     cbInfo.fIsEmpty = false;
 
     // Update command buffer bounds
-    if (clip.scissorTest() == GrScissorTest::kDisabled) {
+    if (!clip.scissorEnabled()) {
         cbInfo.fBounds.join(fRenderTarget->getBoundsRect());
     } else {
         cbInfo.fBounds.join(SkRect::Make(clip.scissorRect()));
@@ -351,7 +351,7 @@
     VkClearColorValue vkColor;
     GrColorToRGBAFloat(color, vkColor.float32);
 
-    if (cbInfo.fIsEmpty && clip.scissorTest() == GrScissorTest::kDisabled) {
+    if (cbInfo.fIsEmpty && !clip.scissorEnabled()) {
         // Change the render pass to do a clear load
         GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_CLEAR,
                                                 VK_ATTACHMENT_STORE_OP_STORE);
@@ -390,7 +390,7 @@
     VkClearRect clearRect;
     // Flip rect if necessary
     SkIRect vkRect;
-    if (clip.scissorTest() == GrScissorTest::kDisabled) {
+    if (!clip.scissorEnabled()) {
         vkRect.setXYWH(0, 0, fRenderTarget->width(), fRenderTarget->height());
     } else if (kBottomLeft_GrSurfaceOrigin != fOrigin) {
         vkRect = clip.scissorRect();
@@ -416,7 +416,7 @@
     cbInfo.fIsEmpty = false;
 
     // Update command buffer bounds
-    if (clip.scissorTest() == GrScissorTest::kDisabled) {
+    if (!clip.scissorEnabled()) {
         cbInfo.fBounds.join(fRenderTarget->getBoundsRect());
     } else {
         cbInfo.fBounds.join(SkRect::Make(clip.scissorRect()));
@@ -591,7 +591,7 @@
 
     GrRenderTarget* rt = pipeline.renderTarget();
 
-    if (pipeline.scissorTest() == GrScissorTest::kDisabled) {
+    if (!pipeline.isScissorEnabled()) {
         GrVkPipeline::SetDynamicScissorRectState(fGpu, cbInfo.currentCmdBuf(),
                                                  rt, pipeline.proxy()->origin(),
                                                  SkIRect::MakeWH(rt->width(), rt->height()));
@@ -663,8 +663,8 @@
         return;
     }
 
-    bool dynamicScissor = (pipeline.scissorTest() == GrScissorTest::kEnabled) &&
-                          dynamicStateArrays && dynamicStateArrays->fScissorRects;
+    bool dynamicScissor =
+            pipeline.isScissorEnabled() && dynamicStateArrays && dynamicStateArrays->fScissorRects;
 
     for (int i = 0; i < meshCount; ++i) {
         const GrMesh& mesh = meshes[i];
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
index 06b8f71..359527f 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -292,6 +292,9 @@
         return false;
     }
 
+    // dummy scissor state
+    GrScissorState scissor;
+
     SkRandom random;
     static const int NUM_TESTS = 1024;
     for (int t = 0; t < NUM_TESTS; t++) {
diff --git a/tests/GrMeshTest.cpp b/tests/GrMeshTest.cpp
index e8c124d..aa951c0 100644
--- a/tests/GrMeshTest.cpp
+++ b/tests/GrMeshTest.cpp
@@ -392,7 +392,7 @@
 
 void DrawMeshHelper::drawMesh(const GrMesh& mesh) {
     GrRenderTargetProxy* proxy = fState->drawOpArgs().fProxy;
-    GrPipeline pipeline(proxy, GrScissorTest::kDisabled, SkBlendMode::kSrc);
+    GrPipeline pipeline(proxy, GrPipeline::ScissorState::kDisabled, SkBlendMode::kSrc);
     GrMeshTestProcessor mtp(mesh.isInstanced(), mesh.hasVertexData());
     fState->rtCommandBuffer()->draw(mtp, pipeline, nullptr, nullptr, &mesh, 1,
                                     SkRect::MakeIWH(kImageWidth, kImageHeight));
diff --git a/tests/GrPipelineDynamicStateTest.cpp b/tests/GrPipelineDynamicStateTest.cpp
index ad63189..b2aaecc 100644
--- a/tests/GrPipelineDynamicStateTest.cpp
+++ b/tests/GrPipelineDynamicStateTest.cpp
@@ -28,6 +28,8 @@
  * scissor rectangles then reads back the result to verify a successful test.
  */
 
+using ScissorState = GrPipeline::ScissorState;
+
 static constexpr int kScreenSize = 6;
 static constexpr int kNumMeshes = 4;
 static constexpr int kScreenSplitX = kScreenSize/2;
@@ -111,18 +113,20 @@
     DEFINE_OP_CLASS_ID
 
     static std::unique_ptr<GrDrawOp> Make(GrContext* context,
-                                          GrScissorTest scissorTest,
+                                          ScissorState scissorState,
                                           sk_sp<const GrBuffer> vbuff) {
         GrOpMemoryPool* pool = context->contextPriv().opMemoryPool();
 
-        return pool->allocate<GrPipelineDynamicStateTestOp>(scissorTest, std::move(vbuff));
+        return pool->allocate<GrPipelineDynamicStateTestOp>(scissorState, std::move(vbuff));
     }
 
 private:
     friend class GrOpMemoryPool;
 
-    GrPipelineDynamicStateTestOp(GrScissorTest scissorTest, sk_sp<const GrBuffer> vbuff)
-            : INHERITED(ClassID()), fScissorTest(scissorTest), fVertexBuffer(std::move(vbuff)) {
+    GrPipelineDynamicStateTestOp(ScissorState scissorState, sk_sp<const GrBuffer> vbuff)
+        : INHERITED(ClassID())
+        , fScissorState(scissorState)
+        , fVertexBuffer(std::move(vbuff)) {
         this->setBounds(SkRect::MakeIWH(kScreenSize, kScreenSize),
                         HasAABloat::kNo, IsZeroArea::kNo);
     }
@@ -137,7 +141,7 @@
     void onPrepare(GrOpFlushState*) override {}
     void onExecute(GrOpFlushState* state) override {
         GrRenderTargetProxy* proxy = state->drawOpArgs().fProxy;
-        GrPipeline pipeline(proxy, fScissorTest, SkBlendMode::kSrc);
+        GrPipeline pipeline(proxy, fScissorState, SkBlendMode::kSrc);
         SkSTArray<kNumMeshes, GrMesh> meshes;
         for (int i = 0; i < kNumMeshes; ++i) {
             GrMesh& mesh = meshes.emplace_back(GrPrimitiveType::kTriangleStrip);
@@ -151,7 +155,7 @@
                                        SkRect::MakeIWH(kScreenSize, kScreenSize));
     }
 
-    GrScissorTest               fScissorTest;
+    ScissorState                fScissorState;
     const sk_sp<const GrBuffer> fVertexBuffer;
 
     typedef GrDrawOp INHERITED;
@@ -204,17 +208,17 @@
 
     uint32_t resultPx[kScreenSize * kScreenSize];
 
-    for (GrScissorTest scissorTest : {GrScissorTest::kEnabled, GrScissorTest::kDisabled}) {
+    for (ScissorState scissorState : {ScissorState::kEnabled, ScissorState::kDisabled}) {
         rtc->clear(nullptr, 0xbaaaaaad, GrRenderTargetContext::CanClearFullscreen::kYes);
         rtc->priv().testingOnly_addDrawOp(
-                GrPipelineDynamicStateTestOp::Make(context, scissorTest, vbuff));
+            GrPipelineDynamicStateTestOp::Make(context, scissorState, vbuff));
         rtc->readPixels(SkImageInfo::Make(kScreenSize, kScreenSize,
                                           kRGBA_8888_SkColorType, kPremul_SkAlphaType),
                         resultPx, 4 * kScreenSize, 0, 0, 0);
         for (int y = 0; y < kScreenSize; ++y) {
             for (int x = 0; x < kScreenSize; ++x) {
                 int expectedColorIdx;
-                if (scissorTest == GrScissorTest::kEnabled) {
+                if (ScissorState::kEnabled == scissorState) {
                     expectedColorIdx = (x < kScreenSplitX ? 0 : 2) + (y < kScreenSplitY ? 0 : 1);
                 } else {
                     expectedColorIdx = kNumMeshes - 1;
@@ -223,7 +227,7 @@
                 uint32_t actual = resultPx[y * kScreenSize + x];
                 if (expected != actual) {
                     ERRORF(reporter, "[scissor=%s] pixel (%i,%i): got 0x%x expected 0x%x",
-                           scissorTest == GrScissorTest::kEnabled ? "enabled" : "disabled", x, y,
+                           ScissorState::kEnabled == scissorState ? "enabled" : "disabled", x, y,
                            actual, expected);
                     return;
                 }