Vulkan: Remove ImageHelper::mImageAndViewGarbage

This was introduced in crrev.com/c/3449450. At that time this is
necessary, because we can not copy mUse for immediate view garbage
collection. Now with recent work, mUse is copyable, we no longer need to
accumulate the view garbage. They can be released immediately with a
copy of image's mUse.

Bug: b/261737134
Change-Id: Ic4393f8c4ee7c0e3be4669a0a557507c909a77ab
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4087323
Reviewed-by: Yuxin Hu <yuxinhu@google.com>
Commit-Queue: Charlie Lao <cclao@google.com>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp b/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp
index 33f32cc..37343f8 100644
--- a/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp
+++ b/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp
@@ -306,8 +306,8 @@
     else
     {
         mRenderTarget.release(contextVk);
-        mImage->collectViewGarbage(renderer, &mImageViews);
-        mImage->collectViewGarbage(renderer, &mMultisampledImageViews);
+        mImageViews.release(renderer, mImage->getResourceUse());
+        mMultisampledImageViews.release(renderer, mImage->getResourceUse());
     }
 
     if (mImage && mOwnsImage)
diff --git a/src/libANGLE/renderer/vulkan/SurfaceVk.cpp b/src/libANGLE/renderer/vulkan/SurfaceVk.cpp
index 852dc2b..d04e770 100644
--- a/src/libANGLE/renderer/vulkan/SurfaceVk.cpp
+++ b/src/libANGLE/renderer/vulkan/SurfaceVk.cpp
@@ -520,7 +520,7 @@
     DisplayVk *displayVk = vk::GetImpl(display);
     RendererVk *renderer = displayVk->getRenderer();
     // Front end must ensure all usage has been submitted.
-    image.collectViewGarbage(renderer, &imageViews);
+    imageViews.release(renderer, image.getResourceUse());
     image.releaseImage(renderer);
     image.releaseStagedUpdates(renderer);
 }
