collective

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

diff --git a/apps/effectcraft/src/main.rs b/apps/effectcraft/src/main.rs--- a/apps/effectcraft/src/main.rs+++ b/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() {