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

Commit a198ad4

Browse files
author
Jonah Williams
authored
[Impeller] Add present wait latch. (#47311)
It turns out the fixing #47249 revealed further bugs: we were actually overwriting previous presents and dropping frames, which was what the forward progress error was hinting. Once this problem is fixed, we started hitting present timeouts or overdraw of swapchain images. The fix for this is that we shouldn't even ask for a swapchain image until after we've called present, which actually wasn't tracked with anything. The error: ``` A Dart VM Service on Pixel 6 Pro is available at: http://127.0.0.1:62491/_N4PSEPUtA0=/ The Flutter DevTools debugger and profiler on Pixel 6 Pro is available at: http://127.0.0.1:9102?uri=http://127.0.0.1:62491/_N4PSEPUtA0=/ W/OnBackInvokedCallback(19160): OnBackInvokedCallback is not enabled for the application. W/OnBackInvokedCallback(19160): Set 'android:enableOnBackInvokedCallback="true"' in the application manifest. W/vulkan (19160): dequeueBuffer timed out: Function not implemented (-38) E/flutter (19160): [ERROR:flutter/impeller/base/validation.cc(49)] Break on 'ImpellerValidationBreak' to inspect point of failure: Could not acquire next swapchain image: Timeout E/flutter (19160): [ERROR:flutter/shell/gpu/gpu_surface_vulkan_impeller.cc(64)] No surface available. ```
1 parent 5176c81 commit a198ad4

File tree

1 file changed

+11
-1
lines changed

1 file changed

+11
-1
lines changed

impeller/renderer/backend/vulkan/swapchain_impl_vk.cc

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include "impeller/renderer/backend/vulkan/swapchain_impl_vk.h"
66

7+
#include "fml/synchronization/count_down_latch.h"
78
#include "impeller/base/validation.h"
89
#include "impeller/renderer/backend/vulkan/command_buffer_vk.h"
910
#include "impeller/renderer/backend/vulkan/command_encoder_vk.h"
@@ -29,6 +30,9 @@ struct FrameSynchronizer {
2930
vk::UniqueSemaphore render_ready;
3031
vk::UniqueSemaphore present_ready;
3132
std::shared_ptr<CommandBuffer> final_cmd_buffer;
33+
/// @brief A latch that is signaled _after_ a given swapchain image is
34+
/// presented.
35+
std::shared_ptr<fml::CountDownLatch> present_latch;
3236
bool is_valid = false;
3337

3438
explicit FrameSynchronizer(const vk::Device& device) {
@@ -45,12 +49,14 @@ struct FrameSynchronizer {
4549
acquire = std::move(acquire_res.value);
4650
render_ready = std::move(render_res.value);
4751
present_ready = std::move(present_res.value);
52+
present_latch = std::make_shared<fml::CountDownLatch>(0u);
4853
is_valid = true;
4954
}
5055

5156
~FrameSynchronizer() = default;
5257

5358
bool WaitForFence(const vk::Device& device) {
59+
present_latch->Wait();
5460
if (auto result = device.waitForFences(
5561
*acquire, // fence
5662
true, // wait all
@@ -65,6 +71,7 @@ struct FrameSynchronizer {
6571
VALIDATION_LOG << "Could not reset fence: " << vk::to_string(result);
6672
return false;
6773
}
74+
present_latch = std::make_shared<fml::CountDownLatch>(1u);
6875
return true;
6976
}
7077
};
@@ -497,7 +504,10 @@ bool SwapchainImplVK::Present(const std::shared_ptr<SwapchainImageVK>& image,
497504
present_info.setImageIndices(indices);
498505
present_info.setWaitSemaphores(*sync->present_ready);
499506

500-
switch (auto result = present_queue_.presentKHR(present_info)) {
507+
auto result = present_queue_.presentKHR(present_info);
508+
sync->present_latch->CountDown();
509+
510+
switch (result) {
501511
case vk::Result::eErrorOutOfDateKHR:
502512
// Caller will recreate the impl on acquisition, not submission.
503513
[[fallthrough]];

0 commit comments

Comments
 (0)