1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-06-01 10:38:13 +00:00

LibVideo: Check whether it's time to present frames before doing so

Previously, we assumed the timer was hitting at the correct time. This
meant that if we changed states and the previous state handler had
prepared a next frame, we would immediately display it without checking
the timestamp.
This commit is contained in:
Zaggy1024 2023-02-12 02:00:59 -06:00 committed by Andreas Kling
parent 5da0c6f916
commit f9a65c1502

View file

@ -313,6 +313,19 @@ private:
ErrorOr<void> on_timer_callback() override
{
auto set_presentation_timer = [&]() {
auto frame_time_ms = (manager().m_next_frame->timestamp() - current_time()).to_milliseconds();
VERIFY(frame_time_ms <= NumericLimits<int>::max());
dbgln_if(PLAYBACK_MANAGER_DEBUG, "Time until next frame is {}ms", frame_time_ms);
manager().start_timer(max(static_cast<int>(frame_time_ms), 0));
};
if (manager().m_next_frame.has_value() && manager().m_next_frame->timestamp() < current_time()) {
dbgln_if(PLAYBACK_MANAGER_DEBUG, "Current time {}ms is too early to present the next frame at {}ms, delaying", current_time().to_milliseconds(), manager().m_next_frame->timestamp().to_milliseconds());
set_presentation_timer();
return {};
}
Optional<FrameQueueItem> future_frame_item;
bool should_present_frame = false;
@ -381,11 +394,7 @@ private:
// The future frame item becomes the next one to present.
manager().m_next_frame.emplace(future_frame_item.release_value());
auto frame_time_ms = (manager().m_next_frame->timestamp() - current_time()).to_milliseconds();
VERIFY(frame_time_ms <= NumericLimits<int>::max());
dbgln_if(PLAYBACK_MANAGER_DEBUG, "Time until next frame is {}ms", frame_time_ms);
manager().start_timer(max(static_cast<int>(frame_time_ms), 0));
set_presentation_timer();
return {};
}