Skip to content

feat(stlxdm): showed missed frames on the desktop bar - #460

Merged
FlareCoding merged 1 commit into
masterfrom
pr/stlxdm-frame-stats
Oct 25, 2026
Merged

FlareCoding merged 1 commit into
masterfrom
pr/stlxdm-frame-stats

Conversation

@FlareCoding

@FlareCoding FlareCoding commented Oct 25, 2026 •

Copy link
Copy Markdown
Owner

Summary

stlxdm, the desktop's compositor, showed the input latency on its top bar but not missed frames, the screen refreshes (vertical blanks) at which an older frame stayed on screen because the next came late, though /dev/gfxfb reports for each present (a request that a buffer replace what the screen shows) the vertical blank at which the present latched, from which the screen shows that buffer.

Changes

  • Count missed frames: stlxdm's presenter interface gains missed_frames(). When flip_presenter reads that a present latched, it counts as missed each vertical blank before the latch from the one the present's frame was due at on, taking those between two latches as evenly spaced.
  • Charge a frame only the vertical blanks it had time for: a frame is due at the first vertical blank more than half a refresh period after both acquire() handing out the buffer it is composed into and the last latch read. A frame begun just before a vertical blank is not charged with it.
  • Show them on the bar: perf_monitor takes the count on every wakeup of stlxdm's loop and sums its increases over the latency readout's 10-second window. dm_panels shows "missed frames N" beside the latency, or "missed frames --" where the memcpy_presenter draws into the framebuffer, which reports no vertical blanks.
  • Count from a known start: the first count the perf monitor takes is its base, so the misses counted during the splash never show. flip_presenter::take_end() clears the latch it counts from when a present ends dark or failed, or when its end cannot be read, so the next latch counts no misses.
  • Keep the readout across a reload: server::reload_config() gives the rebuilt bar the last readout server::perf_tick took, the latency's included, since an idle perf monitor refreshes nothing until the next input or missed frame.
  • Boots: the desktop booted before and after the change on x86_64 and aarch64, on virtio-gpu and on gfxfb's boot display, with no fault. After it the bar read "missed frames 2" on x86_64's desktop, 0 on the other virtio-gpu dumps and "missed frames --" on x86_64's boot display.
  • Screens: below the bar every desktop and terminal dump matches the base's pixel for pixel but one terminal caret dumped in the other phase of its blink. On aarch64's 800-pixel-wide boot display the centered clock covers "missed frames --", as on the base it covers the end of "last".
  • Count checked: a diagnostic build, not committed, delayed every 10th present by 50 ms and logged each latch, each increase the perf monitor took and each refresh of the bar. A recount from the logged times matched all 459 latches, each delayed present missed 2 or 3, and each of the 102 refreshes showed the increases inside its 10-second window.
  • Reload checked: a second diagnostic build delayed presents until the bar showed a missed frame, then reloaded the config once the perf monitor had stopped asking for wakeups. The rebuilt bar, whose label starts as "missed frames --", held "missed frames 0" at the next frame and in a screen dump 3 seconds later, with no refresh between.
  • Not run: no boot reached a present that ended dark or failed, a failed read of a present's end, a present the display refused, an output lit again, a reload while the window held a latency sample, or a count on a display other than virtio-gpu, whose driver reports latches at refresh boundaries exactly 16666666 ns apart.

Note

Medium Risk
Touches present timing, gfxfb latch handling, and the main-loop perf path; display-backend edge cases (failed presents, dark output) reset counting but were not fully exercised in testing.

Overview
stlxdm now surfaces missed frames on the top bar next to input latency, using the same 10s rolling window and ~250ms refresh as the existing perf readouts.

The presenter gains missed_frames(). flip_presenter stamps each compose at acquire(), compares latch events from gfxfb to infer refresh period, and increments a running total for vertical blanks skipped before a present latched (with latch state cleared on dark/failed presents or unreadable end events). memcpy_presenter returns -1 so the bar shows missed frames --.

perf_monitor records deltas when the presenter total rises, sums them in tick(), and only goes quiescent when both the latency window and missed-frame sum are empty. dm_panels renders the new label; server pulls the presenter count each perf_tick (after present-end handling) and reapplies the cached snapshot on config reload so a rebuilt bar does not flash dashes while idle.

Reviewed by Cursor Bugbot for commit 447896e. Bugbot is set up for automated code reviews on this repo. Configure here.

The presenter interface gains missed_frames(). The flip presenter counts
them from each latch and the time its frame began, the memcpy presenter
cannot count them, and the bar shows the last 10 seconds' misses.
@FlareCoding
FlareCoding merged commit 83f946d into master Oct 25, 2026
11 checks passed
@FlareCoding
FlareCoding deleted the pr/stlxdm-frame-stats branch October 25, 2026 22:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant