Search code examples
performanceuser-interfacerustevent-loopwinit

Rust winit eventloop running too often


I have a simple winit application that is creating an empty window and running the EventLoop:

event_loop.run(move |event, _, control_flow| {
    control_flow.set_wait_until(std::time::Instant::now() + Duration::from_millis(1000));
    match event {
        Event::WindowEvent{ ref event, window_id, } => {},
        Event::MainEventsCleared => {
            window.request_redraw()
        },
        _ => {}
    }
});

On MacOS this process uses 100% of 1 core of CPU. If I remove the window.request_redraw call, or when I artificially limit with a thread sleep (regardless of setting wait until to control flow), the CPU usage falls dramatically to about 10%. This suggests that wait/wait until are not working correctly because I expect to only see calls to request_redraw every 1 second if I understood correctly.

Is there any way to limit the event loop run frequency other than thread::sleep/wait/wait until, or I am doing something else wrong?


Solution

  • WaitUntil causes:

    When the current loop iteration finishes, suspend the thread until either another event arrives or the given time is reached.

    and request_redraw

    Emits a Event::RedrawRequested event

    so unless I'm missing something everything works as expected.

    Because request_redraw causes an event to be emitted, the event loop immediately starts the next iteration.

    Also calling that method explicitly shouldn't be required since after MainEventsCleared

    Event::RedrawRequested, [...] gets emitted immediately

    Limiting that frequency artificialy will only cause a sluggish feel about your app which then could not immediately respond to events, so I doubt that's what you want. As far as I know winit doesn't provide such a feature (aside from the mentioned set_wait / set_wait_until).