44
55#include " impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_impl_vk.h"
66
7+ #include " flutter/fml/trace_event.h"
78#include " impeller/base/validation.h"
89#include " impeller/renderer/backend/vulkan/barrier_vk.h"
910#include " impeller/renderer/backend/vulkan/command_buffer_vk.h"
1415
1516namespace impeller {
1617
18+ // ------------------------------------------------------------------------------
19+ // / The maximum number of presents pending in the compositor after which the
20+ // / acquire calls will block.
21+ // /
22+ static constexpr const size_t kMaxPendingPresents = 2u ;
23+
1724static TextureDescriptor ToSwapchainTextureDescriptor (
1825 const android::HardwareBufferDescriptor& ahb_desc) {
1926 TextureDescriptor desc;
@@ -43,7 +50,8 @@ AHBSwapchainImplVK::AHBSwapchainImplVK(
4350 std::weak_ptr<android::SurfaceControl> surface_control,
4451 const ISize& size,
4552 bool enable_msaa)
46- : surface_control_(std::move(surface_control)) {
53+ : surface_control_(std::move(surface_control)),
54+ pending_presents_ (std::make_shared<fml::Semaphore>(kMaxPendingPresents )) {
4755 desc_ = android::HardwareBufferDescriptor::MakeForSwapchainImage (size);
4856 pool_ = std::make_shared<AHBTexturePoolVK>(context, desc_);
4957 if (!pool_->IsValid ()) {
@@ -70,6 +78,17 @@ const android::HardwareBufferDescriptor& AHBSwapchainImplVK::GetDescriptor()
7078}
7179
7280std::unique_ptr<Surface> AHBSwapchainImplVK::AcquireNextDrawable () {
81+ {
82+ TRACE_EVENT0 (" impeller" , " CompositorPendingWait" );
83+ if (!pending_presents_->Wait ()) {
84+ return nullptr ;
85+ }
86+ }
87+
88+ AutoSemaSignaler auto_sema_signaler =
89+ std::make_shared<fml::ScopedCleanupClosure>(
90+ [sema = pending_presents_]() { sema->Signal (); });
91+
7392 if (!is_valid_) {
7493 return nullptr ;
7594 }
@@ -81,18 +100,26 @@ std::unique_ptr<Surface> AHBSwapchainImplVK::AcquireNextDrawable() {
81100 return nullptr ;
82101 }
83102
84- return SurfaceVK::WrapSwapchainImage (
85- transients_, texture, [weak = weak_from_this (), texture]() {
103+ auto surface = SurfaceVK::WrapSwapchainImage (
104+ transients_, texture,
105+ [signaler = auto_sema_signaler, weak = weak_from_this (), texture]() {
86106 auto thiz = weak.lock ();
87107 if (!thiz) {
88108 VALIDATION_LOG << " Swapchain died before image could be presented." ;
89109 return false ;
90110 }
91- return thiz->Present (texture);
111+ return thiz->Present (signaler, texture);
92112 });
113+
114+ if (!surface) {
115+ return nullptr ;
116+ }
117+
118+ return surface;
93119}
94120
95121bool AHBSwapchainImplVK::Present (
122+ const AutoSemaSignaler& signaler,
96123 const std::shared_ptr<AHBTextureSourceVK>& texture) {
97124 auto control = surface_control_.lock ();
98125 if (!control || !control->IsValid ()) {
@@ -121,12 +148,12 @@ bool AHBSwapchainImplVK::Present(
121148 " control." ;
122149 return false ;
123150 }
124- return transaction.Apply ([texture, weak = weak_from_this ()]() {
151+ return transaction.Apply ([signaler, texture, weak = weak_from_this ()]() {
125152 auto thiz = weak.lock ();
126153 if (!thiz) {
127154 return ;
128155 }
129- thiz->OnTextureSetOnSurfaceControl (texture);
156+ thiz->OnTextureSetOnSurfaceControl (signaler, texture);
130157 });
131158}
132159
@@ -180,7 +207,9 @@ std::shared_ptr<ExternalFenceVK> AHBSwapchainImplVK::SubmitCompletionSignal(
180207}
181208
182209void AHBSwapchainImplVK::OnTextureSetOnSurfaceControl (
210+ const AutoSemaSignaler& signaler,
183211 std::shared_ptr<AHBTextureSourceVK> texture) {
212+ signaler->Reset ();
184213 // The transaction completion indicates that the surface control now
185214 // references the hardware buffer. We can recycle the previous set buffer
186215 // safely.
0 commit comments