Add checks that the GrResourceAllocator is operating as expected

With explicit resource allocation there should be no explicit instantiating at flush time. There are, however, still several instances where instantiate is called outside of testing (e.g., readSurfacePixels and writeSurfacePixels).

Change-Id: Ic459a550ca85048f66d6a1eb7d601411f83c6e32
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/204721
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrFragmentProcessor.h b/src/gpu/GrFragmentProcessor.h
index 82a3d18..fecf8d5 100644
--- a/src/gpu/GrFragmentProcessor.h
+++ b/src/gpu/GrFragmentProcessor.h
@@ -431,8 +431,14 @@
     bool operator!=(const TextureSampler& other) const { return !(*this == other); }
 
     // 'instantiate' should only ever be called at flush time.
+    // TODO: this can go away once explicit allocation has stuck
     bool instantiate(GrResourceProvider* resourceProvider) const {
-        return SkToBool(fProxyRef.get()->instantiate(resourceProvider));
+        if (resourceProvider->explicitlyAllocateGPUResources()) {
+            SkASSERT(fProxyRef.get()->isInstantiated());
+            return true;
+        } else {
+            return SkToBool(fProxyRef.get()->instantiate(resourceProvider));
+        }
     }
 
     // 'peekTexture' should only ever be called after a successful 'instantiate' call
