daemon: feed the frame ring from publishes when no producer reports flow

Merged
UT
9d ago
+35-4

Stacked on #41.

Problem

#41 feeds the app's frame ring only from the shim's producer reports (note_produced), so a cap above the panel reads as what the session produced. A session whose frames never go through the ICD shim sends no reports at all: Xwayland GL titles (zink on the xlib winsys, which is every GL game in the container), GDI windows, software renderers. For those the publish path was the only frame count, and with it silent the HUD and the session telemetry read 0.0 fps while the game runs. Seen on the RP6 with SteamWorld Dig 2 on the #41 daemon: HUD 0.0, SurfaceFlinger presenting 42 to 60 fps.

Fix

  • LAST_PRODUCER_REPORT_MS is stamped by every producer report. The publish path counts a frame whenever no report arrived within the last second (PRODUCER_REPORT_GRACE_MS), and goes quiet as soon as reports flow. Shim sessions keep #41's semantics exactly.
  • The first report of a connecting counter (previous == 0) no longer replays its whole backlog into the ring: those frames were counted by the publish path while no reports flowed, so replaying them was a one-off jump of up to MAX_PRODUCED_PER_MESSAGE.

Verification (RP6, payload 20261101.4 stack: gamescope#26, xserver#1+#2 Xwayland, #41 shim, this daemon)

  • SteamWorld Dig 2 (GL): HUD 59.9 fps (was 0.0 on the #41 daemon); SurfaceFlinger 59.86 fps on the scan-out layer over 13.6 s; 30 s of live play recorded: 0 tears / 1799 frames, 1733 distinct frames.
  • Dave the Diver (DXVK, shim-reported): HUD 60.0, unchanged.
  • Builds for aarch64-android28; daemon unit tests pass.