mirror of
https://github.com/nestriness/nestri.git
synced 2026-09-29 06:02:25 +03:00
feat: nescapture capture improvements and drive mounts (#337)
Co-authored-by: DatCaptainHorse <DatCaptainHorse@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
DatCaptainHorse
Claude Opus 5
parent
ebc0242b49
commit
6811c93d51
@@ -15,7 +15,8 @@
|
||||
//! Options:
|
||||
//! --width <N> Output width [default: 1920]
|
||||
//! --height <N> Output height [default: 1080]
|
||||
//! --fps <N> Virtual refresh rate [default: 60]
|
||||
//! --fps <N> Virtual refresh rate, advertised only [default: 60]
|
||||
//! --frame-callback-hz <N> wl_surface.frame cadence [default: 1000]
|
||||
//! --hdr Enable HDR protocols (wp_color_management_v1 + gamescope_swapchain)
|
||||
//! --socket <NAME> Wayland socket name [default: nescope-0]
|
||||
//! ```
|
||||
@@ -94,10 +95,36 @@ struct Args {
|
||||
#[arg(long, default_value = "1080", env = "NESCOPE_HEIGHT")]
|
||||
height: u32,
|
||||
|
||||
/// Virtual output refresh rate (fps).
|
||||
/// Virtual output refresh rate, as advertised to clients.
|
||||
///
|
||||
/// **Advertised only — this does not pace anything.** It is what a game
|
||||
/// reads as its monitor's refresh rate, so it should be the rate the
|
||||
/// session actually sends at: a game with V-Sync on will lock to it, and
|
||||
/// one that reads the mode to build a settings list will offer it.
|
||||
///
|
||||
/// Pacing is `--frame-callback-hz`, and the two used to be this one value.
|
||||
/// That made an honest advertisement and a non-binding cadence mutually
|
||||
/// exclusive, which is why the default sat at 60 while sessions asked for
|
||||
/// 120.
|
||||
#[arg(long, default_value = "60", env = "NESCOPE_FPS")]
|
||||
fps: u32,
|
||||
|
||||
/// How often `wl_surface.frame` callbacks are sent, in hertz.
|
||||
///
|
||||
/// This is the only rate that can throttle a client, and only a FIFO one:
|
||||
/// `IMMEDIATE` and `MAILBOX` swapchains ignore these callbacks entirely.
|
||||
/// It is therefore not a frame limiter — it cannot hold a game whose
|
||||
/// V-Sync is off, which is every game whose player turned it off. That job
|
||||
/// belongs to the capture layer, which sees every present and can hold the
|
||||
/// application whatever its swapchain does.
|
||||
///
|
||||
/// So the default is set high enough never to bind, and the compositor
|
||||
/// stops being a second opinion on the frame rate. The cost is the timer
|
||||
/// itself: a wakeup per tick, each sending callbacks to the surfaces in
|
||||
/// the space. Lower it if that shows up on a small box.
|
||||
#[arg(long, default_value = "1000", env = "NESCOPE_FRAME_CALLBACK_HZ")]
|
||||
frame_callback_hz: u32,
|
||||
|
||||
/// Enable HDR protocols (wp_color_management_v1 + gamescope_swapchain_factory_v2).
|
||||
#[arg(long, env = "NESCOPE_HDR")]
|
||||
hdr: bool,
|
||||
@@ -386,9 +413,17 @@ fn main() {
|
||||
}
|
||||
|
||||
// ── Frame-callback timer ──────────────────────────────────────────────
|
||||
// Send wl_surface.frame done events at the target fps. This is what
|
||||
// drives the game's render loop in the absence of a real scanout.
|
||||
let frame_interval = Duration::from_micros(1_000_000 / args.fps.max(1) as u64);
|
||||
// Sends wl_surface.frame done events, releases the held buffer and posts
|
||||
// presentation feedback.
|
||||
//
|
||||
// Deliberately *not* `--fps`. This cadence only ever throttles a FIFO
|
||||
// client, so using it as a frame limiter caps the games that opted into
|
||||
// V-Sync and does nothing at all to the ones that did not — which is the
|
||||
// wrong way round, and it capped them at 60 while sessions asked for 120.
|
||||
// The capture layer holds the game instead, and this runs fast enough to
|
||||
// stay out of the way.
|
||||
let frame_interval =
|
||||
Duration::from_micros(1_000_000 / args.frame_callback_hz.max(1) as u64);
|
||||
loop_handle
|
||||
.insert_source(Timer::from_duration(frame_interval), move |_, _, data| {
|
||||
if let Some(ref mut li) = data.libinput {
|
||||
|
||||
Reference in New Issue
Block a user