Don't flush on read/write pixels unless necessary

BUG=skia:2889
R=robertphillips@google.com

Author: bsalomon@google.com

Review URL: https://codereview.chromium.org/586073002
diff --git a/include/gpu/GrGpuResource.h b/include/gpu/GrGpuResource.h
index f20bad3..61849e7 100644
--- a/include/gpu/GrGpuResource.h
+++ b/include/gpu/GrGpuResource.h
@@ -80,9 +80,14 @@
 #endif
     }
 
+
 protected:
     GrIORef() : fRefCnt(1), fPendingReads(0), fPendingWrites(0) {}
 
+    bool internalHasPendingRead() const { return SkToBool(fPendingReads); }
+    bool internalHasPendingWrite() const { return SkToBool(fPendingWrites); }
+    bool internalHasPendingIO() const { return SkToBool(fPendingWrites | fPendingReads); }
+
 private:
     void addPendingRead() const {
         this->validate();
diff --git a/include/gpu/GrSurface.h b/include/gpu/GrSurface.h
index 8315c63..24eb39a 100644
--- a/include/gpu/GrSurface.h
+++ b/include/gpu/GrSurface.h
@@ -135,6 +135,10 @@
      */
     bool savePixels(const char* filename);
 
+    bool hasPendingRead() const;
+    bool hasPendingWrite() const;
+    bool hasPendingIO() const;
+
 protected:
     GrSurface(GrGpu* gpu, bool isWrapped, const GrTextureDesc& desc)
     : INHERITED(gpu, isWrapped)
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index eb8455a..afe396d 100755
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -1347,7 +1347,7 @@
         }
     }
 
-    if (!(kDontFlush_PixelOpsFlag & flags)) {
+    if (!(kDontFlush_PixelOpsFlag & flags) && texture->hasPendingIO()) {
         this->flush();
     }
 
@@ -1418,7 +1418,7 @@
         }
     }
 
-    if (!(kDontFlush_PixelOpsFlag & flags)) {
+    if (!(kDontFlush_PixelOpsFlag & flags) && target->hasPendingWrite()) {
         this->flush();
     }
 
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index efbe861..b9e84c0 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -833,7 +833,7 @@
 
 void GrInOrderDrawBuffer::recordStateIfNecessary() {
     if (fStates.empty()) {
-        fStates.push_back() = this->getDrawState();
+        this->convertDrawStateToPendingExec(&fStates.push_back(this->getDrawState()));
         this->addToCmdBuffer(kSetState_Cmd);
         return;
     }
diff --git a/src/gpu/GrSurface.cpp b/src/gpu/GrSurface.cpp
index 52ab4fd..d15cbdf 100644
--- a/src/gpu/GrSurface.cpp
+++ b/src/gpu/GrSurface.cpp
@@ -44,3 +44,39 @@
 
     return true;
 }
+
+bool GrSurface::hasPendingRead() const {
+    const GrTexture* thisTex = this->asTexture();
+    if (thisTex && thisTex->internalHasPendingRead()) {
+        return true;
+    }
+    const GrRenderTarget* thisRT = this->asRenderTarget();
+    if (thisRT && thisRT->internalHasPendingRead()) {
+        return true;
+    }
+    return false;
+}
+
+bool GrSurface::hasPendingWrite() const {
+    const GrTexture* thisTex = this->asTexture();
+    if (thisTex && thisTex->internalHasPendingWrite()) {
+        return true;
+    }
+    const GrRenderTarget* thisRT = this->asRenderTarget();
+    if (thisRT && thisRT->internalHasPendingWrite()) {
+        return true;
+    }
+    return false;
+}
+
+bool GrSurface::hasPendingIO() const {
+    const GrTexture* thisTex = this->asTexture();
+    if (thisTex && thisTex->internalHasPendingIO()) {
+        return true;
+    }
+    const GrRenderTarget* thisRT = this->asRenderTarget();
+    if (thisRT && thisRT->internalHasPendingIO()) {
+        return true;
+    }
+    return false;
+}