Hoist GrVkResource up so it can be used for D3D and Metal.

Bug: skia:9935
Change-Id: Ie13b9077c5db805020973e5cbab1aa8468c88742
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/276214
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
diff --git a/src/gpu/GrManagedResource.cpp b/src/gpu/GrManagedResource.cpp
new file mode 100644
index 0000000..df76a45
--- /dev/null
+++ b/src/gpu/GrManagedResource.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "src/gpu/GrManagedResource.h"
+
+#include "src/gpu/GrGpuResourcePriv.h"
+#include "src/gpu/GrTexture.h"
+
+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().hasRef()) {
+            // Wait for the texture to become idle in the cache to call the procs.
+            return;
+        }
+        fOwningTexture->callIdleProcsOnBehalfOfResource();
+    } else {
+        fIdleProcs.reset();
+    }
+}