Support sharing promise images between DDLs

- Migrate our code to SkImage::MakePromiseTexture
- Have DDLTileHelper share one SKP and one set of promise images across all tiles.
- Disallow on-the-fly allocation of mips for promise textures.

Bug: skia:10286
Change-Id: Ie35976958454fc520f3c9d860e6285441260c9f7
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/291938
Commit-Queue: Adlai Holler <adlai@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp
index 8e4bc2a..9562f07 100644
--- a/src/gpu/GrProxyProvider.cpp
+++ b/src/gpu/GrProxyProvider.cpp
@@ -689,17 +689,19 @@
 
     // We pass kReadOnly here since we should treat content of the client's texture as immutable.
     // The promise API provides no way for the client to indicate that the texture is protected.
-    return sk_sp<GrTextureProxy>(new GrTextureProxy(std::move(callback),
-                                                    format,
-                                                    dimensions,
-                                                    mipMapped,
-                                                    mipmapStatus,
-                                                    SkBackingFit::kExact,
-                                                    SkBudgeted::kNo,
-                                                    GrProtected::kNo,
-                                                    GrInternalSurfaceFlags::kReadOnly,
-                                                    GrSurfaceProxy::UseAllocator::kYes,
-                                                    GrDDLProvider::kYes));
+    auto proxy = sk_sp<GrTextureProxy>(new GrTextureProxy(std::move(callback),
+                                                          format,
+                                                          dimensions,
+                                                          mipMapped,
+                                                          mipmapStatus,
+                                                          SkBackingFit::kExact,
+                                                          SkBudgeted::kNo,
+                                                          GrProtected::kNo,
+                                                          GrInternalSurfaceFlags::kReadOnly,
+                                                          GrSurfaceProxy::UseAllocator::kYes,
+                                                          GrDDLProvider::kYes));
+    proxy->priv().setIsPromiseProxy();
+    return proxy;
 }
 
 sk_sp<GrTextureProxy> GrProxyProvider::createLazyProxy(LazyInstantiateCallback&& callback,
diff --git a/src/gpu/GrSurfaceProxy.h b/src/gpu/GrSurfaceProxy.h
index b6dcad0..f99a67e 100644
--- a/src/gpu/GrSurfaceProxy.h
+++ b/src/gpu/GrSurfaceProxy.h
@@ -337,6 +337,8 @@
 
     GrProtected isProtected() const { return fIsProtected; }
 
+    bool isPromiseProxy() { return fIsPromiseProxy; }
+
 protected:
     // Deferred version - takes a new UniqueID from the shared resource/proxy pool.
     GrSurfaceProxy(const GrBackendFormat&,
@@ -433,6 +435,7 @@
 
     bool                   fIgnoredByResourceAllocator = false;
     bool                   fIsDDLTarget = false;
+    bool                   fIsPromiseProxy = false;
     GrProtected            fIsProtected;
 
     // This entry is lazily evaluated so, when the proxy wraps a resource, the resource
diff --git a/src/gpu/GrSurfaceProxyPriv.h b/src/gpu/GrSurfaceProxyPriv.h
index aa98f96..9fe0d1a 100644
--- a/src/gpu/GrSurfaceProxyPriv.h
+++ b/src/gpu/GrSurfaceProxyPriv.h
@@ -42,6 +42,8 @@
 
     void setIsDDLTarget() { fProxy->fIsDDLTarget = true; }
 
+    void setIsPromiseProxy() { fProxy->fIsPromiseProxy = true; }
+
 private:
     explicit GrSurfaceProxyPriv(GrSurfaceProxy* proxy) : fProxy(proxy) {}
     GrSurfaceProxyPriv(const GrSurfaceProxyPriv&) = delete;
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 750630e..6d85242 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -98,13 +98,18 @@
                                                      SkBudgeted budgeted) {
     SkASSERT(baseProxy);
 
+    // We don't allow this for promise proxies i.e. if they need mips they need to give them
+    // to us upfront.
+    if (baseProxy->isPromiseProxy()) {
+        return nullptr;
+    }
     if (!ctx->priv().caps()->isFormatCopyable(baseProxy->backendFormat())) {
-        return {};
+        return nullptr;
     }
     auto copy = GrSurfaceProxy::Copy(ctx, std::move(baseProxy), origin, GrMipmapped::kYes,
                                      SkBackingFit::kExact, budgeted);
     if (!copy) {
-        return {};
+        return nullptr;
     }
     SkASSERT(copy->asTextureProxy());
     return copy;
diff --git a/src/image/SkImage_GpuBase.cpp b/src/image/SkImage_GpuBase.cpp
index d11a617..6a4d23e 100644
--- a/src/image/SkImage_GpuBase.cpp
+++ b/src/image/SkImage_GpuBase.cpp
@@ -35,13 +35,6 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
 
-#if GR_TEST_UTILS
-void SkImage_GpuBase::resetContext(sk_sp<GrImageContext> newContext) {
-    SkASSERT(fContext->priv().matches(newContext.get()));
-    fContext = newContext;
-}
-#endif
-
 bool SkImage_GpuBase::ValidateBackendTexture(const GrCaps* caps, const GrBackendTexture& tex,
                                              GrColorType grCT, SkColorType ct, SkAlphaType at,
                                              sk_sp<SkColorSpace> cs) {
diff --git a/src/image/SkImage_GpuBase.h b/src/image/SkImage_GpuBase.h
index d38f577..05c2123 100644
--- a/src/image/SkImage_GpuBase.h
+++ b/src/image/SkImage_GpuBase.h
@@ -37,10 +37,6 @@
 
     bool onIsValid(GrRecordingContext*) const final;
 
-#if GR_TEST_UTILS
-    void resetContext(sk_sp<GrImageContext> newContext);
-#endif
-
     static bool ValidateBackendTexture(const GrCaps*, const GrBackendTexture& tex,
                                        GrColorType grCT, SkColorType ct, SkAlphaType at,
                                        sk_sp<SkColorSpace> cs);