bevy icon indicating copy to clipboard operation
bevy copied to clipboard

Bevy 0.10 regression: very long startup if `WinitSettings.unfocused_mode` is set to `UpdateMode::Reactive`

Open JayceFayne opened this issue 1 year ago • 6 comments

Bevy version

The release number or commit hash of the version you're using.

0.10/0.11/0.12

Relevant system information

Arch Linux

What you did

Running https://github.com/JayceFayne/bevy_regression Pasting main.rs below:

use bevy::prelude::*;
use bevy::winit::WinitSettings;

fn main() {
    App::new()
        .insert_resource(WinitSettings::desktop_app())
        .add_plugins(DefaultPlugins.build())
        .run();
}

What went wrong

Takes very long to start on bevy 0.10/0.11/0.12

Additional information

Downgrading to 0.9 fixes the issue

JayceFayne avatar Mar 08 '23 16:03 JayceFayne

Could you give us a before / after tracing flamegraph? This might be due to the more involved system graph processing.

If that's the case, there are a number of things we can do to improve performance there, ranging from simple optimizations to caching the graph on disk.

See https://github.com/bevyengine/bevy/blob/main/docs/profiling.md for more info.

alice-i-cecile avatar Mar 08 '23 16:03 alice-i-cecile

Alternatively, given your reproduction this could just be a bug with how we / winit is handling that specific mode.

alice-i-cecile avatar Mar 08 '23 16:03 alice-i-cecile

Could you give us a before / after tracing flamegraph? This might be due to the more involved system graph processing.

If that's the case, there are a number of things we can do to improve performance there, ranging from simple optimizations to caching the graph on disk.

See https://github.com/bevyengine/bevy/blob/main/docs/profiling.md for more info.

Sure, I have traces for 0.9 and 0.10 in chrome tracing format, ~~I'll attach them here.~~ Since github does not allow me to upload json files I'll upload the rendered flamegraph. 0 9 0 10

My guess is that the 60 sec wait in 0.10 is because max_wait is set to 60 secs in unfocused mode for the desktop_app preset.

JayceFayne avatar Mar 08 '23 16:03 JayceFayne

FYI in the future you can bypass that limitation by using .zip files :) And agreed: that looks squarely like a windowing bug: let's see if we can't get this fixed for 0.10.1...

alice-i-cecile avatar Mar 08 '23 18:03 alice-i-cecile

I've had a look at this and there are two parts that cause this behavior:

  1. Wayland initializes the window with an unfocused state and only displays and focuses the window after a frame is submitted.
  2. Pipelined rendering, which can cause app.update() to finish before the frame is submitted.

Tasks like running the prepare_windows system are spawned by a render thread to run on the main thread. If app.update() is already finished, those tasks have to wait until app.update() is called again.

With DefaultPlugins.build().disable::<PipelinedRenderingPlugin>() this issue does not appear, since the frame is submitted during the first app.update(). Winit sends a WindowEvent::Focused(false) event after creating the window, therefore the app is always updated at startup.

I think the most clean solution (from a task-stall-prevention perspective) would be to wake the main thread (by sending a user event through the winit event proxy) when a main-thread task is spawned by a render-thread, but this would require a lot of changes in a lot of unrelated places and probably hurt performance.

A more pragmatic solution could be to consider a Wayland window focused at creation (ignoring the WindowEvent::Focused(false) event unless we already received a WindowEvent::Focused(true) event for the same window). I can submit a PR for that if such a solution is acceptable.

geieredgar avatar Jun 25 '23 11:06 geieredgar

Just checking in after seeing Mastodon post: https://fosstodon.org/@[email protected]/111811705662087955

I can reproduce this issue on Wayland (Fedora 39, Sway WM) still, so I guess it is still a valid issue.

esensar avatar Jan 24 '24 16:01 esensar