Remove texture idle proc mechanism

Bug: skia:11369
Change-Id: I0d1a74cc64dd74486acbb69df529ccc0f8b63ef3
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/375202
Reviewed-by: Greg Daniel <egdaniel@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/GrGpuResource.cpp b/src/gpu/GrGpuResource.cpp
index 9267608..716dfa8 100644
--- a/src/gpu/GrGpuResource.cpp
+++ b/src/gpu/GrGpuResource.cpp
@@ -158,11 +158,6 @@
     get_resource_cache(fGpu)->resourceAccess().changeUniqueKey(this, key);
 }
 
-void GrGpuResource::notifyRefCntWillBeZero() const {
-    GrGpuResource* mutableThis = const_cast<GrGpuResource*>(this);
-    mutableThis->willRemoveLastRef();
-}
-
 void GrGpuResource::notifyARefCntIsZero(LastRemovedRef removedRef) const {
     if (this->wasDestroyed()) {
         // We've already been removed from the cache. Goodbye cruel world!
diff --git a/src/gpu/GrGpuResource.h b/src/gpu/GrGpuResource.h
index ee61bbe..015f036 100644
--- a/src/gpu/GrGpuResource.h
+++ b/src/gpu/GrGpuResource.h
@@ -83,22 +83,7 @@
 
 private:
     void notifyWillBeZero(LastRemovedRef removedRef) const {
-        if (0 == this->getRefCnt() && this->hasNoCommandBufferUsages()) {
-            // At this point we better be the only thread accessing this resource.
-            // Trick out the notifyRefCntWillBeZero() call by adding back one more ref.
-            fRefCnt.fetch_add(+1, std::memory_order_relaxed);
-            static_cast<const DERIVED*>(this)->notifyRefCntWillBeZero();
-            // notifyRefCntWillBeZero() could have done anything, including re-refing this and
-            // passing on to another thread. Take away the ref-count we re-added above and see
-            // if we're back to zero.
-            // TODO: Consider making it so that refs can't be added and merge
-            //  notifyRefCntWillBeZero()/willRemoveLastRef() with notifyARefCntIsZero().
-            if (1 == fRefCnt.fetch_add(-1, std::memory_order_acq_rel)) {
-                static_cast<const DERIVED*>(this)->notifyARefCntIsZero(removedRef);
-            }
-        } else {
-            static_cast<const DERIVED*>(this)->notifyARefCntIsZero(removedRef);
-        }
+        static_cast<const DERIVED*>(this)->notifyARefCntIsZero(removedRef);
     }
 
     int32_t getRefCnt() const { return fRefCnt.load(std::memory_order_relaxed); }
@@ -294,15 +279,9 @@
 
     virtual size_t onGpuMemorySize() const = 0;
 
-    /**
-     * Called by GrIORef when a resource is about to lose its last ref
-     */
-    virtual void willRemoveLastRef() {}
-
     // See comments in CacheAccess and ResourcePriv.
     void setUniqueKey(const GrUniqueKey&);
     void removeUniqueKey();
-    void notifyRefCntWillBeZero() const;
     void notifyARefCntIsZero(LastRemovedRef removedRef) const;
     void removeScratchKey();
     void makeBudgeted();
diff --git a/src/gpu/GrManagedResource.cpp b/src/gpu/GrManagedResource.cpp
index 4620de5..c88728b 100644
--- a/src/gpu/GrManagedResource.cpp
+++ b/src/gpu/GrManagedResource.cpp
@@ -14,36 +14,3 @@
 #ifdef SK_TRACE_MANAGED_RESOURCES
 std::atomic<uint32_t> GrManagedResource::fKeyCounter{0};
 #endif
-
-void GrTextureResource::addIdleProc(GrTexture* owningTexture,
-                                    sk_sp<GrRefCntedCallback> idleProc) const {
-    SkASSERT(!fOwningTexture || fOwningTexture == owningTexture);
-    fOwningTexture = owningTexture;
-    fIdleProcs.push_back(std::move(idleProc));
-}
-
-int GrTextureResource::idleProcCnt() const { return fIdleProcs.count(); }
-
-sk_sp<GrRefCntedCallback> GrTextureResource::idleProc(int i) const { return fIdleProcs[i]; }
-
-void GrTextureResource::resetIdleProcs() const { fIdleProcs.reset(); }
-
-void GrTextureResource::removeOwningTexture() const { fOwningTexture = nullptr; }
-
-void GrTextureResource::notifyQueuedForWorkOnGpu() const { ++fNumOwners; }
-
-void GrTextureResource::notifyFinishedWithWorkOnGpu() const {
-    SkASSERT(fNumOwners);
-    if (--fNumOwners || !fIdleProcs.count()) {
-        return;
-    }
-    if (fOwningTexture) {
-        if (fOwningTexture->resourcePriv().hasRefOrCommandBufferUsage()) {
-            // Wait for the texture to become idle in the cache to call the procs.
-            return;
-        }
-        fOwningTexture->callIdleProcsOnBehalfOfResource();
-    } else {
-        fIdleProcs.reset();
-    }
-}
diff --git a/src/gpu/GrManagedResource.h b/src/gpu/GrManagedResource.h
index d80a7f9..fd0aa40 100644
--- a/src/gpu/GrManagedResource.h
+++ b/src/gpu/GrManagedResource.h
@@ -217,7 +217,7 @@
 /** \class GrTextureResource
 
   GrTextureResource is the base class for managed texture resources, and implements the
-  basic idleProc and releaseProc functionality for them.
+  basic releaseProc functionality for them.
 
 */
 class GrTextureResource : public GrManagedResource {
@@ -232,30 +232,8 @@
         fReleaseHelper = std::move(releaseHelper);
     }
 
-    /**
-     * These are used to coordinate calling the "finished" idle procs between the GrTexture
-     * and the GrTextureResource. If the GrTexture becomes purgeable and if there are no command
-     * buffers referring to the GrTextureResource then it calls the procs. Otherwise, the
-     * GrTextureResource calls them when the last command buffer reference goes away and the
-     * GrTexture is purgeable.
-     */
-    void addIdleProc(GrTexture*, sk_sp<GrRefCntedCallback>) const;
-    int idleProcCnt() const;
-    sk_sp<GrRefCntedCallback> idleProc(int) const;
-    void resetIdleProcs() const;
-    void removeOwningTexture() const;
-
-    /**
-     * We track how many outstanding references this GrTextureResource has in command buffers and
-     * when the count reaches zero we call the idle proc.
-     */
-    void notifyQueuedForWorkOnGpu() const override;
-    void notifyFinishedWithWorkOnGpu() const override;
-    bool isQueuedForWorkOnGpu() const { return fNumOwners > 0; }
-
 protected:
     mutable sk_sp<GrRefCntedCallback> fReleaseHelper;
-    mutable GrTexture* fOwningTexture = nullptr;
 
     void invokeReleaseProc() const {
         if (fReleaseHelper) {
@@ -266,9 +244,6 @@
     }
 
 private:
-    mutable int fNumOwners = 0;
-    mutable SkTArray<sk_sp<GrRefCntedCallback>> fIdleProcs;
-
     using INHERITED = GrManagedResource;
 };
 
diff --git a/src/gpu/GrTexture.h b/src/gpu/GrTexture.h
index 60dd828..f703b1e 100644
--- a/src/gpu/GrTexture.h
+++ b/src/gpu/GrTexture.h
@@ -40,23 +40,6 @@
                                     GrBackendTexture*,
                                     SkImage::BackendTextureReleaseProc*);
 
-    /**
-     * Installs a proc on this texture. It will be called when the texture becomes "idle". "Idle"
-     * means, accounting only for Skia's use of the texture, it is safe to delete in the underlying
-     * API. This is used to implement release procs for promise image textures because we cache
-     * the GrTexture object and thus can't rely on it's destructor to trigger a normal release proc.
-     */
-    virtual void addIdleProc(sk_sp<GrRefCntedCallback> idleProc) {
-        // This is the default implementation for the managed case where the IdleState can be
-        // ignored. Unmanaged backends, e.g. Vulkan, must override this to detect when the GPU
-        // is finished accessing the texture.
-        fIdleProcs.push_back(std::move(idleProc));
-    }
-    /** Helper version of addIdleProc that creates the ref-counted wrapper. */
-    void addIdleProc(GrRefCntedCallback::Callback callback, GrRefCntedCallback::Context context) {
-        this->addIdleProc(GrRefCntedCallback::Make(callback, context));
-    }
-
     GrTextureType textureType() const { return fTextureType; }
     bool hasRestrictedSampling() const {
         return GrTextureTypeHasRestrictedSampling(this->textureType());
@@ -85,13 +68,6 @@
 
     virtual bool onStealBackendTexture(GrBackendTexture*, SkImage::BackendTextureReleaseProc*) = 0;
 
-    SkTArray<sk_sp<GrRefCntedCallback>> fIdleProcs;
-
-    void willRemoveLastRef() override {
-        // We're about to be idle in the resource cache. Do our part to trigger the idle callbacks.
-        fIdleProcs.reset();
-    }
-    virtual void callIdleProcsOnBehalfOfResource() {}
     void computeScratchKey(GrScratchKey*) const override;
 
 private:
diff --git a/src/gpu/d3d/GrD3DTexture.cpp b/src/gpu/d3d/GrD3DTexture.cpp
index 230c4c9..2107343 100644
--- a/src/gpu/d3d/GrD3DTexture.cpp
+++ b/src/gpu/d3d/GrD3DTexture.cpp
@@ -109,14 +109,6 @@
 }
 
 void GrD3DTexture::onRelease() {
-    // We're about to be severed from our GrManagedResource. If there are "finish" idle procs we
-    // have to decide who will handle them. If the resource is still tied to a command buffer we let
-    // it handle them. Otherwise, we handle them.
-    SkASSERT(this->resource());
-    if (this->resource()->isQueuedForWorkOnGpu()) {
-        this->removeFinishIdleProcs();
-    }
-
     GrD3DGpu* gpu = this->getD3DGpu();
     gpu->resourceProvider().recycleConstantOrShaderView(fShaderResourceView);
     this->releaseResource(gpu);
@@ -125,14 +117,6 @@
 }
 
 void GrD3DTexture::onAbandon() {
-    // We're about to be severed from our GrManagedResource. If there are "finish" idle procs we
-    // have to decide who will handle them. If the resource is still tied to a command buffer we let
-    // it handle them. Otherwise, we handle them.
-    SkASSERT(this->resource());
-    if (this->resource()->isQueuedForWorkOnGpu()) {
-        this->removeFinishIdleProcs();
-    }
-
     GrD3DGpu* gpu = this->getD3DGpu();
     gpu->resourceProvider().recycleConstantOrShaderView(fShaderResourceView);
     this->releaseResource(gpu);
@@ -147,61 +131,3 @@
     SkASSERT(!this->wasDestroyed());
     return static_cast<GrD3DGpu*>(this->getGpu());
 }
-
-void GrD3DTexture::addIdleProc(sk_sp<GrRefCntedCallback> idleProc) {
-    INHERITED::addIdleProc(idleProc);
-    this->addResourceIdleProc(this, std::move(idleProc));
-}
-
-void GrD3DTexture::callIdleProcsOnBehalfOfResource() {
-    // If we got here then the resource is being removed from its last command buffer and the
-    // texture is idle in the cache. Any kFlush idle procs should already have been called. So
-    // the texture and resource should have the same set of procs.
-    SkASSERT(this->resourceIdleProcCnt() == fIdleProcs.count());
-#ifdef SK_DEBUG
-    for (int i = 0; i < fIdleProcs.count(); ++i) {
-        SkASSERT(fIdleProcs[i] == this->resourceIdleProc(i));
-    }
-#endif
-    fIdleProcs.reset();
-    this->resetResourceIdleProcs();
-}
-
-void GrD3DTexture::willRemoveLastRef() {
-    if (!fIdleProcs.count()) {
-        return;
-    }
-    // This is called when the GrTexture is purgeable. However, we need to check whether the
-    // Resource is still owned by any command buffers. If it is then it will call the proc.
-    if (!this->resourceIsQueuedForWorkOnGpu()) {
-        // Everything must go!
-        fIdleProcs.reset();
-        this->resetResourceIdleProcs();
-    } else {
-        // The procs that should be called on flush but not finish are those that are owned
-        // by the GrD3DTexture and not the Resource. We do this by copying the resource's array
-        // and thereby dropping refs to procs we own but the resource does not.
-        fIdleProcs.reset(this->resourceIdleProcCnt());
-        for (int i = 0; i < fIdleProcs.count(); ++i) {
-            fIdleProcs[i] = this->resourceIdleProc(i);
-        }
-    }
-}
-
-void GrD3DTexture::removeFinishIdleProcs() {
-    // This should only be called by onRelease/onAbandon when we have already checked for a
-    // resource.
-    SkSTArray<4, sk_sp<GrRefCntedCallback>> procsToKeep;
-    int resourceIdx = 0;
-    // The idle procs that are common between the GrD3DTexture and its Resource should be found in
-    // the same order.
-    for (int i = 0; i < fIdleProcs.count(); ++i) {
-        if (fIdleProcs[i] == this->resourceIdleProc(resourceIdx)) {
-            ++resourceIdx;
-        } else {
-            procsToKeep.push_back(fIdleProcs[i]);
-        }
-    }
-    SkASSERT(resourceIdx == this->resourceIdleProcCnt());
-    fIdleProcs = procsToKeep;
-}
diff --git a/src/gpu/d3d/GrD3DTexture.h b/src/gpu/d3d/GrD3DTexture.h
index 8787e47..e57dd29 100644
--- a/src/gpu/d3d/GrD3DTexture.h
+++ b/src/gpu/d3d/GrD3DTexture.h
@@ -39,9 +39,6 @@
 
     void textureParamsModified() override {}
 
-    void addIdleProc(sk_sp<GrRefCntedCallback>) override;
-    void callIdleProcsOnBehalfOfResource() override;
-
 protected:
     GrD3DTexture(GrD3DGpu*,
                  SkISize dimensions,
@@ -59,8 +56,6 @@
         return false;
     }
 
-    void willRemoveLastRef() override;
-
 private:
     GrD3DTexture(GrD3DGpu*, SkBudgeted, SkISize dimensions, const GrD3DTextureResourceInfo&,
                  sk_sp<GrD3DResourceState>,
@@ -78,8 +73,6 @@
         this->setResourceRelease(std::move(releaseHelper));
     }
 
-    void removeFinishIdleProcs();
-
     struct SamplerHash {
         uint32_t operator()(GrSamplerState state) const { return state.asIndex(); }
     };
diff --git a/src/gpu/d3d/GrD3DTextureResource.cpp b/src/gpu/d3d/GrD3DTextureResource.cpp
index 916c359..3f3439b 100644
--- a/src/gpu/d3d/GrD3DTextureResource.cpp
+++ b/src/gpu/d3d/GrD3DTextureResource.cpp
@@ -110,7 +110,6 @@
 void GrD3DTextureResource::releaseResource(GrD3DGpu* gpu) {
     // TODO: do we need to migrate resource state if we change queues?
     if (fResource) {
-        fResource->removeOwningTexture();
         fResource.reset();
     }
     fInfo.fResource.reset();
diff --git a/src/gpu/d3d/GrD3DTextureResource.h b/src/gpu/d3d/GrD3DTextureResource.h
index 2d0bc30..37ee930 100644
--- a/src/gpu/d3d/GrD3DTextureResource.h
+++ b/src/gpu/d3d/GrD3DTextureResource.h
@@ -77,28 +77,6 @@
 protected:
     void releaseResource(GrD3DGpu* gpu);
 
-    void addResourceIdleProc(GrTexture* owningTexture, sk_sp<GrRefCntedCallback> idleProc) {
-        if (fResource) {
-            fResource->addIdleProc(owningTexture, std::move(idleProc));
-        }
-    }
-    void resetResourceIdleProcs() {
-        SkASSERT(fResource);
-        fResource->resetIdleProcs();
-    }
-    bool resourceIsQueuedForWorkOnGpu() const {
-        SkASSERT(fResource);
-        return fResource->isQueuedForWorkOnGpu();
-    }
-    int resourceIdleProcCnt() const {
-        SkASSERT(fResource);
-        return fResource->idleProcCnt();
-    }
-    sk_sp<GrRefCntedCallback> resourceIdleProc(int i) const {
-        SkASSERT(fResource);
-        return fResource->idleProc(i);
-    }
-
     GrD3DTextureResourceInfo fInfo;
     sk_sp<GrD3DResourceState> fState;
 
diff --git a/src/gpu/mock/GrMockTexture.h b/src/gpu/mock/GrMockTexture.h
index 2ebdb8f..41ad564 100644
--- a/src/gpu/mock/GrMockTexture.h
+++ b/src/gpu/mock/GrMockTexture.h
@@ -183,10 +183,6 @@
         return GrMockTexture::backendFormat();
     }
 
-protected:
-    // This avoids an inherits via dominance warning on MSVC.
-    void willRemoveLastRef() override { GrTexture::willRemoveLastRef(); }
-
 private:
     void onAbandon() override {
         GrRenderTarget::onAbandon();
diff --git a/src/gpu/vk/GrVkImage.cpp b/src/gpu/vk/GrVkImage.cpp
index 52efe8a..6759481 100644
--- a/src/gpu/vk/GrVkImage.cpp
+++ b/src/gpu/vk/GrVkImage.cpp
@@ -308,7 +308,6 @@
 
 void GrVkImage::releaseImage() {
     if (fResource) {
-        fResource->removeOwningTexture();
         fResource->unref();
         fResource = nullptr;
     }
diff --git a/src/gpu/vk/GrVkTexture.cpp b/src/gpu/vk/GrVkTexture.cpp
index 9d0f400..6feb677 100644
--- a/src/gpu/vk/GrVkTexture.cpp
+++ b/src/gpu/vk/GrVkTexture.cpp
@@ -138,13 +138,6 @@
 }
 
 void GrVkTexture::onRelease() {
-    // We're about to be severed from our GrManagedResource. If there are "finish" idle procs we
-    // have to decide who will handle them. If the resource is still tied to a command buffer we let
-    // it handle them. Otherwise, we handle them.
-    if (this->hasResource() && this->resource()->isQueuedForWorkOnGpu()) {
-        this->removeFinishIdleProcs();
-    }
-
     // we create this and don't hand it off, so we should always destroy it
     if (fTextureView) {
         fTextureView.reset();
@@ -171,13 +164,6 @@
 };
 
 void GrVkTexture::onAbandon() {
-    // We're about to be severed from our GrManagedResource. If there are "finish" idle procs we
-    // have to decide who will handle them. If the resource is still tied to a command buffer we let
-    // it handle them. Otherwise, we handle them.
-    if (this->hasResource() && this->resource()->isQueuedForWorkOnGpu()) {
-        this->removeFinishIdleProcs();
-    }
-
     // we create this and don't hand it off, so we should always destroy it
     if (fTextureView) {
         fTextureView.reset();
@@ -202,74 +188,6 @@
     return fTextureView.get();
 }
 
-void GrVkTexture::addIdleProc(sk_sp<GrRefCntedCallback> idleProc) {
-    INHERITED::addIdleProc(idleProc);
-    if (auto* resource = this->resource()) {
-        resource->addIdleProc(this, std::move(idleProc));
-    }
-}
-
-void GrVkTexture::callIdleProcsOnBehalfOfResource() {
-    // If we got here then the resource is being removed from its last command buffer and the
-    // texture is idle in the cache. Any kFlush idle procs should already have been called. So
-    // the texture and resource should have the same set of procs.
-    SkASSERT(this->resource());
-    SkASSERT(this->resource()->idleProcCnt() == fIdleProcs.count());
-#ifdef SK_DEBUG
-    for (int i = 0; i < fIdleProcs.count(); ++i) {
-        SkASSERT(fIdleProcs[i] == this->resource()->idleProc(i));
-    }
-#endif
-    fIdleProcs.reset();
-    this->resource()->resetIdleProcs();
-}
-
-void GrVkTexture::willRemoveLastRef() {
-    if (!fIdleProcs.count()) {
-        return;
-    }
-    // This is called when the GrTexture is purgeable. However, we need to check whether the
-    // Resource is still owned by any command buffers. If it is then it will call the proc.
-    auto* resource = this->hasResource() ? this->resource() : nullptr;
-    bool callFinishProcs = !resource || !resource->isQueuedForWorkOnGpu();
-    if (callFinishProcs) {
-        // Everything must go!
-        fIdleProcs.reset();
-        if (resource) {
-            resource->resetIdleProcs();
-        }
-    } else {
-        // The procs that should be called on flush but not finish are those that are owned
-        // by the GrVkTexture and not the Resource. We do this by copying the resource's array
-        // and thereby dropping refs to procs we own but the resource does not.
-        SkASSERT(resource);
-        fIdleProcs.reset(resource->idleProcCnt());
-        for (int i = 0; i < fIdleProcs.count(); ++i) {
-            fIdleProcs[i] = resource->idleProc(i);
-        }
-    }
-}
-
-void GrVkTexture::removeFinishIdleProcs() {
-    // This should only be called by onRelease/onAbandon when we have already checked for a
-    // resource.
-    const auto* resource = this->resource();
-    SkASSERT(resource);
-    SkSTArray<4, sk_sp<GrRefCntedCallback>> procsToKeep;
-    int resourceIdx = 0;
-    // The idle procs that are common between the GrVkTexture and its Resource should be found in
-    // the same order.
-    for (int i = 0; i < fIdleProcs.count(); ++i) {
-        if (fIdleProcs[i] == resource->idleProc(resourceIdx)) {
-            ++resourceIdx;
-        } else {
-            procsToKeep.push_back(fIdleProcs[i]);
-        }
-    }
-    SkASSERT(resourceIdx == resource->idleProcCnt());
-    fIdleProcs = procsToKeep;
-}
-
 const GrVkDescriptorSet* GrVkTexture::cachedSingleDescSet(GrSamplerState state) {
     if (std::unique_ptr<DescriptorCacheEntry>* e = fDescSetCache.find(state)) {
         return (*e)->fDescriptorSet;
diff --git a/src/gpu/vk/GrVkTexture.h b/src/gpu/vk/GrVkTexture.h
index 2f22f97..23950a7 100644
--- a/src/gpu/vk/GrVkTexture.h
+++ b/src/gpu/vk/GrVkTexture.h
@@ -45,9 +45,6 @@
 
     const GrVkImageView* textureView();
 
-    void addIdleProc(sk_sp<GrRefCntedCallback>) override;
-    void callIdleProcsOnBehalfOfResource() override;
-
     // For each GrVkTexture, there is a cache of GrVkDescriptorSets which only contain a single
     // texture/sampler descriptor. If there is a cached descriptor set that matches the passed in
     // GrSamplerState, then a pointer to it is returned. The ref count is not incremented on the
@@ -75,8 +72,6 @@
         return false;
     }
 
-    void willRemoveLastRef() override;
-
 private:
     GrVkTexture(GrVkGpu*, SkBudgeted, SkISize, const GrVkImageInfo&,
                 sk_sp<GrBackendSurfaceMutableStateImpl>, sk_sp<const GrVkImageView> imageView,
@@ -92,8 +87,6 @@
         this->setResourceRelease(std::move(releaseHelper));
     }
 
-    void removeFinishIdleProcs();
-
     sk_sp<const GrVkImageView> fTextureView;
 
     struct SamplerHash {
diff --git a/tests/GrSurfaceTest.cpp b/tests/GrSurfaceTest.cpp
index ac863b1..c0ee92d 100644
--- a/tests/GrSurfaceTest.cpp
+++ b/tests/GrSurfaceTest.cpp
@@ -432,395 +432,3 @@
         }
     }
 }
-
-static const int kSurfSize = 10;
-
-static sk_sp<GrTexture> make_wrapped_texture(GrDirectContext* dContext, GrRenderable renderable) {
-    auto mbet = sk_gpu_test::ManagedBackendTexture::MakeWithoutData(
-            dContext, kSurfSize, kSurfSize, kRGBA_8888_SkColorType, GrMipmapped::kNo, renderable);
-    SkASSERT(mbet);
-    sk_sp<GrTextureProxy> proxy;
-    if (renderable == GrRenderable::kYes) {
-        proxy = dContext->priv().proxyProvider()->wrapRenderableBackendTexture(
-                mbet->texture(), 1, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo,
-                mbet->refCountedCallback());
-    } else {
-        proxy = dContext->priv().proxyProvider()->wrapBackendTexture(
-                mbet->texture(), kBorrow_GrWrapOwnership, GrWrapCacheable::kNo, kRW_GrIOType,
-                mbet->refCountedCallback());
-    }
-    if (!proxy) {
-        return nullptr;
-    }
-    return sk_ref_sp(proxy->peekTexture());
-}
-
-static sk_sp<GrTexture> make_normal_texture(GrDirectContext* dContext, GrRenderable renderable) {
-    SkISize desc;
-    desc.fWidth = desc.fHeight = kSurfSize;
-    auto format = dContext->priv().caps()->getDefaultBackendFormat(GrColorType::kRGBA_8888,
-                                                                   renderable);
-    return dContext->priv().resourceProvider()->createTexture(
-            desc, format, renderable, 1, GrMipmapped::kNo, SkBudgeted::kNo, GrProtected::kNo);
-}
-
-DEF_GPUTEST(TextureIdleProcTest, reporter, options) {
-    // Various ways of making textures.
-    auto makeWrapped = [](GrDirectContext* dContext) {
-        return make_wrapped_texture(dContext, GrRenderable::kNo);
-    };
-    auto makeWrappedRenderable = [](GrDirectContext* dContext) {
-        return make_wrapped_texture(dContext, GrRenderable::kYes);
-    };
-    auto makeNormal = [](GrDirectContext* dContext) {
-        return make_normal_texture(dContext, GrRenderable::kNo);
-    };
-    auto makeRenderable = [](GrDirectContext* dContext) {
-        return make_normal_texture(dContext, GrRenderable::kYes);
-    };
-
-    std::function<sk_sp<GrTexture>(GrDirectContext*)> makers[] = {
-        makeWrapped,
-        makeWrappedRenderable,
-        makeNormal,
-        makeRenderable
-    };
-
-    // Add a unique key, or not.
-    auto addKey = [](GrTexture* texture) {
-        static uint32_t gN = 0;
-        static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
-        GrUniqueKey key;
-        GrUniqueKey::Builder builder(&key, kDomain, 1);
-        builder[0] = gN++;
-        builder.finish();
-        texture->resourcePriv().setUniqueKey(key);
-    };
-    auto dontAddKey = [](GrTexture* texture) {};
-    std::function<void(GrTexture*)> keyAdders[] = {addKey, dontAddKey};
-
-    for (const auto& m : makers) {
-        for (const auto& keyAdder : keyAdders) {
-            for (int type = 0; type < sk_gpu_test::GrContextFactory::kContextTypeCnt; ++type) {
-                sk_gpu_test::GrContextFactory factory;
-                auto contextType = static_cast<sk_gpu_test::GrContextFactory::ContextType>(type);
-                auto dContext = factory.get(contextType);
-                if (!dContext) {
-                    continue;
-                }
-
-                // The callback we add simply adds an integer to a set.
-                std::set<int> idleIDs;
-                struct Context {
-                    std::set<int>* fIdleIDs;
-                    int fNum;
-                };
-                auto proc = [](void* context) {
-                    static_cast<Context*>(context)->fIdleIDs->insert(
-                            static_cast<Context*>(context)->fNum);
-                    delete static_cast<Context*>(context);
-                };
-
-                // Makes a texture, possibly adds a key, and sets the callback.
-                auto make = [&m, &keyAdder, &proc, &idleIDs](GrDirectContext* dContext, int num) {
-                    sk_sp<GrTexture> texture = m(dContext);
-                    texture->addIdleProc(proc, new Context{&idleIDs, num});
-                    keyAdder(texture.get());
-                    return texture;
-                };
-
-                auto texture = make(dContext, 1);
-                REPORTER_ASSERT(reporter, idleIDs.find(1) == idleIDs.end());
-                auto renderable = GrRenderable(SkToBool(texture->asRenderTarget()));
-                auto backendFormat = texture->backendFormat();
-                texture.reset();
-                REPORTER_ASSERT(reporter, idleIDs.find(1) != idleIDs.end());
-
-                texture = make(dContext, 2);
-                int w = texture->width();
-                int h = texture->height();
-                SkImageInfo info =
-                        SkImageInfo::Make(w, h, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
-                auto rt = SkSurface::MakeRenderTarget(dContext, SkBudgeted::kNo, info, 0, nullptr);
-                auto sdc = SkCanvasPriv::TopDeviceSurfaceDrawContext(rt->getCanvas());
-                auto singleUseLazyCB = [&texture](GrResourceProvider*,
-                                                  const GrSurfaceProxy::LazySurfaceDesc&) {
-                    auto mode = GrSurfaceProxy::LazyInstantiationKeyMode::kSynced;
-                    if (texture->getUniqueKey().isValid()) {
-                        mode = GrSurfaceProxy::LazyInstantiationKeyMode::kUnsynced;
-                    }
-                    return GrSurfaceProxy::LazyCallbackResult{std::move(texture), true, mode};
-                };
-                SkISize desc;
-                desc.fWidth = w;
-                desc.fHeight = h;
-                SkBudgeted budgeted;
-                if (texture->resourcePriv().budgetedType() == GrBudgetedType::kBudgeted) {
-                    budgeted = SkBudgeted::kYes;
-                } else {
-                    budgeted = SkBudgeted::kNo;
-                }
-                sk_sp<GrSurfaceProxy> proxy;
-                if (renderable == GrRenderable::kYes) {
-                    static const GrProxyProvider::TextureInfo kTexInfo = {GrMipMapped::kNo,
-                                                                          GrTextureType::k2D};
-                    proxy = dContext->priv().proxyProvider()->createLazyRenderTargetProxy(
-                            singleUseLazyCB, backendFormat, desc, 1,
-                            dContext->priv().caps()->getExtraSurfaceFlagsForDeferredRT(),
-                            &kTexInfo,
-                            GrMipmapStatus::kNotAllocated,
-                            SkBackingFit::kExact, budgeted, GrProtected::kNo, false,
-                            GrSurfaceProxy::UseAllocator::kYes);
-                } else {
-                    proxy = dContext->priv().proxyProvider()->createLazyProxy(
-                            singleUseLazyCB, backendFormat, desc, GrMipmapped::kNo,
-                            GrMipmapStatus::kNotAllocated, GrInternalSurfaceFlags ::kNone,
-                            SkBackingFit::kExact, budgeted, GrProtected::kNo,
-                            GrSurfaceProxy::UseAllocator::kYes);
-                }
-                GrSwizzle readSwizzle = dContext->priv().caps()->getReadSwizzle(
-                        backendFormat, GrColorType::kRGBA_8888);
-                GrSurfaceProxyView view(std::move(proxy), kTopLeft_GrSurfaceOrigin, readSwizzle);
-                sdc->drawTexture(nullptr,
-                                 view,
-                                 kPremul_SkAlphaType,
-                                 GrSamplerState::Filter::kNearest,
-                                 GrSamplerState::MipmapMode::kNone,
-                                 SkBlendMode::kSrcOver,
-                                 SkPMColor4f(),
-                                 SkRect::MakeWH(w, h),
-                                 SkRect::MakeWH(w, h),
-                                 GrAA::kNo,
-                                 GrQuadAAFlags::kNone,
-                                 SkCanvas::kFast_SrcRectConstraint,
-                                 SkMatrix::I(),
-                                 nullptr);
-                // We still have the proxy, which should remain instantiated, thereby keeping the
-                // texture not purgeable.
-                REPORTER_ASSERT(reporter, idleIDs.find(2) == idleIDs.end());
-                dContext->flushAndSubmit();
-                REPORTER_ASSERT(reporter, idleIDs.find(2) == idleIDs.end());
-                dContext->submit(true);
-                REPORTER_ASSERT(reporter, idleIDs.find(2) == idleIDs.end());
-
-                // This time we move the proxy into the draw.
-                sdc->drawTexture(nullptr,
-                                 std::move(view),
-                                 kPremul_SkAlphaType,
-                                 GrSamplerState::Filter::kNearest,
-                                 GrSamplerState::MipmapMode::kNone,
-                                 SkBlendMode::kSrcOver,
-                                 SkPMColor4f(),
-                                 SkRect::MakeWH(w, h),
-                                 SkRect::MakeWH(w, h),
-                                 GrAA::kNo,
-                                 GrQuadAAFlags::kNone,
-                                 SkCanvas::kFast_SrcRectConstraint,
-                                 SkMatrix::I(),
-                                 nullptr);
-                REPORTER_ASSERT(reporter, idleIDs.find(2) == idleIDs.end());
-                dContext->flushAndSubmit(true);
-                // Now that the draw is fully consumed by the GPU, the texture should be idle.
-                REPORTER_ASSERT(reporter, idleIDs.find(2) != idleIDs.end());
-
-                // Make sure we make the call during various shutdown scenarios where the texture
-                // might persist after context is destroyed, abandoned, etc. We test three
-                // variations of each scenario. One where the texture is just created. Another,
-                // where the texture has been used in a draw and then the context is flushed. And
-                // one where the the texture was drawn but the context is not flushed.
-                // In each scenario we test holding a ref beyond the context shutdown and not.
-
-                // These tests are difficult to get working with Vulkan, Direct3D, and Dawn.
-                // See http://skbug.com/8705, http://skbug.com/8277, and http://skbug.com/10326
-                GrBackendApi api = sk_gpu_test::GrContextFactory::ContextTypeBackend(contextType);
-                if (api == GrBackendApi::kVulkan || api == GrBackendApi::kDirect3D ||
-                    api == GrBackendApi::kDawn) {
-                    continue;
-                }
-                int id = 3;
-                enum class DrawType {
-                    kNoDraw,
-                    kDraw,
-                    kDrawAndFlush,
-                };
-                for (auto drawType :
-                     {DrawType::kNoDraw, DrawType::kDraw, DrawType::kDrawAndFlush}) {
-                    for (bool unrefFirst : {false, true}) {
-                        auto possiblyDrawAndFlush = [&dContext, &texture, drawType, unrefFirst, w,
-                                                     h] {
-                            if (drawType == DrawType::kNoDraw) {
-                                return;
-                            }
-                            SkImageInfo info = SkImageInfo::Make(w, h, kRGBA_8888_SkColorType,
-                                                                 kPremul_SkAlphaType);
-                            auto rt = SkSurface::MakeRenderTarget(dContext, SkBudgeted::kNo, info, 0,
-                                                                  nullptr);
-                            auto sdc = SkCanvasPriv::TopDeviceSurfaceDrawContext(rt->getCanvas());
-                            auto proxy = dContext->priv().proxyProvider()->testingOnly_createWrapped(
-                                    texture);
-                            GrSwizzle swizzle = dContext->priv().caps()->getReadSwizzle(
-                                    proxy->backendFormat(), GrColorType::kRGBA_8888);
-                            GrSurfaceProxyView view(std::move(proxy), kTopLeft_GrSurfaceOrigin,
-                                                    swizzle);
-                            sdc->drawTexture(nullptr,
-                                             std::move(view),
-                                             kPremul_SkAlphaType,
-                                             GrSamplerState::Filter::kNearest,
-                                             GrSamplerState::MipmapMode::kNone,
-                                             SkBlendMode::kSrcOver,
-                                             SkPMColor4f(),
-                                             SkRect::MakeWH(w, h),
-                                             SkRect::MakeWH(w, h),
-                                             GrAA::kNo,
-                                             GrQuadAAFlags::kNone,
-                                             SkCanvas::kFast_SrcRectConstraint,
-                                             SkMatrix::I(),
-                                             nullptr);
-                            if (drawType == DrawType::kDrawAndFlush) {
-                                dContext->flushAndSubmit();
-                            }
-                            if (unrefFirst) {
-                                texture.reset();
-                            }
-                        };
-                        texture = make(dContext, id);
-                        possiblyDrawAndFlush();
-                        dContext->abandonContext();
-                        texture.reset();
-                        REPORTER_ASSERT(reporter, idleIDs.find(id) != idleIDs.end());
-                        factory.destroyContexts();
-                        dContext = factory.get(contextType);
-                        ++id;
-
-                        // Similar to previous, but reset the texture after the context was
-                        // abandoned and then destroyed.
-                        texture = make(dContext, id);
-                        possiblyDrawAndFlush();
-                        dContext->abandonContext();
-                        factory.destroyContexts();
-                        texture.reset();
-                        REPORTER_ASSERT(reporter, idleIDs.find(id) != idleIDs.end());
-                        dContext = factory.get(contextType);
-                        id++;
-
-                        texture = make(dContext, id);
-                        possiblyDrawAndFlush();
-                        factory.destroyContexts();
-                        texture.reset();
-                        REPORTER_ASSERT(reporter, idleIDs.find(id) != idleIDs.end());
-                        dContext = factory.get(contextType);
-                        id++;
-
-                        texture = make(dContext, id);
-                        possiblyDrawAndFlush();
-                        factory.releaseResourcesAndAbandonContexts();
-                        texture.reset();
-                        REPORTER_ASSERT(reporter, idleIDs.find(id) != idleIDs.end());
-                        dContext = factory.get(contextType);
-                        id++;
-                    }
-                }
-            }
-        }
-    }
-}
-
-// Tests an idle proc that unrefs another resource down to zero.
-DEF_GPUTEST_FOR_ALL_CONTEXTS(TextureIdleProcCacheManipulationTest, reporter, contextInfo) {
-    auto context = contextInfo.directContext();
-
-    // idle proc that releases another texture.
-    auto idleProc = [](void* texture) { reinterpret_cast<GrTexture*>(texture)->unref(); };
-
-    for (const auto& idleMaker : {make_wrapped_texture, make_normal_texture}) {
-        for (const auto& otherMaker : {make_wrapped_texture, make_normal_texture}) {
-            auto idleTexture = idleMaker(context, GrRenderable::kNo);
-            auto otherTexture = otherMaker(context, GrRenderable::kNo);
-            otherTexture->ref();
-            idleTexture->addIdleProc(idleProc, otherTexture.get());
-            otherTexture.reset();
-            idleTexture.reset();
-        }
-    }
-}
-
-// Similar to above but more complicated. This flushes the context from the idle proc.
-// crbug.com/933526.
-DEF_GPUTEST_FOR_ALL_CONTEXTS(TextureIdleProcFlushTest, reporter, contextInfo) {
-    auto dContext = contextInfo.directContext();
-
-    // idle proc that flushes the context.
-    auto idleProc = [](void* context) {
-        reinterpret_cast<GrDirectContext*>(context)->flushAndSubmit();
-    };
-
-    for (const auto& idleMaker : {make_wrapped_texture, make_normal_texture}) {
-        auto idleTexture = idleMaker(dContext, GrRenderable::kNo);
-        idleTexture->addIdleProc(idleProc, dContext);
-        auto info = SkImageInfo::Make(10, 10, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
-        auto surf = SkSurface::MakeRenderTarget(dContext, SkBudgeted::kNo, info, 1, nullptr);
-        // We'll draw two images to the canvas. One is a normal texture-backed image. The other
-        // is a wrapped-texture backed image.
-        surf->getCanvas()->clear(SK_ColorWHITE);
-        auto img1 = surf->makeImageSnapshot();
-        auto img2 = sk_gpu_test::MakeBackendTextureImage(dContext, info, SkColors::kBlack);
-        REPORTER_ASSERT(reporter, img1 && img2);
-        surf->getCanvas()->drawImage(std::move(img1), 0, 0);
-        surf->getCanvas()->drawImage(std::move(img2), 1, 1);
-        idleTexture.reset();
-    }
-}
-
-DEF_GPUTEST_FOR_ALL_CONTEXTS(TextureIdleProcRerefTest, reporter, contextInfo) {
-    auto context = contextInfo.directContext();
-    // idle proc that refs the texture
-    auto idleProc = [](void* texture) { reinterpret_cast<GrTexture*>(texture)->ref(); };
-    // release proc to check whether the texture was released or not.
-    auto releaseProc = [](void* isReleased) { *reinterpret_cast<bool*>(isReleased) = true; };
-    bool isReleased = false;
-    auto idleTexture = make_normal_texture(context, GrRenderable::kNo);
-    // This test assumes the texture won't be cached (or else the release proc doesn't get
-    // called).
-    idleTexture->resourcePriv().removeScratchKey();
-    context->flushAndSubmit();
-    idleTexture->addIdleProc(idleProc, idleTexture.get());
-    idleTexture->setRelease(releaseProc, &isReleased);
-    auto* raw = idleTexture.get();
-    idleTexture.reset();
-    REPORTER_ASSERT(reporter, !isReleased);
-    raw->unref();
-    REPORTER_ASSERT(reporter, isReleased);
-}
-
-DEF_GPUTEST_FOR_ALL_CONTEXTS(TextureIdleStateTest, reporter, contextInfo) {
-    auto context = contextInfo.directContext();
-    for (const auto& idleMaker : {make_wrapped_texture, make_normal_texture}) {
-        auto idleTexture = idleMaker(context, GrRenderable::kNo);
-
-        bool called = false;
-        auto finishProc = [](void* called) { *static_cast<bool*>(called) = true; };
-        idleTexture->addIdleProc(finishProc, &called);
-
-        // Insert a copy from idleTexture to another texture so that we have some queued IO on
-        // idleTexture.
-        SkImageInfo info = SkImageInfo::Make(kSurfSize, kSurfSize, kRGBA_8888_SkColorType,
-                                             kPremul_SkAlphaType);
-        auto rt = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info, 0, nullptr);
-        auto sdc = SkCanvasPriv::TopDeviceSurfaceDrawContext(rt->getCanvas());
-        auto proxy =
-                context->priv().proxyProvider()->testingOnly_createWrapped(std::move(idleTexture));
-        context->flushAndSubmit();
-        SkAssertResult(sdc->testCopy(std::move(proxy)));
-        REPORTER_ASSERT(reporter, !called);
-
-        // After a flush we expect idleTexture to have reached the kFlushed state on all backends.
-        // On "managed" backends we expect it to reach kFinished as well. On Vulkan, the only
-        // current "unmanaged" backend, we *may* need a sync to reach kFinished.
-        context->flushAndSubmit();
-        if (contextInfo.backend() != kVulkan_GrBackend) {
-            REPORTER_ASSERT(reporter, called);
-        }
-        context->submit(true);
-        REPORTER_ASSERT(reporter, called);
-    }
-}
diff --git a/tools/run-wasm-gm-tests/run-wasm-gm-tests.html b/tools/run-wasm-gm-tests/run-wasm-gm-tests.html
index 1fbda89..5a59696 100644
--- a/tools/run-wasm-gm-tests/run-wasm-gm-tests.html
+++ b/tools/run-wasm-gm-tests/run-wasm-gm-tests.html
@@ -183,7 +183,6 @@
     'InitialTextureClear',
     'PinnedImageTest',
     'PromiseImageTextureShutdown',
-    'TextureIdleProcTest',
 
     // These tests time out
     'SkTraceMemoryDump_ownedGLRenderTarget',