[vulkan] Destroy devices and instances when HAL closes

bug: 111137294
Change-Id: I7fd7214c8b7b1bd5db121933f8e06d794d8235f4
diff --git a/system/vulkan/goldfish_vulkan.cpp b/system/vulkan/goldfish_vulkan.cpp
index 4e80c45..d0978d2 100644
--- a/system/vulkan/goldfish_vulkan.cpp
+++ b/system/vulkan/goldfish_vulkan.cpp
@@ -143,11 +143,6 @@
     },
 };
 
-int CloseDevice(struct hw_device_t* /*device*/) {
-    // nothing to do - opening a device doesn't allocate any resources
-    return 0;
-}
-
 #define VK_HOST_CONNECTION(ret) \
     HostConnection *hostCon = HostConnection::get(); \
     if (!hostCon) { \
@@ -167,6 +162,50 @@
     goldfish_vk::ResourceTracker::get()->setupFeatures(rcEnc->featureInfo_const()); \
     auto hostSupportsVulkan = goldfish_vk::ResourceTracker::get()->hostSupportsVulkan(); \
 
+int CloseDevice(struct hw_device_t* /*device*/) {
+    VK_HOST_CONNECTION(-1)
+
+    if (!hostSupportsVulkan) {
+        // nothing to do - opening a device doesn't allocate any resources
+        return 0;
+    }
+
+    goldfish_vk::TeardownFuncs teardownFuncs;
+    teardownFuncs.vkDeviceWaitIdle =
+        (PFN_vkDeviceWaitIdle)goldfish_vk::goldfish_vulkan_get_proc_address("vkDeviceWaitIdle");
+
+#define GET_TEARDOWN_PROC_ADDR(func) \
+    teardownFuncs.func = (PFN_##func)goldfish_vk::goldfish_vulkan_get_proc_address(#func);
+
+    GET_TEARDOWN_PROC_ADDR(vkDestroyInstance)
+    GET_TEARDOWN_PROC_ADDR(vkDestroyDevice)
+    GET_TEARDOWN_PROC_ADDR(vkDestroySemaphore)
+    GET_TEARDOWN_PROC_ADDR(vkDestroyFence)
+    GET_TEARDOWN_PROC_ADDR(vkFreeMemory)
+    GET_TEARDOWN_PROC_ADDR(vkDestroyBuffer)
+    GET_TEARDOWN_PROC_ADDR(vkDestroyImage)
+    GET_TEARDOWN_PROC_ADDR(vkDestroyEvent)
+    GET_TEARDOWN_PROC_ADDR(vkDestroyQueryPool)
+    GET_TEARDOWN_PROC_ADDR(vkDestroyBufferView)
+    GET_TEARDOWN_PROC_ADDR(vkDestroyImageView)
+    GET_TEARDOWN_PROC_ADDR(vkDestroyShaderModule)
+    GET_TEARDOWN_PROC_ADDR(vkDestroyPipelineCache)
+    GET_TEARDOWN_PROC_ADDR(vkDestroyPipelineLayout)
+    GET_TEARDOWN_PROC_ADDR(vkDestroyRenderPass)
+    GET_TEARDOWN_PROC_ADDR(vkDestroyPipeline)
+    GET_TEARDOWN_PROC_ADDR(vkDestroyDescriptorSetLayout)
+    GET_TEARDOWN_PROC_ADDR(vkDestroySampler)
+    GET_TEARDOWN_PROC_ADDR(vkDestroyDescriptorPool)
+    GET_TEARDOWN_PROC_ADDR(vkDestroyFramebuffer)
+    GET_TEARDOWN_PROC_ADDR(vkDestroyCommandPool)
+
+    goldfish_vk::ResourceTracker::get()->teardown(
+        (void*)vkEnc,
+        teardownFuncs);
+
+    return 0;
+}
+
 VKAPI_ATTR
 VkResult EnumerateInstanceExtensionProperties(
     const char* layer_name,
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index 3cacf39..31b4e6d 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -199,6 +199,23 @@
         info_VkDeviceMemory.erase(mem);
     }
 
+    void teardown(void* context, const TeardownFuncs& vk) {
+        VkEncoder* enc = (VkEncoder*)context;
+        // TODO
+        (void)enc;
+
+        for (auto it : info_VkDevice) {
+            auto device = it.first;
+            vk.vkDeviceWaitIdle(device);
+            vk.vkDestroyDevice(device, nullptr);
+        }
+
+        for (auto it : info_VkInstance) {
+            auto instance = it.first;
+            vk.vkDestroyInstance(instance, nullptr);
+        }
+    }
+
     // TODO: Upgrade to 1.1
     static constexpr uint32_t kMaxApiVersion = VK_MAKE_VERSION(1, 0, 65);
     static constexpr uint32_t kMinApiVersion = VK_MAKE_VERSION(1, 0, 0);
@@ -1107,6 +1124,12 @@
     return sTracker;
 }
 
+void ResourceTracker::teardown(
+        void* context,
+        const TeardownFuncs& funcs) {
+    mImpl->teardown(context, funcs);
+}
+
 #define HANDLE_REGISTER_IMPL(type) \
     void ResourceTracker::register_##type(type obj) { \
         mImpl->register_##type(obj); \
diff --git a/system/vulkan_enc/ResourceTracker.h b/system/vulkan_enc/ResourceTracker.h
index c63dfc0..7cc1cd7 100644
--- a/system/vulkan_enc/ResourceTracker.h
+++ b/system/vulkan_enc/ResourceTracker.h
@@ -24,11 +24,39 @@
 
 namespace goldfish_vk {
 
+struct TeardownFuncs {
+    PFN_vkDeviceWaitIdle vkDeviceWaitIdle = 0;
+    PFN_vkDestroyInstance vkDestroyInstance = 0;
+    PFN_vkDestroyDevice vkDestroyDevice = 0;
+    PFN_vkDestroySemaphore vkDestroySemaphore = 0;
+    PFN_vkDestroyFence vkDestroyFence = 0;
+    PFN_vkFreeMemory vkFreeMemory = 0;
+    PFN_vkDestroyBuffer vkDestroyBuffer = 0;
+    PFN_vkDestroyImage vkDestroyImage = 0;
+    PFN_vkDestroyEvent vkDestroyEvent = 0;
+    PFN_vkDestroyQueryPool vkDestroyQueryPool = 0;
+    PFN_vkDestroyBufferView vkDestroyBufferView = 0;
+    PFN_vkDestroyImageView vkDestroyImageView = 0;
+    PFN_vkDestroyShaderModule vkDestroyShaderModule = 0;
+    PFN_vkDestroyPipelineCache vkDestroyPipelineCache = 0;
+    PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout = 0;
+    PFN_vkDestroyRenderPass vkDestroyRenderPass = 0;
+    PFN_vkDestroyPipeline vkDestroyPipeline = 0;
+    PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout = 0;
+    PFN_vkDestroySampler vkDestroySampler = 0;
+    PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool = 0;
+    PFN_vkDestroyFramebuffer vkDestroyFramebuffer = 0;
+    PFN_vkDestroyCommandPool vkDestroyCommandPool = 0;
+};
+
 class ResourceTracker {
 public:
     ResourceTracker();
     virtual ~ResourceTracker();
     static ResourceTracker* get();
+    void teardown(
+        void* context,
+        const TeardownFuncs& teardownFuncs);
     VulkanHandleMapping* createMapping();
     VulkanHandleMapping* unwrapMapping();
     VulkanHandleMapping* destroyMapping();