diff --git a/src/gpu/GrGpuCommandBuffer.cpp b/src/gpu/GrGpuCommandBuffer.cpp
index 3ba49d0..e663fd1 100644
--- a/src/gpu/GrGpuCommandBuffer.cpp
+++ b/src/gpu/GrGpuCommandBuffer.cpp
@@ -54,8 +54,11 @@
         return false;
     }
     if (fixedDynamicState && fixedDynamicState->fPrimitiveProcessorTextures) {
+        GrTextureProxy** processorProxies = fixedDynamicState->fPrimitiveProcessorTextures;
         for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
-            if (!fixedDynamicState->fPrimitiveProcessorTextures[i]->instantiate(resourceProvider)) {
+            if (resourceProvider->explicitlyAllocateGPUResources()) {
+                SkASSERT(processorProxies[i]->isInstantiated());
+            } else if (!processorProxies[i]->instantiate(resourceProvider)) {
                 return false;
             }
         }
@@ -64,7 +67,9 @@
         int n = primProc.numTextureSamplers() * meshCount;
         const auto* textures = dynamicStateArrays->fPrimitiveProcessorTextures;
         for (int i = 0; i < n; ++i) {
-            if (!textures[i]->instantiate(resourceProvider)) {
+            if (resourceProvider->explicitlyAllocateGPUResources()) {
+                SkASSERT(textures[i]->isInstantiated());
+            } else if (!textures[i]->instantiate(resourceProvider)) {
                 return false;
             }
         }
diff --git a/src/gpu/GrOnFlushResourceProvider.cpp b/src/gpu/GrOnFlushResourceProvider.cpp
index 40dc68a..7349901 100644
--- a/src/gpu/GrOnFlushResourceProvider.cpp
+++ b/src/gpu/GrOnFlushResourceProvider.cpp
@@ -64,6 +64,8 @@
 }
 
 bool GrOnFlushResourceProvider::instatiateProxy(GrSurfaceProxy* proxy) {
+    SkASSERT(proxy->priv().requiresNoPendingIO());
+
     // TODO: this class should probably just get a GrDirectContext
     auto direct = fDrawingMgr->getContext()->priv().asDirectContext();
     if (!direct) {
diff --git a/src/gpu/GrOnFlushResourceProvider.h b/src/gpu/GrOnFlushResourceProvider.h
index e2332a9..5851942 100644
--- a/src/gpu/GrOnFlushResourceProvider.h
+++ b/src/gpu/GrOnFlushResourceProvider.h
@@ -66,13 +66,6 @@
 public:
     explicit GrOnFlushResourceProvider(GrDrawingManager* drawingMgr) : fDrawingMgr(drawingMgr) {}
 
-#if 0
-    sk_sp<GrRenderTargetContext> makeRenderTargetContext(const GrSurfaceDesc&,
-                                                         GrSurfaceOrigin,
-                                                         sk_sp<SkColorSpace>,
-                                                         const SkSurfaceProps*);
-#endif
-
     sk_sp<GrRenderTargetContext> makeRenderTargetContext(sk_sp<GrSurfaceProxy>,
                                                          sk_sp<SkColorSpace>,
                                                          const SkSurfaceProps*);
diff --git a/src/gpu/GrOpList.cpp b/src/gpu/GrOpList.cpp
index b1ccc82..4c20a24 100644
--- a/src/gpu/GrOpList.cpp
+++ b/src/gpu/GrOpList.cpp
@@ -54,8 +54,14 @@
     }
 }
 
+// TODO: this can go away when explicit allocation has stuck
 bool GrOpList::instantiate(GrResourceProvider* resourceProvider) {
-    return SkToBool(fTarget.get()->instantiate(resourceProvider));
+    if (resourceProvider->explicitlyAllocateGPUResources()) {
+        SkASSERT(fTarget.get()->isInstantiated());
+        return true;
+    } else {
+        return SkToBool(fTarget.get()->instantiate(resourceProvider));
+    }
 }
 
 void GrOpList::endFlush() {
diff --git a/src/gpu/GrPipeline.cpp b/src/gpu/GrPipeline.cpp
index 07dc753..504d438 100644
--- a/src/gpu/GrPipeline.cpp
+++ b/src/gpu/GrPipeline.cpp
@@ -39,7 +39,9 @@
     fXferProcessor = processors.refXferProcessor();
 
     if (args.fDstProxy.proxy()) {
-        if (!args.fDstProxy.proxy()->instantiate(args.fResourceProvider)) {
+        if (args.fResourceProvider->explicitlyAllocateGPUResources()) {
+            SkASSERT(args.fDstProxy.proxy()->isInstantiated());
+        } else if (!args.fDstProxy.proxy()->instantiate(args.fResourceProvider)) {
             this->markAsBad();
         }
 
diff --git a/src/gpu/GrTextureProxy.cpp b/src/gpu/GrTextureProxy.cpp
index 71af55b..85a312f 100644
--- a/src/gpu/GrTextureProxy.cpp
+++ b/src/gpu/GrTextureProxy.cpp
@@ -92,10 +92,10 @@
 }
 
 sk_sp<GrSurface> GrTextureProxy::createSurface(GrResourceProvider* resourceProvider) const {
-    sk_sp<GrSurface> surface= this->createSurfaceImpl(resourceProvider, 1,
-                                                      /* needsStencil = */ false,
-                                                      kNone_GrSurfaceFlags,
-                                                      fMipMapped);
+    sk_sp<GrSurface> surface = this->createSurfaceImpl(resourceProvider, 1,
+                                                       /* needsStencil = */ false,
+                                                       kNone_GrSurfaceFlags,
+                                                       fMipMapped);
     if (!surface) {
         return nullptr;
     }
diff --git a/src/gpu/GrXferProcessor.h b/src/gpu/GrXferProcessor.h
index 4c3fa9c..008394b 100644
--- a/src/gpu/GrXferProcessor.h
+++ b/src/gpu/GrXferProcessor.h
@@ -95,10 +95,6 @@
             }
         }
 
-        bool instantiate(GrResourceProvider* resourceProvider) {
-            return SkToBool(fProxy->instantiate(resourceProvider));
-        }
-
     private:
         sk_sp<GrTextureProxy> fProxy;
         SkIPoint              fOffset;
diff --git a/src/gpu/ops/GrCopySurfaceOp.cpp b/src/gpu/ops/GrCopySurfaceOp.cpp
index 3adb666..548afb9 100644
--- a/src/gpu/ops/GrCopySurfaceOp.cpp
+++ b/src/gpu/ops/GrCopySurfaceOp.cpp
@@ -87,7 +87,9 @@
 }
 
 void GrCopySurfaceOp::onExecute(GrOpFlushState* state, const SkRect& chainBounds) {
-    if (!fSrc.get()->instantiate(state->resourceProvider())) {
+    if (state->resourceProvider()->explicitlyAllocateGPUResources()) {
+        SkASSERT(fSrc.get()->isInstantiated());
+    } else if (!fSrc.get()->instantiate(state->resourceProvider())) {
         return;
     }
 
diff --git a/src/gpu/ops/GrTextureOp.cpp b/src/gpu/ops/GrTextureOp.cpp
index 73158fb..a0ee544 100644
--- a/src/gpu/ops/GrTextureOp.cpp
+++ b/src/gpu/ops/GrTextureOp.cpp
@@ -437,7 +437,9 @@
             for (unsigned p = 0; p < op.fProxyCnt; ++p) {
                 numTotalQuads += op.fProxies[p].fQuadCnt;
                 auto* proxy = op.fProxies[p].fProxy;
-                if (!proxy->instantiate(target->resourceProvider())) {
+                if (target->resourceProvider()->explicitlyAllocateGPUResources()) {
+                    SkASSERT(proxy->isInstantiated());
+                } else if (!proxy->instantiate(target->resourceProvider())) {
                     return;
                 }
                 SkASSERT(proxy->config() == config);
diff --git a/tests/ImageFilterCacheTest.cpp b/tests/ImageFilterCacheTest.cpp
index 4d1f0f6..de42f52 100644
--- a/tests/ImageFilterCacheTest.cpp
+++ b/tests/ImageFilterCacheTest.cpp
@@ -203,7 +203,8 @@
     SkBitmap srcBM = create_bm();
     sk_sp<SkImage> srcImage(SkImage::MakeFromBitmap(srcBM));
     return proxyProvider->createTextureProxy(srcImage, kNone_GrSurfaceFlags, 1,
-                                             SkBudgeted::kYes, SkBackingFit::kExact);
+                                             SkBudgeted::kYes, SkBackingFit::kExact,
+                                             GrInternalSurfaceFlags::kNoPendingIO);
 }
 
 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageFilterCache_ImageBackedGPU, reporter, ctxInfo) {
diff --git a/tests/OpChainTest.cpp b/tests/OpChainTest.cpp
index a7bd46b..092ccf2 100644
--- a/tests/OpChainTest.cpp
+++ b/tests/OpChainTest.cpp
@@ -173,7 +173,7 @@
 
     auto proxy = context->priv().proxyProvider()->createProxy(
             format, desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, SkBackingFit::kExact,
-            SkBudgeted::kNo, GrInternalSurfaceFlags::kNone);
+            SkBudgeted::kNo, GrInternalSurfaceFlags::kNoPendingIO);
     SkASSERT(proxy);
     proxy->instantiate(context->priv().resourceProvider());
     int result[result_width()];
diff --git a/tests/ProcessorTest.cpp b/tests/ProcessorTest.cpp
index f5c37e4..256f56e 100644
--- a/tests/ProcessorTest.cpp
+++ b/tests/ProcessorTest.cpp
@@ -286,7 +286,9 @@
 }
 
 /** Initializes the two test texture proxies that are available to the FP test factories. */
-bool init_test_textures(GrProxyProvider* proxyProvider, SkRandom* random,
+bool init_test_textures(GrResourceProvider* resourceProvider,
+                        GrProxyProvider* proxyProvider,
+                        SkRandom* random,
                         sk_sp<GrTextureProxy> proxies[2]) {
     static const int kTestTextureSize = 256;
 
@@ -305,7 +307,12 @@
         SkPixmap pixmap(ii, rgbaData.get(), ii.minRowBytes());
         sk_sp<SkImage> img = SkImage::MakeRasterCopy(pixmap);
         proxies[0] = proxyProvider->createTextureProxy(img, kNone_GrSurfaceFlags, 1,
-                                                       SkBudgeted::kYes, SkBackingFit::kExact);
+                                                       SkBudgeted::kYes, SkBackingFit::kExact,
+                                                       GrInternalSurfaceFlags::kNoPendingIO);
+
+        if (resourceProvider->explicitlyAllocateGPUResources()) {
+            proxies[0]->instantiate(resourceProvider);
+        }
     }
 
     {
@@ -322,7 +329,12 @@
         SkPixmap pixmap(ii, alphaData.get(), ii.minRowBytes());
         sk_sp<SkImage> img = SkImage::MakeRasterCopy(pixmap);
         proxies[1] = proxyProvider->createTextureProxy(img, kNone_GrSurfaceFlags, 1,
-                                                       SkBudgeted::kYes, SkBackingFit::kExact);
+                                                       SkBudgeted::kYes, SkBackingFit::kExact,
+                                                       GrInternalSurfaceFlags::kNoPendingIO);
+
+        if (resourceProvider->explicitlyAllocateGPUResources()) {
+            proxies[1]->instantiate(resourceProvider);
+        }
     }
 
     return proxies[0] && proxies[1];
