Prefer to recycle non-RT scratch textures that don't have pending IO

BUG=skia:2889

Review URL: https://codereview.chromium.org/650283002
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index b9cbf3f..6ad98ff 100755
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -470,8 +470,15 @@
 
         do {
             GrResourceKey key = GrTexturePriv::ComputeScratchKey(*desc);
-            GrGpuResource* resource = fResourceCache2->findAndRefScratchResource(key,
-                                                                                 calledDuringFlush);
+            uint32_t scratchFlags = 0;
+            if (calledDuringFlush) {
+                scratchFlags = GrResourceCache2::kRequireNoPendingIO_ScratchFlag;
+            } else  if (!(desc->fFlags & kRenderTarget_GrTextureFlagBit)) {
+                // If it is not a render target then it will most likely be populated by
+                // writePixels() which will trigger a flush if the texture has pending IO.
+                scratchFlags = GrResourceCache2::kPreferNoPendingIO_ScratchFlag;
+            }
+            GrGpuResource* resource = fResourceCache2->findAndRefScratchResource(key, scratchFlags);
             if (resource) {
                 fResourceCache->makeResourceMRU(resource);
                 return static_cast<GrTexture*>(resource);
diff --git a/src/gpu/GrResourceCache2.cpp b/src/gpu/GrResourceCache2.cpp
index 5144c59..6bc23a3 100644
--- a/src/gpu/GrResourceCache2.cpp
+++ b/src/gpu/GrResourceCache2.cpp
@@ -59,29 +59,33 @@
 
 class GrResourceCache2::AvailableForScratchUse {
 public:
-    AvailableForScratchUse(bool calledDuringFlush) : fFlushing(calledDuringFlush) { }
+    AvailableForScratchUse(bool rejectPendingIO) : fRejectPendingIO(rejectPendingIO) { }
 
     bool operator()(const GrGpuResource* resource) const {
-        if (fFlushing) {
-            // If this request is coming during draw buffer flush then no refs are allowed
-            // either by drawing code or for pending io operations.
-            // This will be removed when flush no longer creates resources.
-            return resource->reffedOnlyByCache() && !resource->internalHasPendingIO() &&
-                   resource->isScratch();
-        } else {
-            // Because duties are currently shared between GrResourceCache and GrResourceCache2, the
-            // current interpretation of this rule is that only GrResourceCache has a ref but that
-            // it has been marked as a scratch resource.
-            return resource->reffedOnlyByCache() && resource->isScratch();
+        if (!resource->reffedOnlyByCache() || !resource->isScratch()) {
+            return false;
         }
+
+        return !fRejectPendingIO || !resource->internalHasPendingIO();
     }
 
 private:
-    bool fFlushing;
+    bool fRejectPendingIO;
 };
 
 GrGpuResource* GrResourceCache2::findAndRefScratchResource(const GrResourceKey& scratchKey,
-                                                           bool calledDuringFlush) {
+                                                           uint32_t flags) {
     SkASSERT(scratchKey.isScratch());
-    return SkSafeRef(fScratchMap.find(scratchKey, AvailableForScratchUse(calledDuringFlush)));
+
+    if (flags & (kPreferNoPendingIO_ScratchFlag | kRequireNoPendingIO_ScratchFlag)) {
+        GrGpuResource* resource = fScratchMap.find(scratchKey, AvailableForScratchUse(true));
+        if (resource) {
+            return SkRef(resource);
+        } else if (flags & kRequireNoPendingIO_ScratchFlag) {
+            return NULL;
+        }
+        // TODO: fail here when kPrefer is specified, we didn't find a resource without pending io,
+        // but there is still space in our budget for the resource.
+    }
+    return SkSafeRef(fScratchMap.find(scratchKey, AvailableForScratchUse(false)));
 }
diff --git a/src/gpu/GrResourceCache2.h b/src/gpu/GrResourceCache2.h
index d48ca0b..e10b45a 100644
--- a/src/gpu/GrResourceCache2.h
+++ b/src/gpu/GrResourceCache2.h
@@ -32,8 +32,13 @@
 
     void releaseAll();
 
-    GrGpuResource* findAndRefScratchResource(const GrResourceKey& scratchKey,
-                                             bool calledDuringFlush);
+    enum {
+        /** Preferentially returns scratch resources with no pending IO. */
+        kPreferNoPendingIO_ScratchFlag = 0x1,
+        /** Will not return any resources that match but have pending IO. */
+        kRequireNoPendingIO_ScratchFlag = 0x2,
+    };
+    GrGpuResource* findAndRefScratchResource(const GrResourceKey& scratchKey, uint32_t flags = 0);
 
 private:
 #ifdef SK_DEBUG