[Impeller] Size AHB swapchain based on vk surface properties. (#52692)

Pixel 4 uses 4 images, 7 Pro uses ... 6 actually.

https://github.com/flutter/flutter/issues/147721
diff --git a/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_impl_vk.cc b/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_impl_vk.cc
index 0212d0c..b50972e 100644
--- a/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_impl_vk.cc
+++ b/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_impl_vk.cc
@@ -44,9 +44,11 @@
     const std::weak_ptr<Context>& context,
     std::weak_ptr<android::SurfaceControl> surface_control,
     const ISize& size,
-    bool enable_msaa) {
-  auto impl = std::shared_ptr<AHBSwapchainImplVK>(new AHBSwapchainImplVK(
-      context, std::move(surface_control), size, enable_msaa));
+    bool enable_msaa,
+    size_t swapchain_image_count) {
+  auto impl = std::shared_ptr<AHBSwapchainImplVK>(
+      new AHBSwapchainImplVK(context, std::move(surface_control), size,
+                             enable_msaa, swapchain_image_count));
   return impl->IsValid() ? impl : nullptr;
 }
 
@@ -54,11 +56,13 @@
     const std::weak_ptr<Context>& context,
     std::weak_ptr<android::SurfaceControl> surface_control,
     const ISize& size,
-    bool enable_msaa)
+    bool enable_msaa,
+    size_t swapchain_image_count)
     : surface_control_(std::move(surface_control)),
       pending_presents_(std::make_shared<fml::Semaphore>(kMaxPendingPresents)) {
   desc_ = android::HardwareBufferDescriptor::MakeForSwapchainImage(size);
-  pool_ = std::make_shared<AHBTexturePoolVK>(context, desc_);
+  pool_ =
+      std::make_shared<AHBTexturePoolVK>(context, desc_, swapchain_image_count);
   if (!pool_->IsValid()) {
     return;
   }
@@ -245,7 +249,6 @@
   }
 
   const auto& context_vk = ContextVK::Cast(*context);
-
   const auto& device = context_vk.GetDevice();
 
   auto signal_wait = device.createSemaphoreUnique({});
diff --git a/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_impl_vk.h b/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_impl_vk.h
index f865efc..72979cb 100644
--- a/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_impl_vk.h
+++ b/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_impl_vk.h
@@ -51,7 +51,8 @@
       const std::weak_ptr<Context>& context,
       std::weak_ptr<android::SurfaceControl> surface_control,
       const ISize& size,
-      bool enable_msaa);
+      bool enable_msaa,
+      size_t swapchain_image_count);
 
   ~AHBSwapchainImplVK();
 
@@ -107,7 +108,8 @@
       const std::weak_ptr<Context>& context,
       std::weak_ptr<android::SurfaceControl> surface_control,
       const ISize& size,
-      bool enable_msaa);
+      bool enable_msaa,
+      size_t swapchain_image_count);
 
   bool Present(const AutoSemaSignaler& signaler,
                const std::shared_ptr<AHBTextureSourceVK>& texture);
diff --git a/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_vk.cc b/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_vk.cc
index 2532a36..ad805a0 100644
--- a/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_vk.cc
+++ b/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_vk.cc
@@ -5,8 +5,10 @@
 #include "impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_vk.h"
 
 #include "flutter/fml/trace_event.h"
+#include "impeller/renderer/backend/vulkan/context_vk.h"
 #include "impeller/renderer/backend/vulkan/formats_vk.h"
 #include "impeller/renderer/backend/vulkan/swapchain/ahb/ahb_formats.h"
+#include "third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vulkan_enums.hpp"
 
 namespace impeller {
 
@@ -17,12 +19,26 @@
 
 AHBSwapchainVK::AHBSwapchainVK(const std::shared_ptr<Context>& context,
                                ANativeWindow* window,
+                               vk::UniqueSurfaceKHR surface,
                                const ISize& size,
                                bool enable_msaa)
     : context_(context),
       surface_control_(
           std::make_shared<android::SurfaceControl>(window, "ImpellerSurface")),
       enable_msaa_(enable_msaa) {
+  const auto [caps_result, surface_caps] =
+      ContextVK::Cast(*context).GetPhysicalDevice().getSurfaceCapabilitiesKHR(
+          *surface);
+  if (caps_result == vk::Result::eSuccess) {
+    swapchain_image_count_ =
+        std::clamp(surface_caps.minImageCount + 1u,  // preferred image count
+                   surface_caps.minImageCount,       // min count cannot be zero
+                   surface_caps.maxImageCount == 0u
+                       ? surface_caps.minImageCount + 1u
+                       : surface_caps.maxImageCount  // max zero means no limit
+        );
+  }
+
   UpdateSurfaceSize(size);
 }
 
@@ -56,10 +72,11 @@
     return;
   }
   TRACE_EVENT0("impeller", __FUNCTION__);
