1 // Copyright 2013 The Flutter Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef FLUTTER_VULKAN_VULKAN_SWAPCHAIN_H_ 6 #define FLUTTER_VULKAN_VULKAN_SWAPCHAIN_H_ 7 8 #include <memory> 9 #include <utility> 10 #include <vector> 11 #include <thread> 12 #include <mutex> 13 #include <unordered_map> 14 15 #ifndef RS_ENABLE_VK 16 #include "flutter/fml/compiler_specific.h" 17 #include "flutter/fml/macros.h" 18 #endif 19 #include "flutter/vulkan/vulkan_handle.h" 20 #include "third_party/skia/include/core/SkSize.h" 21 #include "third_party/skia/include/core/SkSurface.h" 22 23 namespace vulkan { 24 25 class VulkanProcTable; 26 class VulkanDevice; 27 class VulkanSurface; 28 class VulkanBackbuffer; 29 class VulkanImage; 30 31 class VulkanSwapchain { 32 public: 33 VulkanSwapchain(const VulkanProcTable& vk, 34 const VulkanDevice& device, 35 const VulkanSurface& surface, 36 GrContext* skia_context, 37 std::unique_ptr<VulkanSwapchain> old_swapchain, 38 uint32_t queue_family_index); 39 40 ~VulkanSwapchain(); 41 42 bool IsValid() const; 43 44 enum class AcquireStatus { 45 /// A valid SkSurface was acquired successfully from the swapchain. 46 Success, 47 /// The underlying surface of the swapchain was permanently lost. This is an 48 /// unrecoverable error. The entire surface must be recreated along with the 49 /// swapchain. 50 ErrorSurfaceLost, 51 /// The swapchain surface is out-of-date with the underlying surface. The 52 /// swapchain must be recreated. 53 ErrorSurfaceOutOfDate, 54 }; 55 using AcquireResult = std::pair<AcquireStatus, sk_sp<SkSurface>>; 56 57 /// Acquire an SkSurface from the swapchain for the caller to render into for 58 /// later submission via |Submit|. There must not be consecutive calls to 59 /// |AcquireFrame| without and interleaving |Submit|. 60 AcquireResult AcquireSurface(); 61 62 /// Submit a previously acquired. There must not be consecutive calls to 63 /// |Submit| without and interleaving |AcquireFrame|. 64 #ifndef RS_ENABLE_VK 65 FML_WARN_UNUSED_RESULT 66 #endif 67 bool Submit(); 68 69 SkISize GetSize() const; 70 71 #ifdef RS_ENABLE_VK 72 bool FlushCommands(); 73 74 void AddToPresent(); 75 76 static void PresentAll(VulkanHandle<VkFence>& shared_fence); 77 78 private: 79 const VulkanProcTable& vk; 80 const VulkanDevice& device_; 81 VkSurfaceCapabilitiesKHR capabilities_; 82 VkSurfaceFormatKHR surface_format_; 83 VulkanHandle<VkSwapchainKHR> swapchain_; 84 std::vector<std::unique_ptr<VulkanBackbuffer>> backbuffers_; 85 std::vector<std::unique_ptr<VulkanImage>> images_; 86 std::vector<sk_sp<SkSurface>> surfaces_; 87 VkPipelineStageFlagBits current_pipeline_stage_; 88 size_t current_backbuffer_index_; 89 size_t current_image_index_; 90 bool valid_; 91 static std::mutex map_mutex_; 92 static std::unordered_map<std::thread::id, VulkanSwapchain*> to_be_present_; 93 94 std::vector<VkImage> GetImages() const; 95 96 bool CreateSwapchainImages(GrContext* skia_context, 97 SkColorType color_type, 98 sk_sp<SkColorSpace> color_space); 99 100 sk_sp<SkSurface> CreateSkiaSurface(GrContext* skia_context, 101 VkImage image, 102 const SkISize& size, 103 SkColorType color_type, 104 sk_sp<SkColorSpace> color_space) const; 105 106 VulkanBackbuffer* GetNextBackbuffer(); 107 #else 108 #if OS_ANDROID 109 private: 110 const VulkanProcTable& vk; 111 const VulkanDevice& device_; 112 VkSurfaceCapabilitiesKHR capabilities_; 113 VkSurfaceFormatKHR surface_format_; 114 VulkanHandle<VkSwapchainKHR> swapchain_; 115 std::vector<std::unique_ptr<VulkanBackbuffer>> backbuffers_; 116 std::vector<std::unique_ptr<VulkanImage>> images_; 117 std::vector<sk_sp<SkSurface>> surfaces_; 118 VkPipelineStageFlagBits current_pipeline_stage_; 119 size_t current_backbuffer_index_; 120 size_t current_image_index_; 121 bool valid_; 122 123 std::vector<VkImage> GetImages() const; 124 125 bool CreateSwapchainImages(GrContext* skia_context, 126 SkColorType color_type, 127 sk_sp<SkColorSpace> color_space); 128 129 sk_sp<SkSurface> CreateSkiaSurface(GrContext* skia_context, 130 VkImage image, 131 const SkISize& size, 132 SkColorType color_type, 133 sk_sp<SkColorSpace> color_space) const; 134 135 VulkanBackbuffer* GetNextBackbuffer(); 136 #endif // OS_ANDROID 137 #endif // RS_ENABLE_VK 138 139 #ifndef RS_ENABLE_VK 140 FML_DISALLOW_COPY_AND_ASSIGN(VulkanSwapchain); 141 #endif 142 }; 143 144 } // namespace vulkan 145 146 #endif // FLUTTER_VULKAN_VULKAN_SWAPCHAIN_H_ 147