aboutsummaryrefslogtreecommitdiff
path: root/src/strategies/low_latency2
diff options
context:
space:
mode:
Diffstat (limited to 'src/strategies/low_latency2')
-rw-r--r--src/strategies/low_latency2/swapchain_monitor.cc29
-rw-r--r--src/strategies/low_latency2/swapchain_monitor.hh5
2 files changed, 18 insertions, 16 deletions
diff --git a/src/strategies/low_latency2/swapchain_monitor.cc b/src/strategies/low_latency2/swapchain_monitor.cc
index 3d1d276..c2a328b 100644
--- a/src/strategies/low_latency2/swapchain_monitor.cc
+++ b/src/strategies/low_latency2/swapchain_monitor.cc
@@ -53,28 +53,26 @@ void SwapchainMonitor::do_monitor(const std::stop_token stoken) {
break;
}
- // Unlock, wait for work to finish, lock again.
+ // Grab mutex protected present delay before we sleep - doesn't matter
+ // if it's 'old'.
+ const auto delay = this->present_delay;
lock.unlock();
+
+ // Wait for work to complete.
for (const auto& frame_span : pending_signal.frame_spans) {
if (frame_span) {
frame_span->await_completed();
}
}
- lock.lock();
+ // Wait for possible need to delay the frame.
using namespace std::chrono;
- if (this->present_delay != 0us) {
- const auto last_time = this->last_signal_time;
- const auto delay = this->present_delay;
- if (last_time.has_value()) {
- lock.unlock();
- std::this_thread::sleep_until(*last_time + delay);
- lock.lock();
- }
- this->last_signal_time.emplace(steady_clock::now());
+ if (delay != 0us && this->last_signal_time.has_value()) {
+ const auto last = this->last_signal_time.get();
+ std::this_thread::sleep_until(last + delay);
}
- lock.unlock();
+ this->last_signal_time.set(std::chrono::steady_clock::now());
pending_signal.wakeup_semaphore.signal(this->device);
}
}
@@ -93,8 +91,11 @@ void SwapchainMonitor::notify_semaphore(const VkSemaphore& timeline_semaphore,
return;
}
- // Signal immediately if we have no outstanding work.
- if (std::ranges::all_of(this->pending_frame_spans,
+ // Signal immediately if we don't need to worry about delaying the frame and
+ // we have no outstanding work.
+ using namespace std::chrono;
+ if (this->present_delay == 0us &&
+ std::ranges::all_of(this->pending_frame_spans,
[](const auto& frame_span) {
if (!frame_span) {
return true;
diff --git a/src/strategies/low_latency2/swapchain_monitor.hh b/src/strategies/low_latency2/swapchain_monitor.hh
index a5f8362..28771cf 100644
--- a/src/strategies/low_latency2/swapchain_monitor.hh
+++ b/src/strategies/low_latency2/swapchain_monitor.hh
@@ -2,8 +2,10 @@
#ifndef SWAPCHAIN_MONITOR_HH_
#define SWAPCHAIN_MONITOR_HH_
+#include "atomic_time_point.hh"
#include "frame_span.hh"
+#include <atomic>
#include <vulkan/vulkan.h>
#include <chrono>
@@ -40,12 +42,11 @@ class SwapchainMonitor final {
std::mutex mutex{};
std::chrono::microseconds present_delay{};
bool was_low_latency_requested{};
+ AtomicTimePoint last_signal_time{};
std::condition_variable_any cv{};
std::jthread monitor_worker{};
- std::optional<std::chrono::steady_clock::time_point> last_signal_time;
-
void do_monitor(const std::stop_token stoken);
public: