gamescope: the display's rate is the mode, and generation follows the cap and the multiplier
The gamescope session's emulated display takes its rate from the display, and the frame generation and the frame counter follow the cap and the multiplier. Together with GameNative/gamenative-drm#41 and GameNative/gamescope#26.
At a 40 cap, changing only the multiplier: x2 produces and counts 80 frames a second, x3 120, x4 160, on a 120 Hz or a 60 Hz display alike, and the mode does not move — it changes only when the display does.
What it does
applyPanelRefreshreports the display's own rate to the daemon and nothing else; the cap and the multiplier never enter it. The mode nudge (backend_set_dirty, now allowlisted in the injector) is asked for only by the display listener, so a display change reaches a running session and a QuickMenu change moves nothing.applyLsfgMultiplierreports the rate before the LSFG settings, so the config the shim opens the generator from carries the rate in force.
Measured
Retroid Pocket Nova, Hades II, cap 40, one session per display:
| display | x2 | x3 | x4 | mode |
|---|---|---|---|---|
| 120 Hz | 80.0 | 120.0 | 160.0 | 120 Hz throughout, one selecting mode, no nudges |
| 60 Hz | 79.8 | 120.0 | 160.0 | 60 Hz throughout, 40.3 acquires/s |
Forcing the display 120 → 60 mid-session reported 60 and re-selected the mode once, which is the display-change path. The reverse could not be forced on this device (SurfaceFlinger kept the panel at 60 until the session ended), so that direction is unverified rather than verified-working.
Files
ui/screen/xserver/XServerScreen.kt—applyPanelRefresh, the change-only nudge, the rate applied before the LSFG settings.display/GamescopeConVar.kt—BACKEND_SET_DIRTY.display/GamescopeCommandQueue.kt—nudgeDisplayMode().display/GamescopePayload.kt— payload20261101.1.jniLibs/arm64-v8a/libgamenative_drm.so— rebuilt (aa33a6a4) from gamenative-drm#41.
The branch's earlier commits describe two intermediate designs this one replaces (the mode following the cap, then the produced rate); the final state is what the diff shows.
Summary by cubic
The gamescope session now advertises the display's own rate as the emulated mode, so the frame-rate cap and generation multiplier affect only frame production and counting, never the mode. The mode changes when the display does, and a mode nudge is issued only on a display change.
applyPanelRefreshreports the display rate alone and nudges the mode only when that rate changes after the first report.applyLsfgMultiplierapplies the rate before the LSFG settings so the generator opens with the rate in force.- Payload bumps to
20261101.6, replacing 20261101.5's Xwayland (which never signaled ready because it lacked the unversioned-libxcvt fix) with one linked against the payload'slibxcvt.so; the rebuiltlibgamenative_drm.sono longer halves the source rate on slow panels.
Summary by CodeRabbit
- Bug Fixes
- Gamescope sessions now report the active display refresh rate and update the display mode when that rate changes.
- FPS cap and LSFG changes no longer affect the reported display mode refresh rate.
- LSFG updates apply the FPS limit before LSFG settings. X11 sessions and invalid refresh rates are unaffected.
- Updates
- Updated the Gamescope runtime.