[Impeller] re-enable AHB swapchain. (#53978)

Fixes https://github.com/flutter/flutter/issues/148139

Block on the CPU rather than immediately beginning encoding. Seems to fix the synchronization issues that we knew about. We need to find a way to use AHB swapchains, as it seems like correct synchronization via either SurfaceView or a SurfaceControl hierarchy will require exposing our rendering as a SurfaceTransaction.
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 b50972e..81af305 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
@@ -22,7 +22,7 @@
 /// The maximum number of presents pending in the compositor after which the
 /// acquire calls will block. This value is 2 images given to the system
 /// compositor and one for the raster thread, Because the semaphore is acquired
-/// when the CPU Begins working on the texture
+/// when the CPU begins working on the texture
 ///
 static constexpr const size_t kMaxPendingPresents = 3u;
 
@@ -68,7 +68,9 @@
   }
   transients_ = std::make_shared<SwapchainTransientsVK>(
       context, ToSwapchainTextureDescriptor(desc_), enable_msaa);
-  is_valid_ = true;
+
+  auto control = surface_control_.lock();
+  is_valid_ = control && control->IsValid();
 }
 
 AHBSwapchainImplVK::~AHBSwapchainImplVK() = default;
@@ -237,7 +239,7 @@
   return fence;
 }
 
