Move some work from backend onClear to base class clear

BUG=skia:

Review URL: https://codereview.chromium.org/1275543005
diff --git a/src/gpu/GrBufferedDrawTarget.cpp b/src/gpu/GrBufferedDrawTarget.cpp
index f2d9367..21a6382 100644
--- a/src/gpu/GrBufferedDrawTarget.cpp
+++ b/src/gpu/GrBufferedDrawTarget.cpp
@@ -80,9 +80,9 @@
     this->recordTraceMarkersIfNecessary(cmd);
 }
 
-void GrBufferedDrawTarget::onClear(const SkIRect* rect, GrColor color,
-                                  bool canIgnoreRect, GrRenderTarget* renderTarget) {
-    GrTargetCommands::Cmd* cmd = fCommands->recordClear(rect, color, canIgnoreRect, renderTarget);
+void GrBufferedDrawTarget::onClear(const SkIRect& rect, GrColor color,
+                                   GrRenderTarget* renderTarget) {
+    GrTargetCommands::Cmd* cmd = fCommands->recordClear(rect, color, renderTarget);
     this->recordTraceMarkersIfNecessary(cmd);
 }
 
diff --git a/src/gpu/GrBufferedDrawTarget.h b/src/gpu/GrBufferedDrawTarget.h
index df9ad46..c149a8d 100644
--- a/src/gpu/GrBufferedDrawTarget.h
+++ b/src/gpu/GrBufferedDrawTarget.h
@@ -96,9 +96,8 @@
                      int count,
                      const GrStencilSettings&,
                      const PipelineInfo&) override;
-    void onClear(const SkIRect* rect,
+    void onClear(const SkIRect& rect,
                  GrColor color,
-                 bool canIgnoreRect,
                  GrRenderTarget* renderTarget) override;
     void onCopySurface(GrSurface* dst,
                        GrSurface* src,
diff --git a/src/gpu/GrCaps.cpp b/src/gpu/GrCaps.cpp
index d6a5470..733c55b 100644
--- a/src/gpu/GrCaps.cpp
+++ b/src/gpu/GrCaps.cpp
@@ -92,6 +92,7 @@
     fOversizedStencilSupport = false;
     fTextureBarrierSupport = false;
     fSupportsInstancedDraws = false;
+    fFullClearIsFree = false;
 
     fUseDrawInsteadOfClear = false;
 
@@ -154,6 +155,7 @@
     r.appendf("Oversized Stencil Support          : %s\n", gNY[fOversizedStencilSupport]);
     r.appendf("Texture Barrier Support            : %s\n", gNY[fTextureBarrierSupport]);
     r.appendf("Supports instanced draws           : %s\n", gNY[fSupportsInstancedDraws]);
+    r.appendf("Full screen clear is free          : %s\n", gNY[fFullClearIsFree]);
     r.appendf("Draw Instead of Clear [workaround] : %s\n", gNY[fUseDrawInsteadOfClear]);
     r.appendf("Draw Instead of TexSubImage [workaround] : %s\n",
               gNY[fUseDrawInsteadOfPartialRenderTargetWrite]);
diff --git a/src/gpu/GrCommandBuilder.cpp b/src/gpu/GrCommandBuilder.cpp
index 28c0cf2..d93a1fa 100644
--- a/src/gpu/GrCommandBuilder.cpp
+++ b/src/gpu/GrCommandBuilder.cpp
@@ -18,28 +18,16 @@
     }
 }
 
-GrTargetCommands::Cmd* GrCommandBuilder::recordClear(const SkIRect* rect,
+GrTargetCommands::Cmd* GrCommandBuilder::recordClear(const SkIRect& rect,
                                                      GrColor color,
-                                                     bool canIgnoreRect,
                                                      GrRenderTarget* renderTarget) {
     SkASSERT(renderTarget);
-
-    SkIRect r;
-    if (NULL == rect) {
-        // We could do something smart and remove previous draws and clears to
-        // the current render target. If we get that smart we have to make sure
-        // those draws aren't read before this clear (render-to-texture).
-        r.setLTRB(0, 0, renderTarget->width(), renderTarget->height());
-        rect = &r;
-    }
-
-    SkASSERT(canIgnoreRect || (rect->fLeft <= rect->fRight && rect->fTop <= rect->fBottom));
+    SkASSERT(rect.fLeft <= rect.fRight && rect.fTop <= rect.fBottom);
 
     Clear* clr = GrNEW_APPEND_TO_RECORDER(*this->cmdBuffer(), Clear, (renderTarget));
     GrColorIsPMAssert(color);
     clr->fColor = color;
-    clr->fRect = *rect;
-    clr->fCanIgnoreRect = canIgnoreRect;
+    clr->fRect = rect;
     return clr;
 }
 
diff --git a/src/gpu/GrCommandBuilder.h b/src/gpu/GrCommandBuilder.h
index c709586..f067249 100644
--- a/src/gpu/GrCommandBuilder.h
+++ b/src/gpu/GrCommandBuilder.h
@@ -49,9 +49,8 @@
                                  int,
                                  const GrStencilSettings&,
                                  const GrDrawTarget::PipelineInfo&) = 0;
