Repository navigation
perf: pace the playback clock's ticks by the screen's frames - #569
Merged
Merged
Conversation
The transport bar's clock woke at every device pixel of playhead travel, at least 1 ms apart: about 1000 ticks a second for a 1 s clip, and the same at every track start while the duration was unknown and the seek bar fell back to a 1 s range. A step of positionSeconds now comes no sooner than a frame after it last changed, at the refresh rate of the window's screen, which WindowPresence reads from QScreen; slow tracks keep their exact pixel-boundary ticks. Without a duration only the text's second boundaries tick. The text's change and exact position reads are unchanged. Closes #553
A sample that corrected the position moved the playhead whenever it crossed a pixel, however soon after the last move, so a short track's playhead could move twice within a frame. Every step, from a tick, a text tick or a sample, now waits a frame after the last one; a step that waits is shown by the tick at that frame. An exact change, such as a seek, a pause or resume, or a duration change, starts the pacing over, so a slow track's next pixel boundary after a seek comes when it is due rather than a frame later.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #553
What changes
The transport bar's
PlaybackClockwoke at every device pixel of playhead travel, at least 1 ms apart. That made about 1000 UI-thread wakeups a second for a 1 s clip. It happened at every track start too, while the duration was unknown and the seek bar fell back to a 1 s range.The scheduling rule in
PlaybackClock::scheduleTicknow works like this:positionSecondscomes no sooner than one frame after it last changed. The frame is set by the refresh rate of the window's screen. When several pixels pass within a frame, the playhead moves by all of them at once, as the screen would show them anyway.currentPositionSeconds(), seeks, pauses and jumps still show the exact position.The refresh rate comes from public API only.
WindowPresencegets ascreenRefreshRateproperty that followsQWindow::screenChangedandQScreen::refreshRateChanged, because QML'sScreenattached type has no refresh rate.Main.qmlpasses it toPlaybackController.frameRate, which binds it into the newPlaybackClock.frameRateproperty. If the screen reports no rate, the clock uses 60 Hz.Tests
tst_playback_clock:shortTrackTicksNoFasterThanTheScreen: a 1 s clip on a 1598 px bar, across a pause/resume and a seek. Moves of the playhead stay at least a frame apart, and total ticks stay within 60 Hz plus the text's ticks. The position and text are right at every tick, the text turns over on time, and ticks stop at the end.unknownDurationTicksOnlyAtSeconds: with the 1 s fallback step, exactly three ticks in 3 s, at the second boundaries, including after a seek and a pause/resume. Once the duration is known, ticks are frame-paced again.frameRateFollowsTheScreen: 0, NaN and negative rates fall back to 60 Hz. At 144 Hz ticks come 7 ms apart, and a change of rate reschedules the next tick.kFrameIntervalMs.tst_qml_smoke_transport_input:windowPresenceFollowsTheScreensRefreshRate: the presence's rate follows its window's screen, and goes to 0 without a window or after the window is destroyed.frameRateto the clock../scripts/run-tests.sh --ui-only: 102/102 passed, no build warnings. No Rust changes.Review round 1
samplesKeepAShortTracksPlayheadToItsFrames: a 1 s clip with jittered samples every 20–50 ms. Every move is at least a frame apart, and the tick bound holds.sparseStepsAfterASeekComeAtTheirBoundaries: a 100 ms step after a seek 1 ms before a boundary. The boundary and the ones after it come within 1 ms.update()removed../scripts/run-tests.sh --ui-only: 102/102 passed.