|  | // Copyright 2013 The Flutter Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #pragma once | 
|  |  | 
|  | #include <memory> | 
|  | #include <variant> | 
|  |  | 
|  | #include "flutter/fml/macros.h" | 
|  | #include "impeller/renderer/backend/vulkan/vk.h" | 
|  | #include "vulkan/vulkan_enums.hpp" | 
|  |  | 
|  | namespace impeller { | 
|  |  | 
|  | class Context; | 
|  | class SwapchainImageVK; | 
|  | class Surface; | 
|  | struct FrameSynchronizer; | 
|  |  | 
|  | //------------------------------------------------------------------------------ | 
|  | /// @brief      An instance of a swapchain that does NOT adapt to going out of | 
|  | ///             date with the underlying surface. Errors will be indicated when | 
|  | ///             the next drawable is acquired from this implementation of the | 
|  | ///             swapchain. If the error is due the swapchain going out of date, | 
|  | ///             the caller must recreate another instance by optionally | 
|  | ///             stealing this implementations guts. | 
|  | /// | 
|  | class SwapchainImplVK final | 
|  | : public std::enable_shared_from_this<SwapchainImplVK> { | 
|  | public: | 
|  | static std::shared_ptr<SwapchainImplVK> Create( | 
|  | const std::shared_ptr<Context>& context, | 
|  | vk::UniqueSurfaceKHR surface, | 
|  | vk::SwapchainKHR old_swapchain = VK_NULL_HANDLE, | 
|  | vk::SurfaceTransformFlagBitsKHR last_transform = | 
|  | vk::SurfaceTransformFlagBitsKHR::eIdentity); | 
|  |  | 
|  | ~SwapchainImplVK(); | 
|  |  | 
|  | bool IsValid() const; | 
|  |  | 
|  | struct AcquireResult { | 
|  | std::unique_ptr<Surface> surface; | 
|  | bool out_of_date = false; | 
|  |  | 
|  | AcquireResult(bool p_out_of_date = false) : out_of_date(p_out_of_date) {} | 
|  |  | 
|  | AcquireResult(std::unique_ptr<Surface> p_surface) | 
|  | : surface(std::move(p_surface)) {} | 
|  | }; | 
|  |  | 
|  | AcquireResult AcquireNextDrawable(); | 
|  |  | 
|  | vk::Format GetSurfaceFormat() const; | 
|  |  | 
|  | vk::SurfaceTransformFlagBitsKHR GetLastTransform() const; | 
|  |  | 
|  | std::shared_ptr<Context> GetContext() const; | 
|  |  | 
|  | std::pair<vk::UniqueSurfaceKHR, vk::UniqueSwapchainKHR> DestroySwapchain(); | 
|  |  | 
|  | private: | 
|  | std::weak_ptr<Context> context_; | 
|  | vk::UniqueSurfaceKHR surface_; | 
|  | vk::Queue present_queue_ = {}; | 
|  | vk::Format surface_format_ = vk::Format::eUndefined; | 
|  | vk::UniqueSwapchainKHR swapchain_; | 
|  | std::vector<std::shared_ptr<SwapchainImageVK>> images_; | 
|  | std::vector<std::unique_ptr<FrameSynchronizer>> synchronizers_; | 
|  | size_t current_frame_ = 0u; | 
|  | bool is_valid_ = false; | 
|  | size_t current_transform_poll_count_ = 0u; | 
|  | vk::SurfaceTransformFlagBitsKHR transform_if_changed_discard_swapchain_; | 
|  |  | 
|  | SwapchainImplVK(const std::shared_ptr<Context>& context, | 
|  | vk::UniqueSurfaceKHR surface, | 
|  | vk::SwapchainKHR old_swapchain, | 
|  | vk::SurfaceTransformFlagBitsKHR last_transform); | 
|  |  | 
|  | bool Present(const std::shared_ptr<SwapchainImageVK>& image, uint32_t index); | 
|  |  | 
|  | void WaitIdle() const; | 
|  |  | 
|  | FML_DISALLOW_COPY_AND_ASSIGN(SwapchainImplVK); | 
|  | }; | 
|  |  | 
|  | }  // namespace impeller |