-    virtual Cmd* recordClear(const SkIRect* rect,
+    virtual Cmd* recordClear(const SkIRect& rect,
                              GrColor,
-                             bool canIgnoreRect,
                              GrRenderTarget*);
     virtual Cmd* recordCopySurface(GrSurface* dst,
                                    GrSurface* src,
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index 0049767..2171f1e 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -309,14 +309,25 @@
                          GrColor color,
                          bool canIgnoreRect,
                          GrRenderTarget* renderTarget) {
+    SkIRect rtRect = SkIRect::MakeWH(renderTarget->width(), renderTarget->height());
+    SkIRect clippedRect;
+    if (!rect ||
+        (canIgnoreRect && this->caps()->fullClearIsFree()) ||
+        rect->contains(rtRect)) {
+        rect = &rtRect;
+    } else {
+        clippedRect = *rect;
+        if (!clippedRect.intersect(rtRect)) {
+            return;
+        }
+        rect = &clippedRect;
+    }
+
     if (fCaps->useDrawInsteadOfClear()) {
         // This works around a driver bug with clear by drawing a rect instead.
         // The driver will ignore a clear if it is the only thing rendered to a
         // target before the target is read.
-        SkIRect rtRect = SkIRect::MakeWH(renderTarget->width(), renderTarget->height());
-        if (NULL == rect || canIgnoreRect || rect->contains(rtRect)) {
-            rect = &rtRect;
-            // We first issue a discard() since that may help tilers.
+        if (rect == &rtRect) {
             this->discard(renderTarget);
         }
 
@@ -325,7 +336,7 @@
 
         this->drawSimpleRect(pipelineBuilder, color, SkMatrix::I(), *rect);
     } else {       
-        this->onClear(rect, color, canIgnoreRect, renderTarget);
+        this->onClear(*rect, color, renderTarget);
     }
 }
 
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index 022c6b3..a38f0e9 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -271,8 +271,7 @@
                              const GrStencilSettings&,
                              const PipelineInfo&) = 0;
 
-    virtual void onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect,
-                         GrRenderTarget* renderTarget) = 0;
+    virtual void onClear(const SkIRect& rect, GrColor color, GrRenderTarget* renderTarget) = 0;
 
     /** The subclass's copy surface implementation. It should assume that any clipping has already
         been performed on the rect and point and that the GrGpu supports the copy. */
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index bb020f5..64016cf 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -216,13 +216,13 @@
     return ib;
 }
 
-void GrGpu::clear(const SkIRect* rect,
+void GrGpu::clear(const SkIRect& rect,
                   GrColor color,
-                  bool canIgnoreRect,
                   GrRenderTarget* renderTarget) {
     SkASSERT(renderTarget);
+    SkASSERT(SkIRect::MakeWH(renderTarget->width(), renderTarget->height()).contains(rect));
     this->handleDirtyContext();
-    this->onClear(renderTarget, rect, color, canIgnoreRect);
+    this->onClear(renderTarget, rect, color);
 }
 
 void GrGpu::clearStencilClip(const SkIRect& rect,
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index b814abf..cc3a92a 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -249,11 +249,9 @@
                      size_t rowBytes);
 
     /**
-     * Clear the passed in render target. Ignores the draw state and clip. Clears the whole thing if
-     * rect is NULL, otherwise just the rect. If canIgnoreRect is set then the entire render target
-     * can be optionally cleared.
+     * Clear the passed in render target. Ignores the draw state and clip.
      */
-    void clear(const SkIRect* rect, GrColor color, bool canIgnoreRect,GrRenderTarget* renderTarget);
+    void clear(const SkIRect& rect, GrColor color, GrRenderTarget* renderTarget);
 
 
     void clearStencilClip(const SkIRect& rect, bool insideClip, GrRenderTarget* renderTarget);
@@ -450,8 +448,7 @@
     virtual GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) = 0;
 
     // overridden by backend-specific derived class to perform the clear.
