Skip flush in GrDrawingManager if the specifed proxy doesn't have any work (take 2)

This is rather ham-fisted but I would like to have a short-term fix for the "always-flush" perf regressions.

Change-Id: I508e2d725ac18f50318baf31bc3243fe932c724b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/206697
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp
index 149b112..897c473 100644
--- a/src/gpu/GrDrawingManager.cpp
+++ b/src/gpu/GrDrawingManager.cpp
@@ -72,6 +72,16 @@
     }
 }
 
+bool GrDrawingManager::OpListDAG::isUsed(GrSurfaceProxy* proxy) const {
+    for (int i = 0; i < fOpLists.count(); ++i) {
+        if (fOpLists[i] && fOpLists[i]->isUsed(proxy)) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
 void GrDrawingManager::OpListDAG::add(sk_sp<GrOpList> opList) {
     fOpLists.emplace_back(std::move(opList));
 }
@@ -209,6 +219,10 @@
 
     SkDEBUGCODE(this->validate());
 
+    if (SkSurface::kNone_FlushFlags == flags && !numSemaphores && proxy && !fDAG.isUsed(proxy)) {
+        return GrSemaphoresSubmitted::kNo;
+    }
+
     auto direct = fContext->priv().asDirectContext();
     if (!direct) {
         return GrSemaphoresSubmitted::kNo; // Can't flush while DDL recording
diff --git a/src/gpu/GrDrawingManager.h b/src/gpu/GrDrawingManager.h
index 3f2245e..157a6c6 100644
--- a/src/gpu/GrDrawingManager.h
+++ b/src/gpu/GrDrawingManager.h
@@ -118,6 +118,8 @@
         bool empty() const { return fOpLists.empty(); }
         int numOpLists() const { return fOpLists.count(); }
 
+        bool isUsed(GrSurfaceProxy*) const;
+
         GrOpList* opList(int index) { return fOpLists[index].get(); }
         const GrOpList* opList(int index) const { return fOpLists[index].get(); }
 
diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp
index f33755d..d2c47ac 100644
--- a/src/gpu/GrProxyProvider.cpp
+++ b/src/gpu/GrProxyProvider.cpp
@@ -130,9 +130,10 @@
     sk_sp<GrTexture> tex;
 
     if (SkBackingFit::kApprox == fit) {
-        tex = resourceProvider->createApproxTexture(desc, GrResourceProvider::Flags::kNone);
+        tex = resourceProvider->createApproxTexture(desc, GrResourceProvider::Flags::kNoPendingIO);
     } else {
-        tex = resourceProvider->createTexture(desc, budgeted, GrResourceProvider::Flags::kNone);
+        tex = resourceProvider->createTexture(desc, budgeted,
+                                              GrResourceProvider::Flags::kNoPendingIO);
     }
     if (!tex) {
         return nullptr;
@@ -244,6 +245,9 @@
             surfaceFlags |= GrInternalSurfaceFlags::kMixedSampled;
         }
     }
+    if (fImageContext->priv().explicitlyAllocateGPUResources()) {
+        surfaceFlags |= GrInternalSurfaceFlags::kNoPendingIO;
+    }
 
     GrSurfaceDesc desc;
     desc.fWidth = srcImage->width();
diff --git a/src/gpu/GrRenderTargetOpList.cpp b/src/gpu/GrRenderTargetOpList.cpp
index 66300df..f66fec9 100644
--- a/src/gpu/GrRenderTargetOpList.cpp
+++ b/src/gpu/GrRenderTargetOpList.cpp
@@ -610,6 +610,21 @@
     }
 }
 
+bool GrRenderTargetOpList::onIsUsed(GrSurfaceProxy* proxyToCheck) const {
+    bool used = false;
+
+    auto visit = [ proxyToCheck, &used ] (GrSurfaceProxy* p) {
+        if (p == proxyToCheck) {
+            used = true;
+        }
+    };
+    for (const OpChain& recordedOp : fOpChains) {
+        recordedOp.visitProxies(visit, GrOp::VisitorType::kOther);
+    }
+
+    return used;
+}
+
 void GrRenderTargetOpList::gatherProxyIntervals(GrResourceAllocator* alloc) const {
 
     for (int i = 0; i < fDeferredProxies.count(); ++i) {
diff --git a/src/gpu/GrRenderTargetOpList.h b/src/gpu/GrRenderTargetOpList.h
index 7faae2a..44cc39f 100644
--- a/src/gpu/GrRenderTargetOpList.h
+++ b/src/gpu/GrRenderTargetOpList.h
@@ -126,6 +126,8 @@
     // however, requires that the RTC be able to coordinate with the op list to achieve similar ends
     friend class GrRenderTargetContext;
 
+    bool onIsUsed(GrSurfaceProxy*) const override;
+
     // Must only be called if native stencil buffer clearing is enabled
     void setStencilLoadOp(GrLoadOp op);
     // Must only be called if native color buffer clearing is enabled.
diff --git a/src/gpu/GrTextureOpList.cpp b/src/gpu/GrTextureOpList.cpp
index 2d93f77..1b18c09 100644
--- a/src/gpu/GrTextureOpList.cpp
+++ b/src/gpu/GrTextureOpList.cpp
@@ -180,6 +180,24 @@
     }
 }
 
+bool GrTextureOpList::onIsUsed(GrSurfaceProxy* proxyToCheck) const {
+    bool used = false;
+
+    auto visit = [ proxyToCheck, &used ] (GrSurfaceProxy* p) {
+        if (p == proxyToCheck) {
+            used = true;
+        }
+    };
+    for (int i = 0; i < fRecordedOps.count(); ++i) {
+        const GrOp* op = fRecordedOps[i].get();
+        if (op) {
+            op->visitProxies(visit, GrOp::VisitorType::kOther);
+        }
+    }
+
+    return used;
+}
+
 void GrTextureOpList::gatherProxyIntervals(GrResourceAllocator* alloc) const {
 
     // Add the interval for all the writes to this opList's target
diff --git a/src/gpu/GrTextureOpList.h b/src/gpu/GrTextureOpList.h
index 133fb2d..839b863 100644
--- a/src/gpu/GrTextureOpList.h
+++ b/src/gpu/GrTextureOpList.h
@@ -59,6 +59,8 @@
     SkDEBUGCODE(void dump(bool printDependencies) const override;)
 
 private:
+    bool onIsUsed(GrSurfaceProxy*) const override;
+
     void deleteOp(int index);
     void deleteOps();
 
diff --git a/src/gpu/ccpr/GrCCAtlas.cpp b/src/gpu/ccpr/GrCCAtlas.cpp
index 82b06f0..417bf96 100644
--- a/src/gpu/ccpr/GrCCAtlas.cpp
+++ b/src/gpu/ccpr/GrCCAtlas.cpp
@@ -91,7 +91,8 @@
                         desc.fWidth = fWidth;
                         desc.fHeight = fHeight;
                         desc.fConfig = pixelConfig;
-                        fBackingTexture = resourceProvider->createTexture(desc, SkBudgeted::kYes);
+                        fBackingTexture = resourceProvider->createTexture(
+                            desc, SkBudgeted::kYes, GrResourceProvider::Flags::kNoPendingIO);
                     }
                     return GrSurfaceProxy::LazyInstantiationResult(fBackingTexture);
             },