client: a window that cannot present keeps pulling frames unpaced #407

Closed
opened 2026-09-25 02:18:27 +09:00 by natsukium · 0 comments
Owner

Split from #398.

When the surface cannot present (macOS with the display asleep or the screen locked; possibly an occluded or minimized window), get_current_texture returns SurfaceError::Timeout immediately. crates/felis-client/src/event_handler.rs ~1235 skips the frame, but ~1258 still sends the next pull to the daemon, so the client decodes updates as fast as the acquire fails: 500-2,100 failed acquires per second and 0.14-0.73 of a core on an M4 Max during DOOM-fire, against 0.044 with a visible window. Nothing is painted in that state, so the work is wasted.

This is also why #397 measured the client at about 30% of felis's CPU: it ran while the display was off (pmset -g log).

Fix: send the next pull only after a frame was presented, and on Timeout back off (until the window reports it is visible again, or on a refresh-interval timer) instead of retrying at once. Pin it with a test that a timed-out acquire does not issue a pull.

The published 9d1d842f binary also grew about 500 MB/s of GPU footprint in this state; current main (a577fee0, after #396) stays flat, so that part needs no work here.

Split from #398. When the surface cannot present (macOS with the display asleep or the screen locked; possibly an occluded or minimized window), `get_current_texture` returns `SurfaceError::Timeout` immediately. `crates/felis-client/src/event_handler.rs` ~1235 skips the frame, but ~1258 still sends the next pull to the daemon, so the client decodes updates as fast as the acquire fails: 500-2,100 failed acquires per second and 0.14-0.73 of a core on an M4 Max during DOOM-fire, against 0.044 with a visible window. Nothing is painted in that state, so the work is wasted. This is also why #397 measured the client at about 30% of felis's CPU: it ran while the display was off (`pmset -g log`). Fix: send the next pull only after a frame was presented, and on `Timeout` back off (until the window reports it is visible again, or on a refresh-interval timer) instead of retrying at once. Pin it with a test that a timed-out acquire does not issue a pull. The published 9d1d842f binary also grew about 500 MB/s of GPU footprint in this state; current main (a577fee0, after #396) stays flat, so that part needs no work here.
Commenting is not possible because the repository is archived.
No description provided.