Skip to content

Commit

Permalink
Reduce iOS cpu usage (#16548)
Browse files Browse the repository at this point in the history
# Objective

- Avoid recreating the monitor every loop (temp fix until it's done
properly on winit side)
- Add a new `WinitSettings` preset for mobile that makes the winit loop
wait more and recommend its usage
  • Loading branch information
mockersf committed Nov 29, 2024
1 parent 4a5f21a commit ec10c5a
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 0 deletions.
10 changes: 10 additions & 0 deletions crates/bevy_winit/src/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,16 @@ pub fn create_monitors(
seen_monitors[idx] = true;
continue 'outer;
}
// on iOS, equality doesn't work, so we need to compare the names
// otherwise the monitor entity is recreated every time
// TODO: remove after https://github.com/rust-windowing/winit/pull/4013 has been released
#[cfg(target_os = "ios")]
{
if monitor.name() == m.name() {
seen_monitors[idx] = true;
continue 'outer;
}
}
}

let size = monitor.size();
Expand Down
13 changes: 13 additions & 0 deletions crates/bevy_winit/src/winit_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,19 @@ impl WinitSettings {
}
}

/// Default settings for mobile.
///
/// [`Reactive`](UpdateMode::Reactive) if windows have focus,
/// [`reactive_low_power`](UpdateMode::reactive_low_power) otherwise.
///
/// Use the [`EventLoopProxy`](crate::EventLoopProxy) to request a redraw from outside bevy.
pub fn mobile() -> Self {
WinitSettings {
focused_mode: UpdateMode::reactive(Duration::from_secs_f32(1.0 / 60.0)),
unfocused_mode: UpdateMode::reactive_low_power(Duration::from_secs(1)),
}
}

/// Returns the current [`UpdateMode`].
///
/// **Note:** The output depends on whether the window has focus or not.
Expand Down
4 changes: 4 additions & 0 deletions examples/mobile/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use bevy::{
log::{Level, LogPlugin},
prelude::*,
window::{AppLifecycle, WindowMode},
winit::WinitSettings,
};

// the `bevy_main` proc_macro generates the required boilerplate for iOS and Android
Expand All @@ -32,6 +33,9 @@ fn main() {
..default()
}),
)
// Make the winit loop wait more aggressively when no user input is received
// This can help reduce cpu usage on mobile devices
.insert_resource(WinitSettings::mobile())
.add_systems(Startup, (setup_scene, setup_music))
.add_systems(Update, (touch_camera, button_handler, handle_lifetime))
.run();
Expand Down

0 comments on commit ec10c5a

Please sign in to comment.