| Flutter Impeller |

khr_swapchain_vk.cc
Go to the documentation of this file.
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 #include "impeller/renderer/backend/vulkan/swapchain/khr/khr_swapchain_vk.h"
6
7 #include "flutter/fml/build_config.h"
8 #include "flutter/fml/trace_event.h"
9 #include "impeller/base/validation.h"
10 #include "impeller/renderer/backend/vulkan/swapchain/khr/khr_swapchain_impl_vk.h"
11
12 namespace impeller {
13
14 KHRSwapchainVK::KHRSwapchainVK(const std::shared_ptr<Context>& context,
15 vk::UniqueSurfaceKHR surface,
16 const ISize& size,
17 bool enable_msaa)
18 : size_(size), enable_msaa_(enable_msaa) {
19 auto impl = KHRSwapchainImplVK::Create(context, //
20 std::move(surface), //
21 size_, //
22 enable_msaa_ //
23 );
24 if (!impl || !impl->IsValid()) {
25 VALIDATION_LOG << "Failed to create SwapchainVK implementation.";
26 return;
27 }
28 impl_ = std::move(impl);
29 }
30
31 KHRSwapchainVK::~KHRSwapchainVK() = default;
32
33 bool KHRSwapchainVK::IsValid() const {
34 return impl_ ? impl_->IsValid() : false;
35 }
36
37 void KHRSwapchainVK::UpdateSurfaceSize(const ISize& size) {
38 // Update the size of the swapchain. On the next acquired drawable,
39 // the sizes may no longer match, forcing the swapchain to be recreated.
40 size_ = size;
41 }
42
43 void KHRSwapchainVK::AddFinalCommandBuffer(
44 std::shared_ptr<CommandBuffer> cmd_buffer) const {
45 impl_->AddFinalCommandBuffer(std::move(cmd_buffer));
46 }
47
48 std::unique_ptr<Surface> KHRSwapchainVK::AcquireNextDrawable() {
49 return AcquireNextDrawable(0u);
50 }
51
52 std::unique_ptr<Surface> KHRSwapchainVK::AcquireNextDrawable(
53 size_t resize_retry_count) {
54 if (!IsValid()) {
55 return nullptr;
56 }
57
58 TRACE_EVENT0("impeller", __FUNCTION__);
59
60 auto result = impl_->AcquireNextDrawable();
61 if (!result.out_of_date && size_ == impl_->GetSize()) {
62 return std::move(result.surface);
63 }
64
65 // When the swapchain says its out-of-date, we attempt to read the underlying
66 // surface size and re-create the swapchain at that size automatically (subject
67 // to a specific number of retries). However, on some platforms, the surface
68 // size reported by the Vulkan API may be stale for several frames. Those
69 // platforms must explicitly set the swapchain size using out-of-band (to
70 // Vulkan) APIs.
71 //
72 // TODO(163070): Expose the API to set surface size in impeller.h
73 #if !FML_OS_ANDROID
74 constexpr const size_t kMaxResizeAttempts = 3u;
75 if (resize_retry_count == kMaxResizeAttempts) {
76 VALIDATION_LOG << "Attempted to resize the swapchain" << kMaxResizeAttempts
77 << " time unsuccessfully. This platform likely doesn't "
78 "support returning the current swapchain extents and "
79 "must recreate the swapchain using the actual size.";
80 return nullptr;
81 }
82
83 size_ = impl_->GetCurrentUnderlyingSurfaceSize().value_or(size_);
84 #endif // !FML_OS_ANDROID
85
86 TRACE_EVENT0("impeller", "RecreateSwapchain");
87
88 // This swapchain implementation indicates that it is out of date. Tear it
89 // down and make a new one.
90 auto context = impl_->GetContext();
91 auto [surface, old_swapchain] = impl_->DestroySwapchain();
92
93 auto new_impl = KHRSwapchainImplVK::Create(context, //
94 std::move(surface), //
95 size_, //
96 enable_msaa_, //
97 *old_swapchain //
98 );
99 if (!new_impl || !new_impl->IsValid()) {
100 VALIDATION_LOG << "Could not update swapchain.";
101 // The old swapchain is dead because we took its surface. This is
102 // unrecoverable.
103 impl_.reset();
104 return nullptr;
105 }
106 impl_ = std::move(new_impl);
107
108 //----------------------------------------------------------------------------
109 /// We managed to recreate the swapchain in the new configuration. Try again.
110 ///
111 return AcquireNextDrawable(resize_retry_count + 1);
112 }
113
114 vk::Format KHRSwapchainVK::GetSurfaceFormat() const {
115 return IsValid() ? impl_->GetSurfaceFormat() : vk::Format::eUndefined;
116 }
117
118 } // namespace impeller
khr_swapchain_impl_vk.h
khr_swapchain_vk.h
impeller::interop::Create
ScopedObject< Object > Create(CtorArgs &&... args)
Definition: object.h:161
impeller
Definition: allocation.cc:12
impeller::ISize
ISize64 ISize
Definition: size.h:162
impeller::TSize
Definition: size.h:25
validation.h
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:91