@@ -433,6 +445,10 @@
     auto resourceProvider = context->priv().resourceProvider();
     using FPFactory = GrFragmentProcessorTestFactory;
 
+    // This test side-steps the GrResourceAllocator thus violates some assumptions and
+    // asserts
+    bool orig = resourceProvider->testingOnly_setExplicitlyAllocateGPUResources(false);
+
     uint32_t seed = FLAGS_processorSeed;
     if (FLAGS_randomProcessorTest) {
         std::random_device rd;
@@ -452,7 +468,7 @@
             nullptr);
 
     sk_sp<GrTextureProxy> proxies[2];
-    if (!init_test_textures(proxyProvider, &random, proxies)) {
+    if (!init_test_textures(resourceProvider, proxyProvider, &random, proxies)) {
         ERRORF(reporter, "Could not create test textures");
         return;
     }
@@ -672,6 +688,8 @@
             }
         }
     }
+
+    resourceProvider->testingOnly_setExplicitlyAllocateGPUResources(orig);
 }
 
 // Tests that fragment processors returned by GrFragmentProcessor::clone() are equivalent to their
@@ -681,6 +699,10 @@
     GrProxyProvider* proxyProvider = context->priv().proxyProvider();
     auto resourceProvider = context->priv().resourceProvider();
 
