From 59316de1e9a83e88809f9380168eb7f0aabb104f Mon Sep 17 00:00:00 2001 From: funman300 Date: Fri, 1 May 2026 01:35:49 +0000 Subject: [PATCH] perf(app): set PresentMode::AutoNoVsync to eliminate window-resize stalls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Smoke-test report: window resize was still laggy after the card-side throttle landed. Diagnosis pointed at the wgpu / OS layer rather than ECS work — Bevy's default PresentMode is AutoVsync (Fifo), which gates every frame on the monitor's vblank. On X11 / Wayland the compositor sends WindowResized events at high frequency during a drag and the vsync gate stalls each one, producing visible lag even when the downstream systems do almost no work. AutoNoVsync prefers Mailbox (triple-buffered, no blocking) and falls back to Immediate when the backend can't honour Mailbox. Either is fine for solitaire — the frame budget is tiny and the occasional dropped frame from disabling vsync is imperceptible compared to the stall this fixes. Layered with the prior in-place resize updates and the 50ms ResizeThrottle, this should bring the window-drag feel from "really laggy" to native-feeling. Co-Authored-By: Claude Opus 4.7 (1M context) --- solitaire_app/src/main.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/solitaire_app/src/main.rs b/solitaire_app/src/main.rs index fa94c1d..ab92ec2 100644 --- a/solitaire_app/src/main.rs +++ b/solitaire_app/src/main.rs @@ -3,7 +3,7 @@ use std::io::Write; use std::time::{SystemTime, UNIX_EPOCH}; use bevy::prelude::*; -use bevy::window::{MonitorSelection, WindowPosition}; +use bevy::window::{MonitorSelection, PresentMode, WindowPosition}; use solitaire_data::{load_settings_from, provider_for_backend, settings_file_path, Settings}; use solitaire_engine::{ AchievementPlugin, AnimationPlugin, AudioPlugin, AutoCompletePlugin, CardAnimationPlugin, @@ -50,6 +50,13 @@ fn main() { name: Some("solitaire-quest".into()), resolution: (1280u32, 800u32).into(), position: WindowPosition::Centered(MonitorSelection::Primary), + // AutoNoVsync prefers Mailbox (triple-buffered) and + // falls back to Immediate, eliminating the vsync stall + // that AutoVsync produces during continuous window + // resize on X11 / Wayland. The game's frame budget is + // small enough that a few stray dropped frames from + // disabling vsync are imperceptible. + present_mode: PresentMode::AutoNoVsync, resize_constraints: bevy::window::WindowResizeConstraints { min_width: 800.0, min_height: 600.0,