• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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