0

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?

Redirectk
  • 160
  • 9
  • Maybe using `control_flow.set_wait_until(std::time::Instant::now() + Duration::from_millis(10))` will solve your problem. You could also try using `control_flow.set_wait()` if your application doesn't need to be redrawn every 10ms (100Hz). – Thomas Saint-Gérand Apr 25 '23 at 20:04
  • I can't reproduce that problem with the code you posted, are you sure this is a [mre]? – cafce25 Apr 25 '23 at 20:06
  • @ThomasSaint-Gérand I tried several variations of that, and while that seems to work for the original empty event loop, it still doesn't work if I add some work in MainEventsCleared. – Redirectk Apr 25 '23 at 20:37
  • I think you can solve your problem by having your rendering code in a `RedrawRequested` match arm and by removing your call to `window.request_redraw()` – Thomas Saint-Gérand Apr 25 '23 at 21:56

1 Answers1

3

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 shoudldn'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).

cafce25
  • 15,907
  • 4
  • 25
  • 31