-vk::UniqueSemaphore AHBSwapchainImplVK::CreateRenderReadySemaphore(
+vk::UniqueFence AHBSwapchainImplVK::CreateRenderReadyFence(
     const std::shared_ptr<fml::UniqueFD>& fd) const {
   if (!fd->is_valid()) {
     return {};
@@ -251,22 +253,22 @@
   const auto& context_vk = ContextVK::Cast(*context);
   const auto& device = context_vk.GetDevice();
 
-  auto signal_wait = device.createSemaphoreUnique({});
+  auto signal_wait = device.createFenceUnique({});
 
   if (signal_wait.result != vk::Result::eSuccess) {
     return {};
   }
 
-  context_vk.SetDebugName(*signal_wait.value, "AHBRenderReadySemaphore");
+  context_vk.SetDebugName(*signal_wait.value, "AHBRenderReadyFence");
 
-  vk::ImportSemaphoreFdInfoKHR import_info;
-  import_info.semaphore = *signal_wait.value;
+  vk::ImportFenceFdInfoKHR import_info;
+  import_info.fence = *signal_wait.value;
   import_info.fd = fd->get();
-  import_info.handleType = vk::ExternalSemaphoreHandleTypeFlagBits::eSyncFd;
+  import_info.handleType = vk::ExternalFenceHandleTypeFlagBits::eSyncFd;
   // From the spec: Sync FDs can only be imported temporarily.
-  import_info.flags = vk::SemaphoreImportFlagBitsKHR::eTemporary;
+  import_info.flags = vk::FenceImportFlagBitsKHR::eTemporary;
 
-  const auto import_result = device.importSemaphoreFdKHR(import_info);
+  const auto import_result = device.importFenceFdKHR(import_info);
 
   if (import_result != vk::Result::eSuccess) {
     VALIDATION_LOG << "Could not import semaphore FD: "
@@ -297,63 +299,20 @@
     return false;
   }
 
-  auto completion_fence =
-      ContextVK::Cast(*context).GetDevice().createFenceUnique({}).value;
-  if (!completion_fence) {
+  auto fence = CreateRenderReadyFence(render_ready_fence);
+
+  auto result = ContextVK::Cast(*context).GetDevice().waitForFences(
+      *fence,                               // fence
+      true,                                 // wait all
+      std::numeric_limits<uint64_t>::max()  // timeout (ns)
+  );
+
+  if (!(result == vk::Result::eSuccess || result == vk::Result::eTimeout)) {
+    VALIDATION_LOG << "Fence waiter encountered an unexpected error. Tearing "
+                      "down the waiter thread.";
     return false;
   }
 
-  auto command_buffer = context->CreateCommandBuffer();
-  if (!command_buffer) {
-    return false;
-  }
-  command_buffer->SetLabel("AHBSubmitWaitForRenderReadyCB");
-  const auto& encoder = CommandBufferVK::Cast(*command_buffer).GetEncoder();
-
-  const auto command_buffer_vk = encoder->GetCommandBuffer();
-
-  BarrierVK barrier;
-  barrier.cmd_buffer = command_buffer_vk;
-  barrier.new_layout = vk::ImageLayout::eColorAttachmentOptimal;
-  barrier.src_stage = vk::PipelineStageFlagBits::eBottomOfPipe;
-  barrier.src_access = {};
-  barrier.dst_stage = vk::PipelineStageFlagBits::eTopOfPipe;
-  barrier.dst_access = {};
-
-  if (!texture->SetLayout(barrier).ok()) {
-    return false;
-  }
-
-  auto render_ready_semaphore =
-      MakeSharedVK(CreateRenderReadySemaphore(render_ready_fence));
-  encoder->Track(render_ready_semaphore);
-
-  if (!encoder->EndCommandBuffer()) {
-    return false;
-  }
-
-  vk::SubmitInfo submit_info;
-
-  if (render_ready_semaphore) {
-    static constexpr const auto kWaitStages =
-        vk::PipelineStageFlagBits::eColorAttachmentOutput |
-        vk::PipelineStageFlagBits::eFragmentShader |
-        vk::PipelineStageFlagBits::eTransfer;
-    submit_info.setWaitSemaphores(render_ready_semaphore->Get());
-    submit_info.setWaitDstStageMask(kWaitStages);
-  }
-
-  submit_info.setCommandBuffers(command_buffer_vk);
-
-  auto result = ContextVK::Cast(*context).GetGraphicsQueue()->Submit(
-      submit_info, *completion_fence);
-  if (result != vk::Result::eSuccess) {
-    return false;
-  }
-
-  ContextVK::Cast(*context).GetFenceWaiter()->AddFence(
-      std::move(completion_fence), [encoder]() {});
-
   return true;
 }
 
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 72979cb..1c546fc 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
@@ -114,7 +114,7 @@
   bool Present(const AutoSemaSignaler& signaler,
                const std::shared_ptr<AHBTextureSourceVK>& texture);
 
-  vk::UniqueSemaphore CreateRenderReadySemaphore(
+  vk::UniqueFence CreateRenderReadyFence(
       const std::shared_ptr<fml::UniqueFD>& fd) const;
 
   bool SubmitWaitForRenderReady(
diff --git a/impeller/renderer/backend/vulkan/swapchain/swapchain_vk.cc b/impeller/renderer/backend/vulkan/swapchain/swapchain_vk.cc
index 279f2bf..534c1f8 100644
--- a/impeller/renderer/backend/vulkan/swapchain/swapchain_vk.cc
+++ b/impeller/renderer/backend/vulkan/swapchain/swapchain_vk.cc
@@ -55,28 +55,24 @@
     return nullptr;
   }
 
-  // TODO(148139): Fix synchronization issues on present.
-  if constexpr (false) {
-    // TODO(147533): AHB swapchains on emulators are not functional.
-    const auto emulator =
-        ContextVK::Cast(*context).GetDriverInfo()->IsEmulator();
+  // TODO(147533): AHB swapchains on emulators are not functional.
+  const auto emulator = ContextVK::Cast(*context).GetDriverInfo()->IsEmulator();
 
-    // Try AHB swapchains first.
-    if (!emulator && AHBSwapchainVK::IsAvailableOnPlatform()) {
-      auto ahb_swapchain = std::shared_ptr<AHBSwapchainVK>(new AHBSwapchainVK(
-          context,             //
-          window.GetHandle(),  //
-          surface,             //
-          window.GetSize(),    //
-          enable_msaa          //
-          ));
+  // Try AHB swapchains first.
+  if (!emulator && AHBSwapchainVK::IsAvailableOnPlatform()) {
+    auto ahb_swapchain = std::shared_ptr<AHBSwapchainVK>(new AHBSwapchainVK(
+        context,             //
+        window.GetHandle(),  //
+        surface,             //
+        window.GetSize(),    //
+        enable_msaa          //
+        ));
 
-      if (ahb_swapchain->IsValid()) {
-        return ahb_swapchain;
-      } else {
-        VALIDATION_LOG
-            << "Could not create AHB swapchain. Falling back to KHR variant.";
-      }
+    if (ahb_swapchain->IsValid()) {
+      return ahb_swapchain;
+    } else {
+      VALIDATION_LOG
+          << "Could not create AHB swapchain. Falling back to KHR variant.";
     }
   }