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
12#include "flutter/fml/compiler_specific.h"
13#include "flutter/fml/macros.h"
14#include "third_party/skia/include/core/SkSize.h"
15#include "third_party/skia/include/core/SkSurface.h"
16#include "vulkan_handle.h"
17
18namespace vulkan {
19
20class VulkanProcTable;
21class VulkanDevice;
22class VulkanSurface;
23class VulkanBackbuffer;
24class VulkanImage;
25
26class VulkanSwapchain {
27 public:
28 VulkanSwapchain(const VulkanProcTable& vk,
29 const VulkanDevice& device,
30 const VulkanSurface& surface,
31 GrDirectContext* skia_context,
32 std::unique_ptr<VulkanSwapchain> old_swapchain,
33 uint32_t queue_family_index);
34
35 ~VulkanSwapchain();
36
37 bool IsValid() const;
38
39 enum class AcquireStatus {
40 /// A valid SkSurface was acquired successfully from the swapchain.
41 Success,
42 /// The underlying surface of the swapchain was permanently lost. This is an
43 /// unrecoverable error. The entire surface must be recreated along with the
44 /// swapchain.
45 ErrorSurfaceLost,
46 /// The swapchain surface is out-of-date with the underlying surface. The
47 /// swapchain must be recreated.
48 ErrorSurfaceOutOfDate,
49 };
50 using AcquireResult = std::pair<AcquireStatus, sk_sp<SkSurface>>;
51
52 /// Acquire an SkSurface from the swapchain for the caller to render into for
53 /// later submission via |Submit|. There must not be consecutive calls to
54 /// |AcquireFrame| without and interleaving |Submit|.
55 AcquireResult AcquireSurface();
56
57 /// Submit a previously acquired. There must not be consecutive calls to
58 /// |Submit| without and interleaving |AcquireFrame|.
59 [[nodiscard]] bool Submit();
60
61 SkISize GetSize() const;
62
63#if OS_ANDROID
64 private:
65 const VulkanProcTable& vk;
66 const VulkanDevice& device_;
67 VkSurfaceCapabilitiesKHR capabilities_;
68 VkSurfaceFormatKHR surface_format_;
69 VulkanHandle<VkSwapchainKHR> swapchain_;
70 std::vector<std::unique_ptr<VulkanBackbuffer>> backbuffers_;
71 std::vector<std::unique_ptr<VulkanImage>> images_;
72 std::vector<sk_sp<SkSurface>> surfaces_;
73 VkPipelineStageFlagBits current_pipeline_stage_;
74 size_t current_backbuffer_index_;
75 size_t current_image_index_;
76 bool valid_;
77
78 std::vector<VkImage> GetImages() const;
79
80 bool CreateSwapchainImages(GrDirectContext* skia_context,
81 SkColorType color_type,
82 sk_sp<SkColorSpace> color_space);
83
84 sk_sp<SkSurface> CreateSkiaSurface(GrDirectContext* skia_context,
85 VkImage image,
86 const SkISize& size,
87 SkColorType color_type,
88 sk_sp<SkColorSpace> color_space) const;
89
90 VulkanBackbuffer* GetNextBackbuffer();
91#endif // OS_ANDROID
92
93 FML_DISALLOW_COPY_AND_ASSIGN(VulkanSwapchain);
94};
95
96} // namespace vulkan
97
98#endif // FLUTTER_VULKAN_VULKAN_SWAPCHAIN_H_
99