fix(host): the console reported the resolution the client asked for, not the one it got
`/api/v1/local/summary` (and the console card behind it) read the live-stats mode
slot, which bring-up seeded from the NEGOTIATED mode:
let live_mode = Arc::new(AtomicU64::new(pack_mode(
mode.width, mode.height, interval_hz(interval))));
The refresh was already corrected there — the comment says so, because KWin caps
a virtual output's rate — but the SIZE was still the request. Only a mid-stream
resize ever fixed it: the rebuild path below publishes `delivered_mode(frame..)`,
and bring-up never did.
Attach is what makes this matter rather than being pedantry. On a box with a
physical display the gamescope backend logs
gamescope: box drives a physical display — attaching at its own mode (no
re-mode) client_w=5120 client_h=1440
and streams the panel's size. Measured on home-nobara-1 with a 1080p HDMI panel
attached: the capture negotiated 1920x1080 and NVENC opened 1920x1080@240, while
the summary reported 5120x1440 — the console confidently naming a resolution
nobody was watching, which is exactly the shape of the stale attach-path report
noted on .41 in July ("reusing w=5120 h=1440" while the session was really 1080p).
Seeding the slot from `delivered_mode(frame.width, frame.height, interval)` uses
the same helper the rebuild path already trusts, and changes only the two fields
that were wrong — its refresh term IS `interval_hz(interval)`, so that half is
bit-for-bit what it was.
This publishes the STATS slot only. It deliberately does not send the client a
corrective `Reconfigured`: that remains owed exactly where it already was, under
`adopted_at_bringup`, because an ordinary connect's mode came from the Welcome
rather than from an accept the client has already acted on.
Verified on home-nobara-1, attach session against a 1080p panel:
summary session: {"width":1920,"height":1080,"fps":240}
actually captured: pipewire format negotiated width=1920 height=1080
Before the change the same session reported 5120x1440.
This commit is contained in:
@@ -1899,10 +1899,21 @@ pub(super) fn virtual_stream(ctx: SessionContext, prepared: Option<PreparedDispl
|
||||
// a stats capture armed after a resize registers the real mode. Seeded with the refresh the
|
||||
// initial build actually achieved (`interval_hz`), not the request — KWin may cap a virtual
|
||||
// output at 60 Hz.
|
||||
// …and seeded with the SIZE the build actually delivered too, not just the refresh. Attach is
|
||||
// what made the asymmetry visible: `gamescope: box drives a physical display — attaching at its
|
||||
// own mode (no re-mode)` streams the panel's size, so a client that asked for 5120x1440 is
|
||||
// really watching 1920x1080 while `/api/v1/local/summary` echoed the request straight back and
|
||||
// the console reported a resolution nobody was looking at. The rebuild path below already
|
||||
// publishes `delivered_mode`; bring-up simply never did, so only a mid-stream resize ever
|
||||
// corrected it. This publishes the stats slot ONLY — it deliberately does not send the client a
|
||||
// corrective `Reconfigured`, which stays owed exactly where it already was (`adopted_at_bringup`
|
||||
// above): an ordinary connect's mode came from the Welcome, not from an accept the client has
|
||||
// acted on, so it is not owed one.
|
||||
let delivered = delivered_mode(frame.width, frame.height, interval);
|
||||
let live_mode = Arc::new(AtomicU64::new(pack_mode(
|
||||
mode.width,
|
||||
mode.height,
|
||||
interval_hz(interval),
|
||||
delivered.width,
|
||||
delivered.height,
|
||||
delivered.refresh_hz,
|
||||
)));
|
||||
// One-shot force-keyframe flag driven by the management API (`POST /session/idr`, the web-console
|
||||
// Dashboard's "Request IDR" button) — drained in the encode loop below exactly like a client
|
||||
|
||||
Reference in New Issue
Block a user