shim: no vblank-grid gate under the cap-rate FIFO declaration; a late start is released at the next grid instant
Follow-up to GameNative/gamenative-drm#46, which merged at c9b7c31 before this commit reached the branch. Master therefore carries the regression @joshuatam's capture found (see https://github.com/GameNative/gamenative-drm/pull/46#issuecomment-6597682480); this PR is that fix, cherry-picked unchanged from the #46 branch (2567925).
Problem
Under a cap equal to the display's rate, #46 declares FIFO and also kept the vblank-grid acquire gate running. Once a frame takes longer than a period from acquire to commit, every start reaches the gate late and the schedule books every other release a whole vblank later: the game settles at 40 fps on a 60 Hz panel (1,2,1,2 vblank intervals). The capture: at 120 Hz declared=mailbox source=env gate=vsync, 60 fps; after a live switch to 60 Hz declared=fifo source=cap-rate gate=vsync, shim commits 400 per 10 s = daemon publishes 400/600 with late=0, gate_late 400/400, skipped +200 per 10 s, acquire-to-commit 24 ms (7-16 ms at 120 Hz), GPU 65 % against 80 % at 120 Hz where the same scene runs 60.
Change
- The cap-rate cell still declares FIFO but with the gate off (
source=cap-rate gate=off): gamescope's limiter (divisor 1) paces it, master's behaviour before #46. - Under a cap below the display's rate, the release after a late start is never more than one grid instant after it, so a late frame's successor does not wait a whole slot.
- The slot count follows the guest's own request whenever the swapchain is declared FIFO for a reason other than its own mode, as before #46.
Tests
cargo test -p adrenotools_gamescope --lib: 88 passed. Clippy on the shim, daemon and android crates with -D warnings: clean. New cases: 60 on 59.97 Hz is FIFO/cap-rate/gate off; 60 on 120 and 30 on 60 stay mailbox with the gate every second vblank; a guest with 16 ms of work on a 59.97 Hz grid gets a start every vblank; a late 30-on-60 frame is followed at the next grid instant.
Verified on a Retroid Pocket 6
Dave the Diver in game (diving), cap 60, in-game VSync on, panel switched live from 120 to 60 Hz, shim 2567925 via payload 20261103.4: census declared=fifo source=cap-rate cap=60 gate=off; SurfaceFlinger 374 of 377 intervals a single vblank, median 16.71 ms; app fps 59.9 / 60.1 / 60.0 at GPU 51-53 %; daemon 596-598 publishes per 600 vsyncs, late 0-2.
Delivery
Payload gamescope-gamenative-20261103.4.tzst (sha256 5126c4ee8f042a69e287a3bde16e3be5a79de0cc052aaeadff5554b6a09fe7b9) already carries this shim (sha256 6355ee9e…9035, build string 2026110307122567925); the app side is utkarshdalal/GameNative#2327. The daemon is unchanged.