feat(host): game-mode integration + dedicated game sessions
Implements design/gamemode-and-dedicated-sessions.md (Parts A1-A5 + B0-B2):
reconciles the merged display-management registry with session-mobile
Bazzite/SteamOS hosts and adds a per-launch dedicated gamescope mode.
- A1 DisplayOwnership {Owned,External,SessionManaged} + poolable_now(): the
registry pools only what it owns, so gamescope managed/attach outputs are no
longer double-owned by the registry AND the gamescope restore worker (fixes
the game-mode-reconnect stale-node wedge).
- A2 validated reuse: (backend,mode,launch,epoch) reuse key + kept_display_alive
liveness probe + reused_gen/mark_failed on a reused-display first-frame failure.
- A3 policy-driven managed restore (keep_alive replaces the hardcoded 5s debounce;
forever = held = gaming-rig truthful) + crash-restore persist + SIGKILL teardown
(kill_unit, applied to our transient unit AND the autologin stop -- validated
live on .181 to avoid the F44 GPU-context leak).
- A4 session epoch: observe_session_instance bumps the epoch + invalidate_backend
on a desktop-compositor instance change; gamescope spawns are exempt.
- A5 per-spawn log + PID-scoped gamescope node discovery.
- B0 game_session {auto,dedicated} policy (top-level, preset-orthogonal) +
pick_gamescope_mode dedicated_launch + steam -silent command shaping.
- B1 free the autologin Steam before a dedicated Steam spawn (single-instance).
- B2 game-exit -> APP_EXITED_CLOSE_CODE (0x52) clean session end.
Adversarially reviewed (11 findings fixed). Validated on glass (.181 Bazzite F44,
RTX 4090): dedicated spawn streams a real game smoothly; keep-alive reuse; the
SIGKILL fix avoids the F44 vkCreateDevice leak. Workspace green
(build / test --workspace / clippy -D warnings / fmt), OpenAPI + C header
regenerated, web console tsc + vite build green. clients/probe: bump the
no-video timeout 8s->45s for gamescope cold starts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
//! `systemctl --user`, see `scripts/headless/prepare-session.sh`), with the ScreenCast
|
||||
//! interface routed to xdpw (`scripts/headless/portals.conf`).
|
||||
|
||||
use super::{Mode, VirtualDisplay, VirtualOutput};
|
||||
use super::{DisplayOwnership, Mode, VirtualDisplay, VirtualOutput};
|
||||
use anyhow::{anyhow, bail, Context, Result};
|
||||
use std::os::fd::OwnedFd;
|
||||
use std::process::Command;
|
||||
@@ -130,6 +130,11 @@ impl VirtualDisplay for WlrootsDisplay {
|
||||
_stop: StopGuard(stop),
|
||||
_output: output,
|
||||
}),
|
||||
// Owned (the compositor output is ours to tear down), but not registry-poolable: the
|
||||
// portal fd can't be re-opened per attach, so the registry passes it through on
|
||||
// `remote_fd.is_some()` (keep-alive stays off for wlroots until fresh-portal re-attach).
|
||||
ownership: DisplayOwnership::Owned,
|
||||
reused_gen: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user