Vulkan: fix CPU throttling frames to 2

Previously, the CPU was throttled to be at most N frames ahead, N being
the number of swapchain images.  N is now fixed to 2, regardless of the
number of swapchain images.  If N < 2, we would be stalling the CPU
unnecessarily, and if N > 2, the CPU could get too far ahead.

Effectively, here is how the throttling plays out with this commit:

Submit (Fence 1) + Present
Submit (Fence 2) + Present
Wait Fence 1
Submit (Fence 3) + Present
Wait Fence 2
Submit (Fence 4) + Present
Wait Fence 3
Submit (Fence 5) + Present
Wait Fence 4
...

Bug: angleproject:2942
Change-Id: I3b8c3bb88e52d62231306ec84aad50d2bf472d8c
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1558681
Reviewed-by: Ian Elliott <ianelliott@google.com>
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/SurfaceVk.cpp b/src/libANGLE/renderer/vulkan/SurfaceVk.cpp
index 8164a91..024111a 100644
--- a/src/libANGLE/renderer/vulkan/SurfaceVk.cpp
+++ b/src/libANGLE/renderer/vulkan/SurfaceVk.cpp
@@ -559,7 +559,6 @@
                  vkGetSwapchainImagesKHR(device, mSwapchain, &imageCount, swapchainImages.data()));
 
     mSwapchainImages.resize(imageCount);
-    ANGLE_TRY(resizeSwapHistory(displayVk, imageCount));
 
     for (uint32_t imageIndex = 0; imageIndex < imageCount; ++imageIndex)
     {
@@ -838,78 +837,6 @@
     return angle::Result::Continue;
 }
 
-angle::Result WindowSurfaceVk::resizeSwapHistory(DisplayVk *displayVk, size_t imageCount)
-{
-    // The number of swapchain images can change if the present mode is changed.  If that number is
-    // increased, we need to rearrange the history (which is a circular buffer) so it remains
-    // continuous.  If it shrinks, we have to additionally make sure we clean up any old swapchains
-    // that can no longer fit in the history.
-    //
-    // Assume the following history buffer identified with serials:
-    //
-    //   mCurrentSwapHistoryIndex
-    //           V
-    //   +----+----+----+
-    //   | 11 |  9 | 10 |
-    //   +----+----+----+
-    //
-    // When shrinking to size 2, we want to clean up 9, and rearrange to the following:
-    //
-    //   mCurrentSwapHistoryIndex
-    //      V
-    //   +----+----+
-    //   | 10 | 11 |
-    //   +----+----+
-    //
-    // When expanding back to 3, we want to rearrange to the following:
-    //
-    //   mCurrentSwapHistoryIndex
-    //      V
-    //   +----+----+----+
-    //   |  0 | 10 | 11 |
-    //   +----+----+----+
-
-    if (mSwapHistory.size() == imageCount)
-    {
-        return angle::Result::Continue;
-    }
-
-    RendererVk *renderer = displayVk->getRenderer();
-
-    // First, clean up anything that won't fit in the resized history.
-    if (imageCount < mSwapHistory.size())
-    {
-        size_t toClean = mSwapHistory.size() - imageCount;
-        for (size_t i = 0; i < toClean; ++i)
-        {
-            size_t historyIndex = (mCurrentSwapHistoryIndex + i) % mSwapHistory.size();
-            SwapHistory &swap   = mSwapHistory[historyIndex];
-
-            ANGLE_TRY(renderer->finishToSerial(displayVk, swap.serial));
-            swap.destroy(renderer->getDevice());
-        }
-    }
-
-    // Now, move the history, from most recent to oldest (as much as fits), into a new vector.
-    std::vector<SwapHistory> resizedHistory(imageCount);
-
-    size_t toCopy = std::min(imageCount, mSwapHistory.size());
-    for (size_t i = 0; i < toCopy; ++i)
-    {
-        size_t historyIndex =
-            (mCurrentSwapHistoryIndex + mSwapHistory.size() - i - 1) % mSwapHistory.size();
-        size_t resizedHistoryIndex          = imageCount - i - 1;
-        resizedHistory[resizedHistoryIndex] = std::move(mSwapHistory[historyIndex]);
-    }
-
-    // Set this as the new history.  Note that after rearranging in either case, the oldest history
-    // is at index 0.
-    mSwapHistory             = std::move(resizedHistory);
-    mCurrentSwapHistoryIndex = 0;
-
-    return angle::Result::Continue;
-}
-
 egl::Error WindowSurfaceVk::postSubBuffer(const gl::Context *context,
                                           EGLint x,
                                           EGLint y,
diff --git a/src/libANGLE/renderer/vulkan/SurfaceVk.h b/src/libANGLE/renderer/vulkan/SurfaceVk.h
index 8ea5290..886e902 100644
--- a/src/libANGLE/renderer/vulkan/SurfaceVk.h
+++ b/src/libANGLE/renderer/vulkan/SurfaceVk.h
@@ -163,7 +163,6 @@
                           EGLint n_rects,
                           bool &swapchainOutOfDate);
     angle::Result swapImpl(DisplayVk *displayVk, EGLint *rects, EGLint n_rects);
-    angle::Result resizeSwapHistory(DisplayVk *displayVk, size_t imageCount);
 
     VkSurfaceCapabilitiesKHR mSurfaceCaps;
     std::vector<VkPresentModeKHR> mPresentModes;
@@ -212,9 +211,9 @@
     // results cannot affect the images in a swap chain.
     std::vector<vk::Semaphore> mFlushSemaphoreChain;
 
-    // A circular buffer, with the same size as mSwapchainImages (N), that stores the serial of the
-    // renderer on every swap.  The CPU is throttled by waiting for the Nth previous serial to
-    // finish.  Old swapchains are scheduled to be destroyed at the same time.
+    // A circular buffer that stores the serial of the renderer on every swap.  The CPU is
+    // throttled by waiting for the 2nd previous serial to finish.  Old swapchains are scheduled to
+    // be destroyed at the same time.
     struct SwapHistory : angle::NonCopyable
     {
         SwapHistory();
@@ -228,7 +227,8 @@
         std::vector<vk::Semaphore> semaphores;
         VkSwapchainKHR swapchain = VK_NULL_HANDLE;
     };
-    std::vector<SwapHistory> mSwapHistory;
+    static constexpr size_t kSwapHistorySize = 2;
+    std::array<SwapHistory, kSwapHistorySize> mSwapHistory;
     size_t mCurrentSwapHistoryIndex;
 
     vk::ImageHelper mDepthStencilImage;