@@ -1591,14 +1591,14 @@
 
     if (mDepthStencilImage.valid())
     {
-        mDepthStencilImage.collectViewGarbage(renderer, &mDepthStencilImageViews);
+        mDepthStencilImageViews.release(renderer, mDepthStencilImage.getResourceUse());
         mDepthStencilImage.releaseImageFromShareContexts(renderer, contextVk);
         mDepthStencilImage.releaseStagedUpdates(renderer);
     }
 
     if (mColorImageMS.valid())
     {
-        mColorImageMS.collectViewGarbage(renderer, &mColorImageMSViews);
+        mColorImageMSViews.release(renderer, mColorImageMS.getResourceUse());
         mColorImageMS.releaseImageFromShareContexts(renderer, contextVk);
         mColorImageMS.releaseStagedUpdates(renderer);
         contextVk->addGarbage(&mFramebufferMS);
@@ -1608,8 +1608,7 @@
 
     for (SwapchainImage &swapchainImage : mSwapchainImages)
     {
-        swapchainImage.image.collectViewGarbage(renderer, &swapchainImage.imageViews);
-        swapchainImage.image.releaseImageAndViewGarbage(renderer);
+        swapchainImage.imageViews.release(renderer, swapchainImage.image.getResourceUse());
         // We don't own the swapchain image handles, so we just remove our reference to it.
         swapchainImage.image.resetImageWeakReference();
         swapchainImage.image.destroy(renderer);
diff --git a/src/libANGLE/renderer/vulkan/TextureVk.cpp b/src/libANGLE/renderer/vulkan/TextureVk.cpp
index 1a88259..476543d 100644
--- a/src/libANGLE/renderer/vulkan/TextureVk.cpp
+++ b/src/libANGLE/renderer/vulkan/TextureVk.cpp
@@ -3292,7 +3292,7 @@
 
     for (vk::ImageViewHelper &imageViewHelper : mMultisampledImageViews)
     {
-        mImage->collectViewGarbage(renderer, &imageViewHelper);
+        imageViewHelper.release(renderer, mImage->getResourceUse());
     }
 
     for (auto &renderTargets : mSingleLayerRenderTargets)
@@ -3604,7 +3604,7 @@
     else
     {
         RendererVk *renderer = contextVk->getRenderer();
-        mImage->collectViewGarbage(renderer, &imageView);
+        imageView.release(renderer, mImage->getResourceUse());
 
         for (auto &renderTargets : mSingleLayerRenderTargets)
         {
diff --git a/src/libANGLE/renderer/vulkan/VkImageImageSiblingVk.cpp b/src/libANGLE/renderer/vulkan/VkImageImageSiblingVk.cpp
index 8d0fe0b..24b9177 100644
--- a/src/libANGLE/renderer/vulkan/VkImageImageSiblingVk.cpp
+++ b/src/libANGLE/renderer/vulkan/VkImageImageSiblingVk.cpp
@@ -131,7 +131,6 @@
     {
         // TODO: Handle the case where the EGLImage is used in two contexts not in the same share
         // group.  https://issuetracker.google.com/169868803
-        mImage->releaseImageAndViewGarbage(renderer);
         mImage->resetImageWeakReference();
         mImage->destroy(renderer);
         SafeDelete(mImage);
diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.cpp b/src/libANGLE/renderer/vulkan/vk_helpers.cpp
index 6c507df..d3ec7c9 100644
--- a/src/libANGLE/renderer/vulkan/vk_helpers.cpp
+++ b/src/libANGLE/renderer/vulkan/vk_helpers.cpp
@@ -4950,7 +4950,6 @@
       mCurrentSingleClearValue(std::move(other.mCurrentSingleClearValue)),
       mContentDefined(std::move(other.mContentDefined)),
       mStencilContentDefined(std::move(other.mStencilContentDefined)),
-      mImageAndViewGarbage(std::move(other.mImageAndViewGarbage)),
       mAllocationSize(std::move(other.mAllocationSize)),
       mMemoryAllocationType(std::move(other.mMemoryAllocationType))
 {
@@ -5359,11 +5358,9 @@
                                   mDeviceMemory.getHandle());
     }
 
-    CollectGarbage(&mImageAndViewGarbage, &mImage, &mDeviceMemory);
-    // Notify us if the application pattern causes the views to keep getting reallocated and create
-    // infinite garbage
-    ASSERT(mImageAndViewGarbage.size() <= 1000);
-    releaseImageAndViewGarbage(renderer);
+    renderer->collectGarbage(mUse, &mImage, &mDeviceMemory);
+    mUse.reset();
+    mImageSerial = kInvalidImageSerial;
     setEntireContentUndefined();
 }
 
@@ -5381,18 +5378,6 @@
     releaseImage(renderer);
 }
 
-void ImageHelper::collectViewGarbage(RendererVk *renderer, vk::ImageViewHelper *imageView)
-{
-    imageView->release(renderer, mImageAndViewGarbage);
-    // If we do not have any ImageHelper::mUse retained in ResourceUseList, make a cloned copy of
-    // ImageHelper::mUse and use it to free any garbage in mImageAndViewGarbage immediately.
-    if (!mImageAndViewGarbage.empty())
-    {
-        renderer->collectGarbage(mUse, std::move(mImageAndViewGarbage));
-    }
-    ASSERT(mImageAndViewGarbage.size() <= 1000);
-}
-
 void ImageHelper::releaseStagedUpdates(RendererVk *renderer)
 {
     ASSERT(validateSubresourceUpdateRefCountsConsistent());
@@ -5420,16 +5405,6 @@
     mRotatedAspectRatio = false;
 }
 
-void ImageHelper::releaseImageAndViewGarbage(RendererVk *renderer)
-{
-    if (!mImageAndViewGarbage.empty())
-    {
-        renderer->collectGarbage(mUse, std::move(mImageAndViewGarbage));
-    }
-    mUse.reset();
-    mImageSerial = kInvalidImageSerial;
-}
-
 angle::Result ImageHelper::initializeNonZeroMemory(Context *context,
                                                    bool hasProtectedContent,
                                                    VkDeviceSize size)
@@ -5757,20 +5732,14 @@
 
 void ImageHelper::destroy(RendererVk *renderer)
 {
+    VkDevice device = renderer->getDevice();
+
     if (mImage.valid())
     {
         renderer->onMemoryDealloc(mMemoryAllocationType, mAllocationSize,
                                   mDeviceMemory.getHandle());
     }
 
-    // destroy any pending garbage objects (most likely from ImageViewHelper) at this point
-    for (GarbageObject &object : mImageAndViewGarbage)
-    {
-        object.destroy(renderer);
-    }
-
-    VkDevice device = renderer->getDevice();
-
     mImage.destroy(device);
     mDeviceMemory.destroy(device);
     mCurrentLayout = ImageLayout::Undefined;
@@ -7793,7 +7762,6 @@
     prevImage->get().mImageSerial                 = mImageSerial;
     prevImage->get().mAllocationSize              = mAllocationSize;
     prevImage->get().mMemoryAllocationType        = mMemoryAllocationType;
-    prevImage->get().mImageAndViewGarbage         = std::move(mImageAndViewGarbage);
 
     // Reset information for current (invalid) image.
     mCurrentLayout               = ImageLayout::Undefined;
@@ -9534,10 +9502,11 @@
     }
 }
 
-void ImageViewHelper::release(RendererVk *renderer, std::vector<vk::GarbageObject> &garbage)
+void ImageViewHelper::release(RendererVk *renderer, const ResourceUse &use)
 {
     mCurrentBaseMaxLevelHash = 0;
 
+    std::vector<vk::GarbageObject> garbage;
     // Release the read views
     ReleaseImageViews(&mPerLevelRangeLinearReadImageViews, &garbage);
     ReleaseImageViews(&mPerLevelRangeSRGBReadImageViews, &garbage);
@@ -9595,6 +9564,11 @@
     }
     mLayerLevelStorageImageViews.clear();
 
+    if (!garbage.empty())
+    {
+        renderer->collectGarbage(use, std::move(garbage));
+    }
+
     // Update image view serial.
     mImageViewSerial = renderer->getResourceSerialFactory().generateImageOrBufferViewSerial();
 }
diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.h b/src/libANGLE/renderer/vulkan/vk_helpers.h
index ed594f6..bf26bcc 100644
--- a/src/libANGLE/renderer/vulkan/vk_helpers.h
+++ b/src/libANGLE/renderer/vulkan/vk_helpers.h
@@ -1829,7 +1829,6 @@
     // Similar to releaseImage, but also notify all contexts in the same share group to stop
     // accessing to it.
     void releaseImageFromShareContexts(RendererVk *renderer, ContextVk *contextVk);
-    void collectViewGarbage(RendererVk *renderer, vk::ImageViewHelper *imageView);
     void releaseStagedUpdates(RendererVk *renderer);
 
     bool valid() const { return mImage.valid(); }
@@ -1849,7 +1848,6 @@
                              GLint samples,
                              bool isRobustResourceInitEnabled);
     void resetImageWeakReference();
-    void releaseImageAndViewGarbage(RendererVk *renderer);
 
     const Image &getImage() const { return mImage; }
     const DeviceMemory &getDeviceMemory() const { return mDeviceMemory; }
@@ -2613,8 +2611,6 @@
     gl::TexLevelArray<LevelContentDefinedMask> mContentDefined;
     gl::TexLevelArray<LevelContentDefinedMask> mStencilContentDefined;
 
-    std::vector<vk::GarbageObject> mImageAndViewGarbage;
-
     // Used for memory allocation tracking.
     // Memory size allocated for the image in the memory during the initialization.
     VkDeviceSize mAllocationSize;
@@ -2828,7 +2824,7 @@
 
     bool isImageViewGarbageEmpty() const;
 
-    void release(RendererVk *renderer, std::vector<vk::GarbageObject> &garbage);
+    void release(RendererVk *renderer, const ResourceUse &use);
 
   private:
     ImageView &getReadImageView()