diff --git a/impeller/renderer/backend/vulkan/swapchain_impl_vk.cc b/impeller/renderer/backend/vulkan/swapchain_impl_vk.cc index 81a3a39c7b5ce..bb58edb7f3160 100644 --- a/impeller/renderer/backend/vulkan/swapchain_impl_vk.cc +++ b/impeller/renderer/backend/vulkan/swapchain_impl_vk.cc @@ -392,88 +392,97 @@ bool SwapchainImplVK::Present(const std::shared_ptr& image, } const auto& context = ContextVK::Cast(*context_strong); + context.GetConcurrentWorkerTaskRunner()->PostTask( + [&, index, image, current_frame = current_frame_] { + auto context_strong = context_.lock(); + if (!context_strong) { + return; + } + const auto& context = ContextVK::Cast(*context_strong); + const auto& sync = synchronizers_[current_frame]; + + //---------------------------------------------------------------------------- + /// Transition the image to color-attachment-optimal. + /// + sync->final_cmd_buffer = context.CreateCommandBuffer(); + if (!sync->final_cmd_buffer) { + return; + } - const auto& sync = synchronizers_[current_frame_]; - - //---------------------------------------------------------------------------- - /// Transition the image to color-attachment-optimal. - /// - sync->final_cmd_buffer = context.CreateCommandBuffer(); - if (!sync->final_cmd_buffer) { - return false; - } - - auto vk_final_cmd_buffer = CommandBufferVK::Cast(*sync->final_cmd_buffer) - .GetEncoder() - ->GetCommandBuffer(); - { - BarrierVK barrier; - barrier.new_layout = vk::ImageLayout::ePresentSrcKHR; - barrier.cmd_buffer = vk_final_cmd_buffer; - barrier.src_access = vk::AccessFlagBits::eColorAttachmentWrite; - barrier.src_stage = vk::PipelineStageFlagBits::eColorAttachmentOutput; - barrier.dst_access = {}; - barrier.dst_stage = vk::PipelineStageFlagBits::eBottomOfPipe; - - if (!image->SetLayout(barrier)) { - return false; - } - - if (vk_final_cmd_buffer.end() != vk::Result::eSuccess) { - return false; - } - } + auto vk_final_cmd_buffer = + CommandBufferVK::Cast(*sync->final_cmd_buffer) + .GetEncoder() + ->GetCommandBuffer(); + { + BarrierVK barrier; + barrier.new_layout = vk::ImageLayout::ePresentSrcKHR; + barrier.cmd_buffer = vk_final_cmd_buffer; + barrier.src_access = vk::AccessFlagBits::eColorAttachmentWrite; + barrier.src_stage = vk::PipelineStageFlagBits::eColorAttachmentOutput; + barrier.dst_access = {}; + barrier.dst_stage = vk::PipelineStageFlagBits::eBottomOfPipe; + + if (!image->SetLayout(barrier)) { + return; + } + + if (vk_final_cmd_buffer.end() != vk::Result::eSuccess) { + return; + } + } - //---------------------------------------------------------------------------- - /// Signal that the presentation semaphore is ready. - /// - { - vk::SubmitInfo submit_info; - vk::PipelineStageFlags wait_stage = - vk::PipelineStageFlagBits::eColorAttachmentOutput; - submit_info.setWaitDstStageMask(wait_stage); - submit_info.setWaitSemaphores(*sync->render_ready); - submit_info.setSignalSemaphores(*sync->present_ready); - submit_info.setCommandBuffers(vk_final_cmd_buffer); - auto result = - context.GetGraphicsQueue()->Submit(submit_info, *sync->acquire); - if (result != vk::Result::eSuccess) { - VALIDATION_LOG << "Could not wait on render semaphore: " - << vk::to_string(result); - return false; - } - } + //---------------------------------------------------------------------------- + /// Signal that the presentation semaphore is ready. + /// + { + vk::SubmitInfo submit_info; + vk::PipelineStageFlags wait_stage = + vk::PipelineStageFlagBits::eColorAttachmentOutput; + submit_info.setWaitDstStageMask(wait_stage); + submit_info.setWaitSemaphores(*sync->render_ready); + submit_info.setSignalSemaphores(*sync->present_ready); + submit_info.setCommandBuffers(vk_final_cmd_buffer); + auto result = + context.GetGraphicsQueue()->Submit(submit_info, *sync->acquire); + if (result != vk::Result::eSuccess) { + VALIDATION_LOG << "Could not wait on render semaphore: " + << vk::to_string(result); + return; + } + } - //---------------------------------------------------------------------------- - /// Present the image. - /// - uint32_t indices[] = {static_cast(index)}; - - vk::PresentInfoKHR present_info; - present_info.setSwapchains(*swapchain_); - present_info.setImageIndices(indices); - present_info.setWaitSemaphores(*sync->present_ready); - - switch (auto result = present_queue_.presentKHR(present_info)) { - case vk::Result::eErrorOutOfDateKHR: - // Caller will recreate the impl on acquisition, not submission. - [[fallthrough]]; - case vk::Result::eErrorSurfaceLostKHR: - // Vulkan guarantees that the set of queue operations will still complete - // successfully. - [[fallthrough]]; - case vk::Result::eSuccess: - is_rotated_ = false; - return true; - case vk::Result::eSuboptimalKHR: - is_rotated_ = true; - return true; - default: - VALIDATION_LOG << "Could not present queue: " << vk::to_string(result); - return false; - } - FML_UNREACHABLE(); - return false; + //---------------------------------------------------------------------------- + /// Present the image. + /// + uint32_t indices[] = {static_cast(index)}; + + vk::PresentInfoKHR present_info; + present_info.setSwapchains(*swapchain_); + present_info.setImageIndices(indices); + present_info.setWaitSemaphores(*sync->present_ready); + + switch (auto result = present_queue_.presentKHR(present_info)) { + case vk::Result::eErrorOutOfDateKHR: + // Caller will recreate the impl on acquisition, not submission. + [[fallthrough]]; + case vk::Result::eErrorSurfaceLostKHR: + // Vulkan guarantees that the set of queue operations will still + // complete successfully. + [[fallthrough]]; + case vk::Result::eSuccess: + is_rotated_ = false; + return; + case vk::Result::eSuboptimalKHR: + is_rotated_ = true; + return; + default: + VALIDATION_LOG << "Could not present queue: " + << vk::to_string(result); + return; + } + FML_UNREACHABLE(); + }); + return true; } } // namespace impeller