-    virtual void onClear(GrRenderTarget*, const SkIRect* rect, GrColor color,
-                         bool canIgnoreRect) = 0;
+    virtual void onClear(GrRenderTarget*, const SkIRect& rect, GrColor color) = 0;
 
 
     // Overridden by backend specific classes to perform a clear of the stencil clip bits.  This is
diff --git a/src/gpu/GrImmediateDrawTarget.cpp b/src/gpu/GrImmediateDrawTarget.cpp
index 0cdc645..f69f86a 100644
--- a/src/gpu/GrImmediateDrawTarget.cpp
+++ b/src/gpu/GrImmediateDrawTarget.cpp
@@ -49,9 +49,9 @@
     pipeline->~GrPipeline();
 }
 
-void GrImmediateDrawTarget::onClear(const SkIRect* rect, GrColor color,
-                                    bool canIgnoreRect, GrRenderTarget* renderTarget) {
-    this->getGpu()->clear(rect, color, canIgnoreRect, renderTarget);
+void GrImmediateDrawTarget::onClear(const SkIRect& rect, GrColor color,
+                                    GrRenderTarget* renderTarget) {
+    this->getGpu()->clear(rect, color, renderTarget);
 }
 
 void GrImmediateDrawTarget::onCopySurface(GrSurface* dst,
diff --git a/src/gpu/GrImmediateDrawTarget.h b/src/gpu/GrImmediateDrawTarget.h
index b6fda07..0fc049e 100644
--- a/src/gpu/GrImmediateDrawTarget.h
+++ b/src/gpu/GrImmediateDrawTarget.h
@@ -63,9 +63,8 @@
                      const PipelineInfo&) override {
         SkFAIL("Only batch implemented\n");
     }
-    void onClear(const SkIRect* rect,
+    void onClear(const SkIRect& rect,
                  GrColor color,
-                 bool canIgnoreRect,
                  GrRenderTarget* renderTarget) override;
     void onCopySurface(GrSurface* dst,
                        GrSurface* src,
diff --git a/src/gpu/GrReorderCommandBuilder.cpp b/src/gpu/GrReorderCommandBuilder.cpp
index 151b516..90953b0 100644
--- a/src/gpu/GrReorderCommandBuilder.cpp
+++ b/src/gpu/GrReorderCommandBuilder.cpp
@@ -32,11 +32,10 @@
             if (Cmd::kDrawBatch_CmdType == reverseIter->type()) {
                 DrawBatch* previous = static_cast<DrawBatch*>(reverseIter.get());
 
-                // We cannot continue to search backwards if the render target changes
                 if (previous->fBatch->pipeline()->getRenderTarget() != rt) {
                     break;
                 }
-
+                // We cannot continue to search backwards if the render target changes
                 if (previous->fBatch->combineIfPossible(batch)) {
                     return NULL;
                 }
@@ -53,9 +52,7 @@
                 }
 
                 // We set the color to illegal if we are doing a discard.
-                // If we can ignore the rect, then we do a full clear
                 if (previous->fColor == GrColor_ILLEGAL ||
-                    previous->fCanIgnoreRect ||
                     intersect(batch->bounds(), previous->fRect)) {
                     break;
                 }
diff --git a/src/gpu/GrTargetCommands.cpp b/src/gpu/GrTargetCommands.cpp
index 3096e27..713514f 100644
--- a/src/gpu/GrTargetCommands.cpp
+++ b/src/gpu/GrTargetCommands.cpp
@@ -91,7 +91,7 @@
     if (GrColor_ILLEGAL == fColor) {
         gpu->discard(this->renderTarget());
     } else {
-        gpu->clear(&fRect, fColor, fCanIgnoreRect, this->renderTarget());
+        gpu->clear(fRect, fColor, this->renderTarget());
     }
 }
 
diff --git a/src/gpu/GrTargetCommands.h b/src/gpu/GrTargetCommands.h
index 9be1210..55c1dfc 100644
--- a/src/gpu/GrTargetCommands.h
+++ b/src/gpu/GrTargetCommands.h
@@ -183,7 +183,6 @@
 
         SkIRect fRect;
         GrColor fColor;
-        bool    fCanIgnoreRect;
 
     private:
         GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> fRenderTarget;
diff --git a/src/gpu/GrTest.cpp b/src/gpu/GrTest.cpp
index f77092a..518ebac 100644
--- a/src/gpu/GrTest.cpp
+++ b/src/gpu/GrTest.cpp
@@ -202,8 +202,7 @@
 
     GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) override { return NULL; }
 
-    void onClear(GrRenderTarget*, const SkIRect* rect, GrColor color,
-                         bool canIgnoreRect) override {}
+    void onClear(GrRenderTarget*, const SkIRect& rect, GrColor color) override {}
 
     void onClearStencilClip(GrRenderTarget*, const SkIRect& rect, bool insideClip) override {}
 
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index a4a5b68..7e84553 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -47,7 +47,6 @@
     fMultisampleDisableSupport = false;
     fUseNonVBOVertexAndIndexDynamicData = false;
     fIsCoreProfile = false;
-    fFullClearIsFree = false;
     fBindFragDataLocationSupport = false;
     fSRGBWriteControl = false;
     fRGBA8888PixelsOpsAreSlow = false;
@@ -1143,7 +1142,6 @@
     r.appendf("Multisample disable support: %s\n", (fMultisampleDisableSupport ? "YES" : "NO"));
     r.appendf("Use non-VBO for dynamic data: %s\n",
              (fUseNonVBOVertexAndIndexDynamicData ? "YES" : "NO"));
-    r.appendf("Full screen clear is free: %s\n", (fFullClearIsFree ? "YES" : "NO"));
     r.appendf("SRGB write contol: %s\n", (fSRGBWriteControl ? "YES" : "NO"));
     r.appendf("RGBA 8888 pixel ops are slow: %s\n", (fRGBA8888PixelsOpsAreSlow? "YES" : "NO"));
     r.appendf("Partial FBO read is slow: %s\n", (fPartialFBOReadIsSlow? "YES" : "NO"));
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index 01ce5bb..bbfdaef 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -252,8 +252,6 @@
 
     bool isCoreProfile() const { return fIsCoreProfile; }
 
-    bool fullClearIsFree() const { return fFullClearIsFree; }
-
     bool bindFragDataLocationSupport() const { return fBindFragDataLocationSupport; }
 
     /**
@@ -380,7 +378,6 @@
     bool fMultisampleDisableSupport : 1;
     bool fUseNonVBOVertexAndIndexDynamicData : 1;
     bool fIsCoreProfile : 1;
-    bool fFullClearIsFree : 1;
     bool fBindFragDataLocationSupport : 1;
     bool fSRGBWriteControl : 1;
     bool fRGBA8888PixelsOpsAreSlow : 1;
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index faee922..ec95557 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -1569,33 +1569,14 @@
     }
 }
 
-void GrGLGpu::onClear(GrRenderTarget* target, const SkIRect* rect, GrColor color,
-                      bool canIgnoreRect) {
+void GrGLGpu::onClear(GrRenderTarget* target, const SkIRect& rect, GrColor color) {
     // parent class should never let us get here with no RT
     SkASSERT(target);
     GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
 
-    if (canIgnoreRect && this->glCaps().fullClearIsFree()) {
-        rect = NULL;
-    }
-
-    SkIRect clippedRect;
-    if (rect) {
-        // flushScissor expects rect to be clipped to the target.
-        clippedRect = *rect;
-        SkIRect rtRect = SkIRect::MakeWH(target->width(), target->height());
-        if (clippedRect.intersect(rtRect)) {
-            rect = &clippedRect;
-        } else {
-            return;
-        }
-    }
-
-    this->flushRenderTarget(glRT, rect);
+    this->flushRenderTarget(glRT, &rect);
     GrScissorState scissorState;
-    if (rect) {
-        scissorState.set(*rect);
-    }
+    scissorState.set(rect);
     this->flushScissor(scissorState, glRT->getViewport(), glRT->origin());
 
     GrGLfloat r, g, b, a;
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index eb9795c..d247a68 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -132,8 +132,7 @@
     bool attachStencilAttachmentToRenderTarget(GrStencilAttachment* sb,
                                                GrRenderTarget* rt) override;
 
-    void onClear(GrRenderTarget*, const SkIRect* rect, GrColor color,
-                 bool canIgnoreRect) override;
+    void onClear(GrRenderTarget*, const SkIRect& rect, GrColor color) override;
 
     void onClearStencilClip(GrRenderTarget*, const SkIRect& rect, bool insideClip) override;