+    // This test side-steps the GrResourceAllocator thus violates some assumptions and
+    // asserts
+    bool orig = resourceProvider->testingOnly_setExplicitlyAllocateGPUResources(false);
+
     SkRandom random;
 
     const GrBackendFormat format =
@@ -693,7 +715,7 @@
             nullptr);
 
     sk_sp<GrTextureProxy> proxies[2];
-    if (!init_test_textures(proxyProvider, &random, proxies)) {
+    if (!init_test_textures(resourceProvider, proxyProvider, &random, proxies)) {
         ERRORF(reporter, "Could not create test textures");
         return;
     }
@@ -751,6 +773,8 @@
             }
         }
     }
+
+    resourceProvider->testingOnly_setExplicitlyAllocateGPUResources(orig);
 }
 
 #endif  // GR_TEST_UTILS
diff --git a/tests/ProxyTest.cpp b/tests/ProxyTest.cpp
index 87b92ee..d8bd651 100644
--- a/tests/ProxyTest.cpp
+++ b/tests/ProxyTest.cpp
@@ -141,7 +141,7 @@
                                 sk_sp<GrTexture> tex;
                                 if (SkBackingFit::kApprox == fit) {
                                     tex = resourceProvider->createApproxTexture(
-                                            desc, GrResourceProvider::Flags::kNone);
+                                            desc, GrResourceProvider::Flags::kNoPendingIO);
                                 } else {
                                     tex = resourceProvider->createTexture(desc, budgeted);
                                 }
diff --git a/tests/TextureProxyTest.cpp b/tests/TextureProxyTest.cpp
index 9e6067e..11e4f29 100644
--- a/tests/TextureProxyTest.cpp
+++ b/tests/TextureProxyTest.cpp
@@ -46,7 +46,7 @@
 
     sk_sp<GrTextureProxy> proxy =
             proxyProvider->createProxy(format, desc, kBottomLeft_GrSurfaceOrigin, fit,
-                                       SkBudgeted::kYes);
+                                       SkBudgeted::kYes, GrInternalSurfaceFlags::kNoPendingIO);
     // Only budgeted & wrapped external proxies get to carry uniqueKeys
     REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid());
     return proxy;
@@ -59,7 +59,8 @@
             ctx->priv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
 
     sk_sp<GrTextureProxy> proxy =
-            proxyProvider->createProxy(format, desc, kBottomLeft_GrSurfaceOrigin, fit, SkBudgeted::kYes);
+            proxyProvider->createProxy(format, desc, kBottomLeft_GrSurfaceOrigin, fit,
+                                       SkBudgeted::kYes, GrInternalSurfaceFlags::kNoPendingIO);
     // Only budgeted & wrapped external proxies get to carry uniqueKeys
     REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid());
     return proxy;
diff --git a/tests/WritePixelsTest.cpp b/tests/WritePixelsTest.cpp
index 297e82b..5377d5b 100644
--- a/tests/WritePixelsTest.cpp
+++ b/tests/WritePixelsTest.cpp
@@ -533,7 +533,8 @@
             context->priv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
 
         sk_sp<GrTextureProxy> temp = proxyProvider->createProxy(
-                format, desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kApprox, SkBudgeted::kYes);
+                format, desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kApprox, SkBudgeted::kYes,
+                GrInternalSurfaceFlags::kNoPendingIO);
         temp->instantiate(context->priv().resourceProvider());
     }