Open fredizzimo opened 1 year ago
When debugging another issue I saw the following calls stack
enum2$<core::result::Result<std::sync::mutex::MutexGuard<winit::platform_impl::platform::keyboard_layout::LayoutCache>,std::sync::poison::PoisonError<std::sync::mutex::MutexGuard<winit::platform_impl::platform::keyboard_layout::LayoutCache> > > > std::sync::mutex::Mutex<winit::platform_impl::platform::keyboard_layout::LayoutCache>::lock<winit::platform_impl::platform::keyboard_layout::LayoutCache>() (@std::sync::mutex::Mutex<T>::lock:13)
static struct alloc::vec::Vec<winit::platform_impl::platform::keyboard::MessageAsKeyEvent,alloc::alloc::Global> winit::platform_impl::platform::keyboard::KeyEventBuilder::synthesize_kbd_state(winit::event::ElementState, unsigned char[256] *) (c:\Users\fred.sundvik\.cargo\git\checkouts\winit-58efae9df3f5264a\4d8d82f\src\platform_impl\windows\keyboard.rs:336)
static union enum2$<winit::platform_impl::platform::keyboard::impl$1::process_message::MatchResult> winit::platform_impl::platform::keyboard::impl$1::process_message::closure$0(struct winit::platform_impl::platform::keyboard::impl$1::process_message::closure_env$0 *) (c:\Users\fred.sundvik\.cargo\git\checkouts\winit-58efae9df3f5264a\4d8d82f\src\platform_impl\windows\keyboard.rs:115)
struct alloc::vec::Vec<winit::platform_impl::platform::keyboard::MessageAsKeyEvent,alloc::alloc::Global> winit::platform_impl::platform::keyboard::KeyEventBuilder::process_message(__int64, unsigned int, unsigned __int64, __int64, union enum2$<winit::platform_impl::platform::event_loop::ProcResult> *) (c:\Users\fred.sundvik\.cargo\git\checkouts\winit-58efae9df3f5264a\4d8d82f\src\platform_impl\windows\keyboard.rs:319)
void winit::platform_impl::platform::event_loop::public_window_callback_inner::closure$2<enum2$<neovide::window::UserEvent> >(struct winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$2<enum2$<neovide::window::UserEvent> > *) (c:\Users\fred.sundvik\.cargo\git\checkouts\winit-58efae9df3f5264a\4d8d82f\src\platform_impl\windows\event_loop.rs:1016)
void core::ops::function::FnOnce::call_once<winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$2<enum2$<neovide::window::UserEvent> >,tuple$<> >(struct winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$2<enum2$<neovide::window::UserEvent> >) (@core::ops::function::FnOnce::call_once:8)
void core::panic::unwind_safe::impl$23::call_once<tuple$<>,winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$2<enum2$<neovide::window::UserEvent> > >(struct core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$2<enum2$<neovide::window::UserEvent> > >) (@<core::panic::unwind_safe::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once:10)
static void std::panicking::try::do_call<core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$2<enum2$<neovide::window::UserEvent> > >,tuple$<> >(unsigned char *) (@7ff7e12729e4..7ff7e1272a8e:3)
140014993 (@7ff7e1274993..7ff7e1274a01:3)
union enum2$<core::result::Result<tuple$<>,alloc::boxed::Box<dyn$<core::any::Any,core::marker::Send>,alloc::alloc::Global> > > std::panicking::try<tuple$<>,core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$2<enum2$<neovide::window::UserEvent> > > >(struct core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$2<enum2$<neovide::window::UserEvent> > >) (@std::panicking::try:18)
union enum2$<core::result::Result<tuple$<>,alloc::boxed::Box<dyn$<core::any::Any,core::marker::Send>,alloc::alloc::Global> > > std::panic::catch_unwind<core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$2<enum2$<neovide::window::UserEvent> > >,tuple$<> >(struct core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$2<enum2$<neovide::window::UserEvent> > >) (@std::panic::catch_unwind:5)
union enum2$<core::option::Option<tuple$<> > > winit::platform_impl::platform::event_loop::runner::EventLoopRunner<enum2$<neovide::window::UserEvent> >::catch_unwind<enum2$<neovide::window::UserEvent>,tuple$<>,winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$2<enum2$<neovide::window::UserEvent> > >(struct winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$2<enum2$<neovide::window::UserEvent> >) (c:\Users\fred.sundvik\.cargo\git\checkouts\winit-58efae9df3f5264a\4d8d82f\src\platform_impl\windows\event_loop\runner.rs:157)
static __int64 winit::platform_impl::platform::event_loop::public_window_callback_inner<enum2$<neovide::window::UserEvent> >(__int64, unsigned int, unsigned __int64, __int64, struct winit::platform_impl::platform::event_loop::WindowData<enum2$<neovide::window::UserEvent> > *) (c:\Users\fred.sundvik\.cargo\git\checkouts\winit-58efae9df3f5264a\4d8d82f\src\platform_impl\windows\event_loop.rs:1030)
__int64 winit::platform_impl::platform::event_loop::public_window_callback<enum2$<neovide::window::UserEvent> >(__int64, unsigned int, unsigned __int64, __int64) (c:\Users\fred.sundvik\.cargo\git\checkouts\winit-58efae9df3f5264a\4d8d82f\src\platform_impl\windows\event_loop.rs:968)
CallWindowProcW (@CallWindowProcW:248)
CallWindowProcW (@CallWindowProcW:39)
wglSwapBuffers (@wglSwapBuffers:129)
CallWindowProcW (@CallWindowProcW:248)
EnumChildWindows (@EnumChildWindows:78)
IsIconic (@IsIconic:108)
KiUserCallbackDispatcher (@KiUserCallbackDispatcher:10)
NtUserPeekMessage (@NtUserPeekMessage:8)
PeekMessageW (@PeekMessageW:127)
PeekMessageW (@PeekMessageW:80)
static union enum2$<core::option::Option<windows_sys::Windows::Win32::UI::WindowsAndMessaging::MSG> > winit::platform_impl::platform::keyboard::next_kbd_msg(__int64) (c:\Users\fred.sundvik\.cargo\git\checkouts\winit-58efae9df3f5264a\4d8d82f\src\platform_impl\windows\keyboard.rs:899)
static union enum2$<winit::platform_impl::platform::keyboard::impl$1::process_message::MatchResult> winit::platform_impl::platform::keyboard::impl$1::process_message::closure$0(struct winit::platform_impl::platform::keyboard::impl$1::process_message::closure_env$0 *) (c:\Users\fred.sundvik\.cargo\git\checkouts\winit-58efae9df3f5264a\4d8d82f\src\platform_impl\windows\keyboard.rs:292)
struct alloc::vec::Vec<winit::platform_impl::platform::keyboard::MessageAsKeyEvent,alloc::alloc::Global> winit::platform_impl::platform::keyboard::KeyEventBuilder::process_message(__int64, unsigned int, unsigned __int64, __int64, union enum2$<winit::platform_impl::platform::event_loop::ProcResult> *) (c:\Users\fred.sundvik\.cargo\git\checkouts\winit-58efae9df3f5264a\4d8d82f\src\platform_impl\windows\keyboard.rs:319)
void winit::platform_impl::platform::event_loop::public_window_callback_inner::closure$2<enum2$<neovide::window::UserEvent> >(struct winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$2<enum2$<neovide::window::UserEvent> > *) (c:\Users\fred.sundvik\.cargo\git\checkouts\winit-58efae9df3f5264a\4d8d82f\src\platform_impl\windows\event_loop.rs:1016)
void core::ops::function::FnOnce::call_once<winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$2<enum2$<neovide::window::UserEvent> >,tuple$<> >(struct winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$2<enum2$<neovide::window::UserEvent> >) (@core::ops::function::FnOnce::call_once:8)
void core::panic::unwind_safe::impl$23::call_once<tuple$<>,winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$2<enum2$<neovide::window::UserEvent> > >(struct core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$2<enum2$<neovide::window::UserEvent> > >) (@<core::panic::unwind_safe::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once:10)
static void std::panicking::try::do_call<core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$2<enum2$<neovide::window::UserEvent> > >,tuple$<> >(unsigned char *) (@7ff7e12729e4..7ff7e1272a8e:3)
140014993 (@7ff7e1274993..7ff7e1274a01:3)
union enum2$<core::result::Result<tuple$<>,alloc::boxed::Box<dyn$<core::any::Any,core::marker::Send>,alloc::alloc::Global> > > std::panicking::try<tuple$<>,core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$2<enum2$<neovide::window::UserEvent> > > >(struct core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$2<enum2$<neovide::window::UserEvent> > >) (@std::panicking::try:18)
union enum2$<core::result::Result<tuple$<>,alloc::boxed::Box<dyn$<core::any::Any,core::marker::Send>,alloc::alloc::Global> > > std::panic::catch_unwind<core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$2<enum2$<neovide::window::UserEvent> > >,tuple$<> >(struct core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$2<enum2$<neovide::window::UserEvent> > >) (@std::panic::catch_unwind:5)
union enum2$<core::option::Option<tuple$<> > > winit::platform_impl::platform::event_loop::runner::EventLoopRunner<enum2$<neovide::window::UserEvent> >::catch_unwind<enum2$<neovide::window::UserEvent>,tuple$<>,winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$2<enum2$<neovide::window::UserEvent> > >(struct winit::platform_impl::platform::event_loop::public_window_callback_inner::closure_env$2<enum2$<neovide::window::UserEvent> >) (c:\Users\fred.sundvik\.cargo\git\checkouts\winit-58efae9df3f5264a\4d8d82f\src\platform_impl\windows\event_loop\runner.rs:157)
static __int64 winit::platform_impl::platform::event_loop::public_window_callback_inner<enum2$<neovide::window::UserEvent> >(__int64, unsigned int, unsigned __int64, __int64, struct winit::platform_impl::platform::event_loop::WindowData<enum2$<neovide::window::UserEvent> > *) (c:\Users\fred.sundvik\.cargo\git\checkouts\winit-58efae9df3f5264a\4d8d82f\src\platform_impl\windows\event_loop.rs:1030)
__int64 winit::platform_impl::platform::event_loop::public_window_callback<enum2$<neovide::window::UserEvent> >(__int64, unsigned int, unsigned __int64, __int64) (c:\Users\fred.sundvik\.cargo\git\checkouts\winit-58efae9df3f5264a\4d8d82f\src\platform_impl\windows\event_loop.rs:968)
CallWindowProcW (@CallWindowProcW:248)
CallWindowProcW (@CallWindowProcW:39)
wglSwapBuffers (@wglSwapBuffers:129)
CallWindowProcW (@CallWindowProcW:248)
DispatchMessageW (@DispatchMessageW:172)
static int winit::platform_impl::platform::event_loop::EventLoop<enum2$<neovide::window::UserEvent> >::run_return<enum2$<neovide::window::UserEvent>,neovide::window::create_window::closure_env$1>(struct neovide::window::create_window::closure_env$1) (c:\Users\fred.sundvik\.cargo\git\checkouts\winit-58efae9df3f5264a\4d8d82f\src\platform_impl\windows\event_loop.rs:292)
void winit::platform_impl::platform::event_loop::EventLoop<enum2$<neovide::window::UserEvent> >::run<enum2$<neovide::window::UserEvent>,neovide::window::create_window::closure_env$1>(struct winit::platform_impl::platform::event_loop::EventLoop<enum2$<neovide::window::UserEvent> >, struct neovide::window::create_window::closure_env$1) (c:\Users\fred.sundvik\.cargo\git\checkouts\winit-58efae9df3f5264a\4d8d82f\src\platform_impl\windows\event_loop.rs:255)
void winit::event_loop::EventLoop<enum2$<neovide::window::UserEvent> >::run<enum2$<neovide::window::UserEvent>,neovide::window::create_window::closure_env$1>(struct winit::event_loop::EventLoop<enum2$<neovide::window::UserEvent> >, struct neovide::window::create_window::closure_env$1) (c:\Users\fred.sundvik\.cargo\git\checkouts\winit-58efae9df3f5264a\4d8d82f\src\event_loop.rs:305)
void neovide::window::create_window() (f:\neovide\src\window\mod.rs:618)
static void neovide::protected_main() (f:\neovide\src\main.rs:172)
static void neovide::main() (f:\neovide\src\main.rs:75)
void core::ops::function::FnOnce::call_once<void (*)(),tuple$<> >( *) (@core::ops::function::FnOnce::call_once:6)
void std::sys_common::backtrace::__rust_begin_short_backtrace<void (*)(),tuple$<> >( *) (@std::sys_common::backtrace::__rust_begin_short_backtrace:6)
int std::rt::lang_start::closure$0<tuple$<> >(struct std::rt::lang_start::closure_env$0<tuple$<> > *) (@std::rt::lang_start::{{closure}}:7)
void std::rt::lang_start_internal() (@std::rt::lang_start_internal:45)
__int64 std::rt::lang_start<tuple$<> >( *, __int64, unsigned char * *, unsigned char) (@std::rt::lang_start:16)
main (@main:9)
static int __scrt_common_main_seh() (@7ff7e1ecf16c..7ff7e1ecf1d3:3)
BaseThreadInitThunk (@BaseThreadInitThunk:8)
RtlUserThreadStart (@RtlUserThreadStart:13)
That is probably caused by these extra WM_PAINT messages and could explain why a few frames still are dropped on Windows with https://github.com/neovide/neovide/pull/1870.
Hi, it could be worth taking a look at https://github.com/rust-windowing/winit/pull/2767 where I've overhauled the structure of the event loops for each platform. Overall I'd say that the Windows backend was the one that changed the most, including enabling the use of PeekMessage when we want to check for messages without blocking.
Thank you @rib. That does indeed look promising. I will take a closer look, maybe during the weekend.
Winit is currently flooding the Windows event queue with
WM_PAINT
messages. Furthermore the main loop is always blocking withGetMessage
, waiting for eitherWM_PAINT
or another message to appear.This can cause long gaps between frames, event when
ControlFlow::Poll
is used. For example take a look at the following captureHere there was 3.89 ms between two calls with
MainEventsCleared
, almost half the frame budget when rendering at 120 FPS, causing a missed vsync here. Note that my loop is called two times in between with some other event, so this is not even a worst case, if there are multiple events, then the delay could be even longer.The main loop should never block, normally you use
PeekMessage
in a non-blocking loop on Windows, or completely decouple the rendering from the event loop.Due to this I'm forced to take the second appoach and use a separate loop for the rendering, but because the events takes a timeline it's quite invonvenient https://github.com/rust-windowing/winit/issues/1387 to pass the events to my rendering thread.
You could perhaps use some use event to singal a new pass of the loops, but polling with
PeekMessage
should be preferred.WM_PAINT
indirectly thoughRedrawWindow
is really bad, because it has a very special meaning to the operating system, and probably forces a lot of interna stuff related to the window to be updated, in addition to posting the even.Note there are a few issues I found releated to this, but not exactly the same https://github.com/rust-windowing/winit/issues/2698 - Not directly related, but decoupling the loop from
WM_PAINT
should fix the issue https://github.com/rust-windowing/winit/issues/2367 - This is mostly the same issue, the flooding ofWM_PAINT
, which is increadible slow causes other events to be delayed https://github.com/rust-windowing/winit/issues/2287 - However, my timings on Windows 11 are much, much worse than what's reported thereThe TLDR; for my suggestion is:
RedrawWindow
unless the user explicitly requests itControlFlow::Poll
, if there are no new eventsMainEventsCleared
should just be returned again.