Make GrSemaphore a GrGpuResource

This makes semaphores get handled correctly when GrContext is abandoned or
asked to free all its resources.

Change-Id: I0b935bb95cf99b9acf647472bcd0231bb2759db6
Reviewed-on: https://skia-review.googlesource.com/150364
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/src/gpu/GrSemaphore.h b/src/gpu/GrSemaphore.h
index bdaf805..6023104 100644
--- a/src/gpu/GrSemaphore.h
+++ b/src/gpu/GrSemaphore.h
@@ -9,21 +9,31 @@
 #define GrSemaphore_DEFINED
 
 #include "GrBackendSemaphore.h"
-#include "SkRefCnt.h"
+#include "GrGpuResource.h"
 
-class GrGpu;
-
-class GrSemaphore : public SkRefCnt {
+/**
+ * Represents a semaphore-like GPU synchronization object. This is a slightly odd fit for
+ * GrGpuResource because we don't care about budgeting, recycling, or read/write references for
+ * these. However, making it a GrGpuResource makes it simpler to handle releasing/abandoning these
+ * along with other resources. If more cases like this arise we could consider moving some of the
+ * unused functionality off of GrGpuResource.
+ */
+class GrSemaphore : public GrGpuResource {
 public:
     // The derived class can return its GrBackendSemaphore. This is used when flushing with signal
     // semaphores so we can set the client's GrBackendSemaphore object after we've created the
     // internal semaphore.
     virtual GrBackendSemaphore backendSemaphore() const = 0;
 
-protected:
-    explicit GrSemaphore(const GrGpu* gpu) : fGpu(gpu) {}
+    const char* getResourceType() const override { return "semaphore"; }
 
-    const GrGpu* fGpu;
+protected:
+    explicit GrSemaphore(GrGpu* gpu) : INHERITED(gpu) {}
+
+private:
+    size_t onGpuMemorySize() const override { return 0; }
+
+    typedef GrGpuResource INHERITED;
 };
 
 #endif
diff --git a/src/gpu/gl/GrGLSemaphore.cpp b/src/gpu/gl/GrGLSemaphore.cpp
index c26b74e..b557efb 100644
--- a/src/gpu/gl/GrGLSemaphore.cpp
+++ b/src/gpu/gl/GrGLSemaphore.cpp
@@ -9,12 +9,20 @@
 
 #include "GrGLGpu.h"
 
-GrGLSemaphore::GrGLSemaphore(const GrGLGpu* gpu, bool isOwned)
-    : INHERITED(gpu), fSync(0), fIsOwned(isOwned) {
+GrGLSemaphore::GrGLSemaphore(GrGLGpu* gpu, bool isOwned)
+        : INHERITED(gpu), fSync(0), fIsOwned(isOwned) {
+    isOwned ? this->registerWithCache(SkBudgeted::kNo) : this->registerWithCacheWrapped();
 }
 
-GrGLSemaphore::~GrGLSemaphore() {
-    if (fIsOwned && fGpu) {
-        static_cast<const GrGLGpu*>(fGpu)->deleteSync(fSync);
+void GrGLSemaphore::onRelease() {
+    if (fSync && fIsOwned) {
+        static_cast<const GrGLGpu*>(this->getGpu())->deleteSync(fSync);
     }
+    fSync = 0;
+    INHERITED::onRelease();
+}
+
+void GrGLSemaphore::onAbandon() {
+    fSync = 0;
+    INHERITED::onAbandon();
 }
diff --git a/src/gpu/gl/GrGLSemaphore.h b/src/gpu/gl/GrGLSemaphore.h
index 6fd1a6f..851ae02 100644
--- a/src/gpu/gl/GrGLSemaphore.h
+++ b/src/gpu/gl/GrGLSemaphore.h
@@ -16,11 +16,11 @@
 
 class GrGLSemaphore : public GrSemaphore {
 public:
-    static sk_sp<GrGLSemaphore> Make(const GrGLGpu* gpu, bool isOwned) {
+    static sk_sp<GrGLSemaphore> Make(GrGLGpu* gpu, bool isOwned) {
         return sk_sp<GrGLSemaphore>(new GrGLSemaphore(gpu, isOwned));
     }
 
-    static sk_sp<GrGLSemaphore> MakeWrapped(const GrGLGpu* gpu,
+    static sk_sp<GrGLSemaphore> MakeWrapped(GrGLGpu* gpu,
                                             GrGLsync sync,
                                             GrWrapOwnership ownership) {
         auto sema = sk_sp<GrGLSemaphore>(new GrGLSemaphore(gpu,
@@ -29,8 +29,6 @@
         return sema;
     }
 
-    ~GrGLSemaphore() override;
-
     GrGLsync sync() const { return fSync; }
     void setSync(const GrGLsync& sync) { fSync = sync; }
 
@@ -41,8 +39,10 @@
     }
 
 private:
-    GrGLSemaphore(const GrGLGpu* gpu, bool isOwned);
+    GrGLSemaphore(GrGLGpu* gpu, bool isOwned);
 
+    void onRelease() override;
+    void onAbandon() override;
 
     GrGLsync fSync;
     bool     fIsOwned;
diff --git a/src/gpu/vk/GrVkSemaphore.cpp b/src/gpu/vk/GrVkSemaphore.cpp
index 7a56391..ef53b30 100644
--- a/src/gpu/vk/GrVkSemaphore.cpp
+++ b/src/gpu/vk/GrVkSemaphore.cpp
@@ -16,7 +16,7 @@
 #undef CreateSemaphore
 #endif
 
-sk_sp<GrVkSemaphore> GrVkSemaphore::Make(const GrVkGpu* gpu, bool isOwned) {
+sk_sp<GrVkSemaphore> GrVkSemaphore::Make(GrVkGpu* gpu, bool isOwned) {
     VkSemaphoreCreateInfo createInfo;
     memset(&createInfo, 0, sizeof(VkSemaphoreCreateInfo));
     createInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
@@ -29,7 +29,7 @@
     return sk_sp<GrVkSemaphore>(new GrVkSemaphore(gpu, semaphore, false, false, isOwned));
 }
 
-sk_sp<GrVkSemaphore> GrVkSemaphore::MakeWrapped(const GrVkGpu* gpu,
+sk_sp<GrVkSemaphore> GrVkSemaphore::MakeWrapped(GrVkGpu* gpu,
                                                 VkSemaphore semaphore,
                                                 WrapType wrapType,
                                                 GrWrapOwnership ownership) {
@@ -42,18 +42,27 @@
                                                   kBorrow_GrWrapOwnership != ownership));
 }
 
-GrVkSemaphore::GrVkSemaphore(const GrVkGpu* gpu, VkSemaphore semaphore, bool prohibitSignal,
+GrVkSemaphore::GrVkSemaphore(GrVkGpu* gpu, VkSemaphore semaphore, bool prohibitSignal,
                              bool prohibitWait, bool isOwned)
         : INHERITED(gpu) {
     fResource = new Resource(semaphore, prohibitSignal, prohibitWait, isOwned);
+    isOwned ? this->registerWithCache(SkBudgeted::kNo) : this->registerWithCacheWrapped();
 }
 
-GrVkSemaphore::~GrVkSemaphore() {
-    if (fGpu) {
-        fResource->unref(static_cast<const GrVkGpu*>(fGpu));
-    } else {
-        fResource->unrefAndAbandon();
+void GrVkSemaphore::onRelease() {
+    if (fResource) {
+        fResource->unref(static_cast<const GrVkGpu*>(this->getGpu()));
+        fResource = nullptr;
     }
+    INHERITED::onRelease();
+}
+
+void GrVkSemaphore::onAbandon() {
+    if (fResource) {
+        fResource->unrefAndAbandon();
+        fResource = nullptr;
+    }
+    INHERITED::onAbandon();
 }
 
 void GrVkSemaphore::Resource::freeGPUData(const GrVkGpu* gpu) const {
diff --git a/src/gpu/vk/GrVkSemaphore.h b/src/gpu/vk/GrVkSemaphore.h
index 58e5080..a334d99 100644
--- a/src/gpu/vk/GrVkSemaphore.h
+++ b/src/gpu/vk/GrVkSemaphore.h
@@ -20,17 +20,15 @@
 
 class GrVkSemaphore : public GrSemaphore {
 public:
-    static sk_sp<GrVkSemaphore> Make(const GrVkGpu* gpu, bool isOwned);
+    static sk_sp<GrVkSemaphore> Make(GrVkGpu* gpu, bool isOwned);
 
     using WrapType = GrResourceProvider::SemaphoreWrapType;
 
-    static sk_sp<GrVkSemaphore> MakeWrapped(const GrVkGpu* gpu,
+    static sk_sp<GrVkSemaphore> MakeWrapped(GrVkGpu* gpu,
                                             VkSemaphore semaphore,
                                             WrapType wrapType,
                                             GrWrapOwnership);
 
-    ~GrVkSemaphore() override;
-
     GrBackendSemaphore backendSemaphore() const override;
 
     class Resource : public GrVkResource {
@@ -89,9 +87,12 @@
     Resource* getResource() { return fResource; }
 
 private:
-    GrVkSemaphore(const GrVkGpu* gpu, VkSemaphore semaphore, bool prohibitSignal, bool prohibitWait,
+    GrVkSemaphore(GrVkGpu* gpu, VkSemaphore semaphore, bool prohibitSignal, bool prohibitWait,
                   bool isOwned);
 
+    void onRelease() override;
+    void onAbandon() override;
+
     Resource* fResource;
 
     typedef GrSemaphore INHERITED;