-  auto impl = AHBSwapchainImplVK::Create(context_,          //
-                                         surface_control_,  //
-                                         size,              //
-                                         enable_msaa_       //
+  auto impl = AHBSwapchainImplVK::Create(context_,               //
+                                         surface_control_,       //
+                                         size,                   //
+                                         enable_msaa_,           //
+                                         swapchain_image_count_  //
   );
   if (!impl || !impl->IsValid()) {
     VALIDATION_LOG << "Could not resize swapchain to size: " << size;
diff --git a/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_vk.h b/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_vk.h
index b95e1c2..a3b330f 100644
--- a/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_vk.h
+++ b/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_vk.h
@@ -52,10 +52,12 @@
   std::weak_ptr<Context> context_;
   std::shared_ptr<android::SurfaceControl> surface_control_;
   const bool enable_msaa_;
+  size_t swapchain_image_count_ = 3u;
   std::shared_ptr<AHBSwapchainImplVK> impl_;
 
   explicit AHBSwapchainVK(const std::shared_ptr<Context>& context,
                           ANativeWindow* window,
+                          vk::UniqueSurfaceKHR surface,
                           const ISize& size,
                           bool enable_msaa);
 };
diff --git a/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_texture_pool_vk.h b/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_texture_pool_vk.h
index 19429ad..f6d3840 100644
--- a/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_texture_pool_vk.h
+++ b/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_texture_pool_vk.h
@@ -9,7 +9,6 @@
 
 #include "flutter/fml/unique_fd.h"
 #include "impeller/base/thread.h"
-#include "impeller/base/timing.h"
 #include "impeller/renderer/backend/vulkan/android/ahb_texture_source_vk.h"
 
 namespace impeller {
@@ -30,14 +29,12 @@
 class AHBTexturePoolVK {
  public:
   struct PoolEntry {
-    TimePoint last_access_time;
     std::shared_ptr<AHBTextureSourceVK> texture;
     std::shared_ptr<fml::UniqueFD> render_ready_fence;
 
     explicit PoolEntry(std::shared_ptr<AHBTextureSourceVK> p_item,
                        fml::UniqueFD p_render_ready_fence = {})
-        : last_access_time(Clock::now()),
-          texture(std::move(p_item)),
+        : texture(std::move(p_item)),
           render_ready_fence(std::make_shared<fml::UniqueFD>(
               std::move(p_render_ready_fence))) {}
 
diff --git a/impeller/renderer/backend/vulkan/swapchain/swapchain_vk.cc b/impeller/renderer/backend/vulkan/swapchain/swapchain_vk.cc
index 70e9553..a777e66 100644
--- a/impeller/renderer/backend/vulkan/swapchain/swapchain_vk.cc
+++ b/impeller/renderer/backend/vulkan/swapchain/swapchain_vk.cc
@@ -44,6 +44,17 @@
     return nullptr;
   }
 
+  vk::AndroidSurfaceCreateInfoKHR surface_info;
+  surface_info.setWindow(window.GetHandle());
+  auto [result, surface] =
+      ContextVK::Cast(*context).GetInstance().createAndroidSurfaceKHRUnique(
+          surface_info);
+  if (result != vk::Result::eSuccess) {
+    VALIDATION_LOG << "Could not create KHR Android Surface: "
+                   << vk::to_string(result);
+    return nullptr;
+  }
+
   // TODO(147533): AHB swapchains on emulators are not functional.
   const auto emulator = ContextVK::Cast(*context).GetDriverInfo()->IsEmulator();
 
@@ -52,6 +63,7 @@
     auto ahb_swapchain = std::shared_ptr<AHBSwapchainVK>(new AHBSwapchainVK(
         context,             //
         window.GetHandle(),  //
+        std::move(surface),  //
         window.GetSize(),    //
         enable_msaa          //
         ));
@@ -65,16 +77,6 @@
   }
 
   // Fallback to KHR swapchains if AHB swapchains aren't available.
-  vk::AndroidSurfaceCreateInfoKHR surface_info;
-  surface_info.setWindow(window.GetHandle());
-  auto [result, surface] =
-      ContextVK::Cast(*context).GetInstance().createAndroidSurfaceKHRUnique(
-          surface_info);
-  if (result != vk::Result::eSuccess) {
-    VALIDATION_LOG << "Could not create KHR Android Surface: "
-                   << vk::to_string(result);
-    return nullptr;
-  }
   return Create(context, std::move(surface), window.GetSize(), enable_msaa);
 }
 #endif  // FML_OS_ANDROID