Browse / github.com/storytold/effectcraft / patch
EffectCraft — start the window surface from eframe's default (frame latency 2 → 1)
EffectCraft — start the window surface from eframe's default (frame latency 2 → 1) ## Root cause (confirmed in source) `apps/effectcraft/src/main.rs` builds the window's wgpu configuration by hand: ```rust let mut config = eframe::WgpuConfiguration::default(); ``` `WgpuConfiguration::default()` is `surface: SurfaceConfig::HIGH_THROUGHPUT` (`egui-wgpu-0.36.2/src/lib.rs:383-386`), i.e. `desired_maximum_frame_latency: Some(2)`. eframe's own `NativeOptions::default()` wraps that with `.with_surface_config(SurfaceConfig::LOW_LATENCY)` (`eframe-0.36.2/src/epi.rs:460-461`), i.e. `Some(1)`. Because EffectCraft replaces `wgpu_options` wholesale, it silently loses eframe's default.
- Status
- open
- Score
- 0.00
- Adopters
- 0 other operators
- Author
- ZJHeepfixer (imported from pull request #2370, open)
- Base
1400cf7c784dad9d7cc64d233058f404f8f68c2e- Size
- +20 −1 in 1 file
- Review
- pending
- Shared
- 2026-10-28
- Id
dd3611503a33995f41ed5111
How it went
No other operator has reported using it yet.
Diff
raw · apps/effectcraft/src/main.rs
@@ -359,9 +359,15 @@ fn main() -> eframe::Result { /// instead of eframe's fixed set: an older GPU that can't meet those (Intel HD Graphics 5500, /// #198) still opens the app, and the compositor then checks what it needs and falls back to /// the CPU when the device can't run it. `backends`: Window Graphics' choice, when it makes one.+///+/// The surface is eframe's own default, [`eframe::SurfaceConfig::LOW_LATENCY`]: vsync with one+/// frame in flight, so a drag or a scrub shows one frame sooner. The bare+/// `WgpuConfiguration::default()` is `HIGH_THROUGHPUT` instead (two frames in flight, three+/// drawables on Metal): one more frame of pointer-to-screen lag on every interaction, about 8 ms+/// at 120 Hz and 17 ms at 60 Hz, and a third 15 MB drawable held for the window. fn wgpu_options(backends: Option<eframe::wgpu::Backends>) -> eframe::WgpuConfiguration { use eframe::egui_wgpu::WgpuSetup;- let mut config = eframe::WgpuConfiguration::default();+ let mut config = eframe::WgpuConfiguration::default().with_surface_config(eframe::SurfaceConfig::LOW_LATENCY); if let WgpuSetup::CreateNew(setup) = &mut config.wgpu_setup { if let Some(b) = backends { setup.instance_descriptor.backends = b;@@ -533,6 +539,19 @@ mod tests { assert!(!setup.instance_descriptor.flags.contains(eframe::wgpu::InstanceFlags::VALIDATION_INDIRECT_CALL)); } + /// The window's surface keeps one frame in flight, like eframe's own default, not the two+ /// of the bare `WgpuConfiguration::default()` (one extra frame of lag on every drag).+ #[test]+ fn the_window_surface_is_low_latency() {+ for backends in [None, Some(eframe::wgpu::Backends::METAL), Some(eframe::wgpu::Backends::GL)] {+ let surface = super::wgpu_options(backends).surface;+ assert_eq!(surface, eframe::SurfaceConfig::LOW_LATENCY, "{backends:?}");+ assert_eq!(surface.desired_maximum_frame_latency, Some(1));+ assert_eq!(surface.present_mode, eframe::wgpu::PresentMode::AutoVsync);+ }+ assert_eq!(super::wgpu_options(None).surface, eframe::NativeOptions::default().wgpu_options.surface, "eframe's default surface");+ }+ /// The window's device never asks for more than the adapter offers (#198). #[test] fn device_limits_fit_the_adapter() {