-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Winit 0.28 and android #6830
Winit 0.28 and android #6830
Conversation
Awesome, thanks for putting the work in. @rib, if you're able, I'd love your review here.
This is useful context that will help shape redesigns of plugins, thanks for raising it.
Eventually we might be able to get away with something involving a dedicated schedule for this. For now though I think the dumb-but-vaguely-functional solution is the right one. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for taking a look at this - I've taken a quick look over it, looking at the android-activity bits and added a few comments
crates/bevy_android/Cargo.toml
Outdated
bevy_log = { path = "../bevy_log", version = "0.9.0" } | ||
once_cell = "1.16" | ||
|
||
ndk = "0.7" # This version *must* be the same as the version used by android-activity |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure this is true, but might be overlooking something.
The ndk crate shouldn't have any static state, though there are some ndk types exposed by the android-activity crate, e.g. for input.
I would have expected there wouldn't be any conflict with using other versions, but maybe it's an issue considering that the only use of the ndk
crate in Bevy is in conjunction with an android-activity
API and some types don't match without picking the same version here.
Maybe android-activity and Winit could re-export the ndk
API similar to how the Winit crate re-exports the android-activity crate. That way you wouldn't have to worry about synchronizing this if you're only interested in using the same version that Winit and android-activity use.
This isn't the same as the previous requirement for the ndk-glue
crate version needing to match the version used by Winit. There is a similar requirement that the android-activity
crate must match watch Winit expects (for the same reason todo with how these glue crates are responsible for the main entrypoint of the application)
examples/android/Cargo.toml
Outdated
assets = "../../assets" | ||
resources = "../../assets/android-res" | ||
build_targets = ["aarch64-linux-android", "armv7-linux-androideabi"] | ||
#package = "org.bevyengine.example" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this stuff not still needed for building with cargo apk
? (which I guess can continue working while Bevy is using NativeActivity
)
examples/android/Cargo.toml
Outdated
@@ -7,23 +7,38 @@ publish = false | |||
license = "MIT OR Apache-2.0" | |||
|
|||
[lib] | |||
name = "bevy_android_example" | |||
crate-type = ["cdylib"] | |||
crate-type = ["cdylib", "rlib"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure what the rlib
is for here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rlib is for the main.rs, so its easy to run on desktop. If I remove it change [[bin]] src to lib.rs like you did in android-activity examples, they work but then you get these warnings:
warning: ~/bevy/examples/android/Cargo.toml: file found to be present in multiple build targets: ~/bevy/examples/android/src/lib.rs
About the suspend and resume stuff, I'm not sure it's quite as bad as it may seem. The only thing that needs to be re-created is the top-level render target/surface - not all wgpu rendering resources. I think there's often a bit of a confusion about this topic, perhaps in part because it used to be true a long time ago that Android required a full GPU context tear down on some devices when they suspended and resumed (there was notion that a context would be "lost") These days it's just the SurfaceView that is effectively dropped when the application suspends and the application can create a new render target and continue using it's pre-existing context and all gpu state (such as loaded textures etc). I think a good first step for supporting suspend / resume would probably be to update this branch based on the last comments (unfortunately t ran out of time to follow up on that): #4913 Enabling suspend should then mainly just be a question of getting Bevy to re-create the render target surface for each resume on Android. This android-activity example tries to illustrate how that can work with wgpu + winit applications: https://github.com/rib/android-activity/blob/main/examples/agdk-winit-wgpu/src/lib.rs In general though enabling suspend/resume support for Android can probably be treated as an orthogonal issue that shouldn't hold up an initial port to winit 0.28 + android-activity. |
Switch from using global to resource, AndroidResource (happy to change the name), and pulled fn android_main from bevymain macro. Without the global, main has to receive the app, a resource, or the android app its self, or an option wrapping the later two. Only the first option keeps non android builds from needing to know about android related crates. This breaks the intended use of bevymain, but there is no magic global state. |
I hadn't seen all the work in #4913, I got as far as recreating RenderApp resources and surfaces then threw in the towel once I started seeing the scope of the issue. You are far more knowledgeable in this area. |
Seems reasonable to me. Name seems ok, if a bit general maybe? Maybe it'd be good to have 'App' in the name? Personally I tend to think it's fine to not use the Maybe if there would be strong interest in making the |
crates/bevy_android/src/lib.rs
Outdated
#[cfg(target_os = "android")] | ||
use bevy_ecs::system::Resource; | ||
|
||
#[cfg(target_os = "android")] | ||
pub use ndk::asset::AssetManager; | ||
#[cfg(target_os = "android")] | ||
pub use winit::platform::android::activity::*; | ||
|
||
/// Resource containing AndroidApp | ||
#[cfg(target_os = "android")] | ||
pub struct AndroidResource { | ||
pub android_app: AndroidApp | ||
} | ||
|
||
#[cfg(target_os = "android")] | ||
impl Resource for AndroidResource {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this justify creating a new crate for it. Also, I would rather avoid having a bevy_android
crate where everything is behind a check for android.
Could it be placed in an existing crate?
examples/android/Cargo.toml
Outdated
assets = "../../assets" | ||
resources = "../../assets/android-res" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it possible to keep referencing the same asset folder?
5d706a4
to
febb8fe
Compare
# Objective - Update winit to 0.28 ## Solution - Small API change - A security advisory has been added for a unmaintained crate used by a dependency of winit build script for wayland I didn't do anything for Android support in this PR though it should be fixable, it should be done in a separate one, maybe #6830 --- ## Changelog - `window.always_on_top` has been removed, you can now use `window.window_level` ## Migration Guide before: ```rust app.new() .add_plugins(DefaultPlugins.set(WindowPlugin { primary_window: Some(Window { always_on_top: true, ..default() }), ..default() })); ``` after: ```rust app.new() .add_plugins(DefaultPlugins.set(WindowPlugin { primary_window: Some(Window { window_level: bevy::window::WindowLevel::AlwaysOnTop, ..default() }), ..default() })); ```
# Objective - Update winit to 0.28 ## Solution - Small API change - A security advisory has been added for a unmaintained crate used by a dependency of winit build script for wayland I didn't do anything for Android support in this PR though it should be fixable, it should be done in a separate one, maybe #6830 --- ## Changelog - `window.always_on_top` has been removed, you can now use `window.window_level` ## Migration Guide before: ```rust app.new() .add_plugins(DefaultPlugins.set(WindowPlugin { primary_window: Some(Window { always_on_top: true, ..default() }), ..default() })); ``` after: ```rust app.new() .add_plugins(DefaultPlugins.set(WindowPlugin { primary_window: Some(Window { window_level: bevy::window::WindowLevel::AlwaysOnTop, ..default() }), ..default() })); ```
Once #7493 is merged, please rebase (or redo) to capture the remaining fixes needed. |
The other work from this PR has already been merged, so closing this out. |
# Objective - Merge the examples on iOS and Android - Make sure they both work from the same code ## Solution - don't create window when not in an active state (from #6830) - exit on suspend on Android (from #6830) - automatically enable dependency feature of bevy_audio on android so that it works out of the box - don't inverse y position of touch events - reuse the same example for both Android and iOS Fixes #4616 Fixes #4103 Fixes #3648 Fixes #3458 Fixes #3249 Fixes #86
# Objective - Merge the examples on iOS and Android - Make sure they both work from the same code ## Solution - don't create window when not in an active state (from #6830) - exit on suspend on Android (from #6830) - automatically enable dependency feature of bevy_audio on android so that it works out of the box - don't inverse y position of touch events - reuse the same example for both Android and iOS Fixes #4616 Fixes #4103 Fixes #3648 Fixes #3458 Fixes #3249 Fixes #86
# Objective - Merge the examples on iOS and Android - Make sure they both work from the same code ## Solution - don't create window when not in an active state (from #6830) - exit on suspend on Android (from #6830) - automatically enable dependency feature of bevy_audio on android so that it works out of the box - don't inverse y position of touch events - reuse the same example for both Android and iOS Fixes #4616 Fixes #4103 Fixes #3648 Fixes #3458 Fixes #3249 Fixes #86
# Objective - Update winit to 0.28 ## Solution - Small API change - A security advisory has been added for a unmaintained crate used by a dependency of winit build script for wayland I didn't do anything for Android support in this PR though it should be fixable, it should be done in a separate one, maybe bevyengine/bevy#6830 --- ## Changelog - `window.always_on_top` has been removed, you can now use `window.window_level` ## Migration Guide before: ```rust app.new() .add_plugins(DefaultPlugins.set(WindowPlugin { primary_window: Some(Window { always_on_top: true, ..default() }), ..default() })); ``` after: ```rust app.new() .add_plugins(DefaultPlugins.set(WindowPlugin { primary_window: Some(Window { window_level: bevy::window::WindowLevel::AlwaysOnTop, ..default() }), ..default() })); ```
Objective
Currently Android support has a few issues. While learning winit I noticed 0.28 was going to change quite a bit for android thanks to @rib and this is an attempt to get ready for those and hopefully improve bevy android support. This is not complete, but I have enough working that a few more eyes would be welcome.
Solution
Two main changes changes with 0.28:
Workaround for Resume/Suspend on Android
I spend over a week working on trying to fix this the "ideal" way, but I am now of the option its not possible due to fact that it would be such burden to the rest of the bevy community it wouldn't be welcome. "After being
Suspended
on Android applications must drop all render surfaces before the event callback completes, which may be re-created when the application is nextResumed
." For bevy though this is a lot worse then it sounds, its not just window surfaces, its every render resource, basically anything wgpu had a hand in. We have no way to reload plugins much less any resource that's been added from systems or FromWorld impls and since some of these resources are dependent on each other the order they would be reloaded matters. It get even worse when you consider we don't know what to drop either.Simple but stupid work around, restart. If you exit the eventloop on suspend, android will restart you on resume, its not ideal, but its better than a blank screen or crashing.
Todo:
Tried to break this down, but its all winit and android releated