Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit c222d0a

Browse files
committed
Cap the number of presents pending in the compositor.
1 parent c1d4e74 commit c222d0a

File tree

3 files changed

+51
-12
lines changed

3 files changed

+51
-12
lines changed

fml/closure.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,7 @@ class ScopedCleanupClosure final {
4545
explicit ScopedCleanupClosure(const fml::closure& closure)
4646
: closure_(closure) {}
4747

48-
~ScopedCleanupClosure() {
49-
if (closure_) {
50-
closure_();
51-
}
52-
}
48+
~ScopedCleanupClosure() { Reset(); }
5349

5450
fml::closure SetClosure(const fml::closure& closure) {
5551
auto old_closure = closure_;
@@ -63,6 +59,13 @@ class ScopedCleanupClosure final {
6359
return closure;
6460
}
6561

62+
void Reset() {
63+
if (closure_) {
64+
closure_();
65+
closure_ = nullptr;
66+
}
67+
}
68+
6669
private:
6770
fml::closure closure_;
6871

impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_impl_vk.cc

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
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"
@@ -14,6 +15,12 @@
1415

1516
namespace 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+
1724
static 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

7280
std::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

95121
bool 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

182209
void 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.

impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_impl_vk.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
#include <memory>
99

10+
#include "flutter/fml/closure.h"
11+
#include "flutter/fml/synchronization/semaphore.h"
1012
#include "impeller/base/thread.h"
1113
#include "impeller/renderer/backend/vulkan/android/ahb_texture_source_vk.h"
1214
#include "impeller/renderer/backend/vulkan/swapchain/ahb/ahb_texture_pool_vk.h"
@@ -87,6 +89,8 @@ class AHBSwapchainImplVK final
8789
std::unique_ptr<Surface> AcquireNextDrawable();
8890

8991
private:
92+
using AutoSemaSignaler = std::shared_ptr<fml::ScopedCleanupClosure>;
93+
9094
std::weak_ptr<android::SurfaceControl> surface_control_;
9195
android::HardwareBufferDescriptor desc_;
9296
std::shared_ptr<AHBTexturePoolVK> pool_;
@@ -96,6 +100,7 @@ class AHBSwapchainImplVK final
96100
Mutex currently_displayed_texture_mutex_;
97101
std::shared_ptr<AHBTextureSourceVK> currently_displayed_texture_
98102
IPLR_GUARDED_BY(currently_displayed_texture_mutex_);
103+
std::shared_ptr<fml::Semaphore> pending_presents_;
99104
bool is_valid_ = false;
100105

101106
explicit AHBSwapchainImplVK(
@@ -104,12 +109,14 @@ class AHBSwapchainImplVK final
104109
const ISize& size,
105110
bool enable_msaa);
106111

107-
bool Present(const std::shared_ptr<AHBTextureSourceVK>& texture);
112+
bool Present(const AutoSemaSignaler& signaler,
113+
const std::shared_ptr<AHBTextureSourceVK>& texture);
108114

109115
std::shared_ptr<ExternalFenceVK> SubmitCompletionSignal(
110116
const std::shared_ptr<AHBTextureSourceVK>& texture) const;
111117

112118
void OnTextureSetOnSurfaceControl(
119+
const AutoSemaSignaler& signaler,
113120
std::shared_ptr<AHBTextureSourceVK> texture);
114121
};
115122

0 commit comments

Comments
 (0)