Skip to content
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

Consistently deliver a Resumed event on all platforms #2331

Merged
merged 1 commit into from
Jul 26, 2022

Conversation

rib
Copy link
Contributor

@rib rib commented Jun 12, 2022

To be more consistent with mobile platforms this updates the Windows,
macOS, Wayland, X11 and Web backends to all emit a Resumed event
immediately after the initial NewEvents(StartCause::Init) event.

The documentation for the Resumed event has also been updated to
recommend that applications should wait until they receive the Resumed
event before creating any graphics context and their first window to
help ensure portability.

This consistency makes it possible to write applications that lazily
initialize their graphics state when the application resumes without
any platform-specific knowledge. Previously, applications that wanted
to run on Android needed to have target_os="android" specific code
to initialize within the Resumed event because that same logic
would never run on non-mobile platforms.

Relates to:
#2111 - Is it possible to automatically port over a GUI application from Linux/Windows to Android that was written in Rust?
#2185 - Documentation on Event::{Suspended, Resumed} is lacking
#2144 - Add Foreground and Background events for iOS
#2293 - Evolution of the Android backend

  • Tested on all platforms changed
    • Tested on Windows
    • Tested on X11
    • Tested on Wayland
    • Tested on macOS
    • Tested on iOS
    • Tested on Web
  • Added an entry to CHANGELOG.md if knowledge of this change could be valuable to users
  • Updated documentation to reflect any user-facing changes, including notes of platform-specific behavior
  • Created or updated an example program if it would help users understand this functionality

Fixes: #2185

@MarijnS95
Copy link
Member

Nit: you don't need to have cfg(target_os="android") on the events because they won't be firing anyway, but you do absolutely need them on the code that creates / initializes a graphics context on a created window.

src/event.rs Show resolved Hide resolved
src/platform_impl/web/event_loop/runner.rs Outdated Show resolved Hide resolved
CHANGELOG.md Show resolved Hide resolved
@MarijnS95 MarijnS95 changed the title Consistently deliver a Resumed event on all platforms Consistently deliver a Resumed event on all platforms Jun 12, 2022
@MarijnS95 MarijnS95 added this to the Version 0.27 milestone Jun 12, 2022
@MarijnS95
Copy link
Member

MarijnS95 commented Jun 12, 2022

@rib Do you think it's worth renaming these events in light of e.g. the massive discussion in #2118? Something closer to WindowCreated/WindowDestroyed? It doesn't map to Android's onPause/onResume bit of the cycle anyway.

@rib
Copy link
Contributor Author

rib commented Jun 12, 2022

Nit: you don't need to have cfg(target_os="android") on the events because they won't be firing anyway, but you do absolutely need them on the code that creates / initializes a graphics context on a created window.

:) Nit nit: A few benefits to cfg(target_os="android") guarding the Resumed events path for Android are:

  1. be clear where initialization happens on iOS which also emits Resumed events,
  2. being forwards compatible. Existing code that's guarded now (such as the linked code) can remain forwards compatible (at least as far as this specific code is concerned) with a future version of Winit that starts to emit Resumed events on all platforms - otherwise other platforms would start to initialize twice if a patch like this lands.

@MarijnS95
Copy link
Member

MarijnS95 commented Jun 12, 2022

:) Nit nit

I just think users weren't wrapping it like that, so perhaps this API change might already blow up if they created e.g. a swapchain, and then create it again in Resumed :D

They certainly don't/didn't need to, which is the word that was used in the description that I'm nitting about 😅 - but they did need to have it around their code outside the event loop that (indirectly) calls into fn raw_window_handle() or run into a nice panic on Android.

@rib
Copy link
Contributor Author

rib commented Jun 12, 2022

@rib Do you think it's worth renaming these events in light of e.g. the massive discussion in #2118? Something closer to WindowCreated/WindowDestroyed? It doesn't map to Android's onPause/onResume bit of the cycle anyway.

Something to consider here is that the existing Suspended and Resumed are also supported on iOS so any renaming of the existing events will affect the iOS backend too.

I think there's probably still some value in having some portable lifecycle events like "suspend" and "resume" that have reasonably practical mappings on Android and iOS - even though there's some nuance to how we define "suspended" on Android. (and as an asside I recall thinking the android backend should probably be mapping "suspended" to the logical OR of 'lifecycle suspended' and 'window destroyed', instead of directly to the 'window destroyed' state).

Since the mapping is a bit fuzzy if you need to handle some platform specific details I tend to think it would also be good if there was a practical way to also notified about Android or iOS specific lifecycle events. Maybe instead of having to expose any platform-specific details there could be some general PLATFORM_LIFECYCLE_CHANGED event which just provides the event loop wake up and then assumes apps can access that state easily via a platform-specific API.

What's extra funky here though is that the window destroyed / created events are not conceptually lifecycle events on Android.

@rib
Copy link
Contributor Author

rib commented Jun 12, 2022

:) Nit nit

I just think users weren't wrapping it like that, so perhaps this API change might already blow up if they created e.g. a swapchain, and then create it again in Resumed :D

They certainly don't/didn't need to, which is the word that was used in the description that I'm nitting about 😅 - but they did need to have it around their code outside the event loop that (indirectly) calls into fn raw_window_handle() or run into a nice panic on Android.

I concede the nit battle :) yeah, existing apps wouldn't necessarily need to cfg() guard mobile/android specific Resumed code if they rely on the Resumed event not being emitted and just guard the non-mobile code.

Since I've been guarding the android-specific Resumed path in some apps I've written recently (just to give me one fewer thing to consider in case we do end up landing a change like this) then my wording was probably just echoing what I've felt I needed to do to write portable, forwards-compatible winit code.

@rib rib force-pushed the consistent-resumed-event branch from adc4d35 to cdf12ca Compare June 13, 2022 15:06
@rib
Copy link
Contributor Author

rib commented Jun 13, 2022

Ok, with the updates I've pushed I bit the bullet and wrote much more comprehensive documentation for both the Suspended and Resumed events that provide some general guidance about writing portable applications as well as providing Android and iOS specific information so that developers can understand how these events map to OS-specific lifecycle details.

I had been thinking it could be good to try and deal with documentation improvements separately but while it makes sense to try and some general recommendations about handling these events it's a good opportunity to add more details too.

I've updated the commit message in line with these changes, and some of the comments above and I've now marked the patch as Resolving #2185

I updated the web backend change as suggested by @MarijnS95 above and at least smoke tested the change via cargo run-wasm --example web

Although this has provoked some interesting discussions around some of the Android specific thorns I think for now most of that looks like it probably deserves follow up issues + discussions and hopefully doesn't need to block making this incremental change for improved consistency first.

@MarijnS95
Copy link
Member

MarijnS95 commented Jun 14, 2022

Something to consider here is that the existing Suspended and Resumed are also supported on iOS so any renaming of the existing events will affect the iOS backend too.

Right, that makes this situation a bit more complicated as I have zero experience with iOS. Are these events purely used for window/surface creation and destruction there too?

I think there's probably still some value in having some portable lifecycle events like "suspend" and "resume" that have reasonably practical mappings on Android and iOS

Correct, hence, my linking to #2118 - that PR author also got thrown off by the unfortunate naming, as you said:

What's extra funky here though is that the window destroyed / created events are not conceptually lifecycle events on Android.

They are not, which is why I think we should have separate events that represent window creation/destruction. Android doesn't ever raise WindowEvent::Destroyed which should be used in place of Suspended. Then we can have separate events that propagate actual lifecycle events?


Since I've been guarding the android-specific Resumed path in some apps I've written recently (just to give me one fewer thing to consider in case we do end up landing a change like this) then my wording was probably just echoing what I've felt I needed to do to write portable, forwards-compatible winit code.

Exactly, I'll have to go over a bunch of applications and make sure that we're either guarding these or move the initialization for all platforms into ::Resumed.


Although this has provoked some interesting discussions around some of the Android specific thorns I think for now most of that looks like it probably deserves follow up issues + discussions and hopefully doesn't need to block making this incremental change for improved consistency first.

Fair enough, if your documentation looks good we should get this in as it is clearly an improvement over the status-quo - and separately before winit 0.27 please discuss whether we should rework the events entirely. Repeating what we both seem to agree on: these aren't strictly speaking lifecycle events (not at all, cc #2118), but window created and destroyed events that require the user to perform some resource handling (EDIT: Again I don't know about iOS, please enlighten me 😄).

@MarijnS95
Copy link
Member

https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622956-applicationdidbecomeactive / https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622950-applicationwillresignactive (these callbacks map to Resumed/Suspended resp.) mention to throttle up/down framerates, nothing said about needing to create/destroy surfaces.

More fuel for switching these to WindowEvent::{Created, Destroyed} on android and pull in onPause/onResume handling from #2118 that then maps to Suspended/Resumed?

src/event.rs Outdated
///
/// Also see [`Resumed`][Self::Resumed] notes.
///
/// # Android
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this fits under the Portability umbrella, should we make this h2 with two ##?

src/event.rs Outdated
/// destroyed, which indirectly invalidates any existing render surfaces that may have been
/// created outside of Winit (such as an `EGLSurface`, `VkSurfaceKHR` or [`wgpu::Surface`][wgpu_surface]).
///
/// [wgpu_surface]: https://docs.rs/wgpu/latest/wgpu/struct.Surface.html
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can also make this [`wgpu::Surface`] and remove the [wgpu_surface] link target entirely. Same for android_ls.

Shall we also add links for EGLSurface and (Ash's) VkSurfaceKHR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep the short hand wgpu::Surface linking makes sense.

There isn't really a canonical link for EGLSurface - the official EGL spec is a Khronos PDF. The Vulkan spec is at least published as HTML so could maybe link to the spec but not sure it's that important for either really.

Not sure about the "Same for android_ls" comment - that's a link about the Android activity life cycle so there wouldn't be a shorthand way of making that link?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can make that an [Android lifecycle]: https... too.

Yeah, link Vulkan if easy, I tried linking (E)GL in the ndk (see recent doc improvement PRs) and it's a bit of a hit and miss. Only need this if it's easy and makes it more clear to the user what you're talking about / referencing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh yeah I misinterpreted the comment about wgpu::Surface because I thought for a second there was dependency on wgpu::Surface and so we could rely on rustdoc figuring out the link, but that wasn't what you meant, you're meaning to avoid the separate link target which applies to the android_ls link too 👍

src/event.rs Outdated Show resolved Hide resolved
@rib
Copy link
Contributor Author

rib commented Jun 14, 2022

Something to consider here is that the existing Suspended and Resumed are also supported on iOS so any renaming of the existing events will affect the iOS backend too.

Right, that makes this situation a bit more complicated as I have zero experience with iOS. Are these events purely used for window/surface creation and destruction there too?

It's the other way around - they are purely iOS lifecycle based - and I'm fairly sure that there's no equivalent requirement to destroy and recreate render surfaces on iOS like there is on Android.

With the way they are currently mapped to the iOS lifecycle events though I have a feeling that it could be slightly better to map Suspended to iOS's "inactive" state. Currently Suspended gets mapped to "about to become inactive soon" on iOS. The subtlety here is that on iOS applications aren't required to stop rendering at this point (though they may reduce their frame rate) and I think perhaps Winit's Suspended event could be more clearly documented if it was a platform-agnostic way of indicating when rendering is blocked on Android and iOS. On iOS I think that would be when the app really becomes "inactive".

@rib
Copy link
Contributor Author

rib commented Jun 14, 2022

Since I've been guarding the android-specific Resumed path in some apps I've written recently (just to give me one fewer thing to consider in case we do end up landing a change like this) then my wording was probably just echoing what I've felt I needed to do to write portable, forwards-compatible winit code.

Exactly, I'll have to go over a bunch of applications and make sure that we're either guarding these or move the initialization for all platforms into ::Resumed.

Yeah, for sure, if we can land this change I'd be interested in seeing some (all ideally) of the examples be updated to demonstrate lazy initialization of graphics state via the Resumed event.

Ideally the first-party examples in the Winit repo can try to demonstrate how to write portable code that will run on all supported platforms - even if there are things that could be improved about the API to make it harder to write non-portable code.

Some of the examples here, demonstrate winit applications that can run on both Android and Windows:
https://github.com/rib/agdk-rust/tree/main/examples as well as this bluetooth UI: https://github.com/rib/bluey/tree/main/bluey-ui

It would be good to verify the same lazy initialization via Resumed also works as expected on web and iOS.

@rib
Copy link
Contributor Author

rib commented Jun 14, 2022

https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622956-applicationdidbecomeactive / https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622950-applicationwillresignactive (these callbacks map to Resumed/Suspended resp.) mention to throttle up/down framerates, nothing said about needing to create/destroy surfaces.

More fuel for switching these to WindowEvent::{Created, Destroyed} on android and pull in onPause/onResume handling from #2118 that then maps to Suspended/Resumed?

right, this is why I was suggesting the tweak on iOS that they should emit Suspended when the app really becomes "inactive" not before it becomes inactive. When the app is inactive then it shouldn't render so then there would be consistency.

I currently still think it's reasonable to keep the Suspended and Resumed events in Winit and documenting that they delimit when applications are blocked from rendering which is useful/meaningful on Android and iOS.

Another way to think about this is could be to essentially forget about "lifecycle" events for a moment and consider that those are just implementation details for the backend. The purpose of the Winit events would conceptually be to delimit when applications are blocked from from rendering. On iOS the implementation would map to being "inactive" and on Android that would map to "being paused OR not having a surface view" - but the platform specific lifecycle state is really just an implementation detail.

@kchibisov
Copy link
Member

I currently still think it's reasonable to keep the Suspended and Resumed events in Winit and documenting that they delimit when applications are blocked from rendering which is useful/meaningful on Android and iOS.

I think resume if fine, however could we name them Resume -> CouldStartDrawing, Suspend -> Suspend(action).

where

enum SuspendAction {
  ClearGraphicsContenxt,
  None,
  ThrottleDrawing
}

That was I think you can map it to anything and it'll be the most portable thing, since desktop platforms will have None or ThrottleDrawing, android will have ClearGraphicsContext, and ios should ThrottleDrawing.

The issue when the window should be created is also related to macOS, since the window should e created when the event loop is running, otherwise it could miss on some features iirc.

The problem with Resumed, since it's not clear for other platforms, suspend could be left as is.

@MarijnS95
Copy link
Member

and documenting that they delimit when applications are blocked from rendering

There's still quite a difference between "hey stop rendering now" and "hey you must recreate your graphics context/surface otherwise things don't work", and I think @kchibisov's suggestion solves that.

The problem with Resumed, since it's not clear for other platforms, suspend could be left as is.

We can have an enum ResumeAction too with the antonyms of what you suggested?

@maroider maroider requested a review from MarijnS95 July 23, 2022 09:30
@maroider maroider mentioned this pull request Jul 23, 2022
4 tasks
Copy link
Member

@MarijnS95 MarijnS95 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm okay with this after fixing the is is typo, and bringing up the same lifecycle-paused vs surface destroyed question: which may be simply addressed by s/Or/And which has been done for Resumed but not Suspended?

src/event.rs Outdated Show resolved Hide resolved
src/event.rs Outdated Show resolved Hide resolved
src/event.rs Outdated Show resolved Hide resolved
src/event.rs Outdated Show resolved Hide resolved
@rib rib force-pushed the consistent-resumed-event branch 2 times, most recently from 6c775dc to 9975660 Compare July 23, 2022 12:18
@rib
Copy link
Contributor Author

rib commented Jul 23, 2022

I just pushed an update that resolves the changelog conflict and fixes an "is is" typo that @MarijnS95 pointed out.

I haven't changed the wording about the implementation details that @MarijnS95 has recently commented on while I think the current wording is a correct reflection of the android-specific details.

There might be some better wording we could come up with to clarify further but I'd like to keep the information itself which the last suggested changes wouldn't do imho.

I also figure that this kind of re-wording can happen after the change lands. Even though this does try to improve the state of the docs for the Suspended/Resumed events, I think the technical consistency change is more important.

@rib rib force-pushed the consistent-resumed-event branch from 9975660 to b904d72 Compare July 23, 2022 12:46
@rib
Copy link
Contributor Author

rib commented Jul 23, 2022

last push tries to add a couple of lines to further clarify the android-specific logic for suspended/resumed events and fixes a copy and paste error that was noticed from @MarijnS95's comments:

--- a/src/event.rs
+++ b/src/event.rs
@@ -97,6 +97,9 @@ pub enum Event<'a, T: 'static> {
     /// 2. Or the application has had its associated [`SurfaceView`] destroyed (which is expected
     /// to closely correlate with being paused)
     ///
+    /// _(I.e. **either** of these may lead to a `Suspended` event, but applications should act
+    /// as if both have happened.)_
+    ///
     /// Applications that need to run on Android should assume their [`SurfaceView`] has been
     /// destroyed, which indirectly invalidates any existing render surfaces that may have been
     /// created outside of Winit (such as an `EGLSurface`, [`VkSurfaceKHR`] or [`wgpu::Surface`]).
@@ -145,11 +148,13 @@ pub enum Event<'a, T: 'static> {
     ///
     /// ## Android
     ///
-    /// On Android specifically, the [`Suspended`] event relates to two things:
+    /// On Android specifically, the `Resumed` event relates to two things:
     /// 1. The application has resumed (according to the [Activity lifecycle])
     /// 2. And the application has an associated [`SurfaceView`] (which is expected to closely correlate
     /// with being resumed)
     ///
+    /// _(I.e. **both** of these must happen before the application gets a `Resumed` event.)_
+    ///
     /// Applications that need to run on Android must wait until they have been `Resumed`
     /// before they will be able to create a render surface (such as an `EGLSurface`,
     /// [`VkSurfaceKHR`] or [`wgpu::Surface`]) which depend on having a

@rib rib force-pushed the consistent-resumed-event branch from b904d72 to a0e2601 Compare July 24, 2022 11:49
@rib
Copy link
Contributor Author

rib commented Jul 24, 2022

After realising that I was actually documenting the Android behaviour of the Suspend/Resumed events I have on a branch and not on master I've tweaked the technical descriptions for Android again - sorry for the churn.

Copy link
Member

@maroider maroider left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just have some minor phrasing and punctuation nits. The text is certainly a lot easier to read now.

src/event.rs Outdated Show resolved Hide resolved
src/event.rs Outdated Show resolved Hide resolved
src/event.rs Outdated Show resolved Hide resolved
src/event.rs Outdated Show resolved Hide resolved
src/event.rs Outdated Show resolved Hide resolved
src/event.rs Outdated Show resolved Hide resolved
src/event.rs Outdated Show resolved Hide resolved
src/event.rs Outdated Show resolved Hide resolved
@rib rib force-pushed the consistent-resumed-event branch from e4ca285 to 9ebeafc Compare July 25, 2022 13:21
To be more consistent with mobile platforms this updates the Windows,
macOS, Wayland, X11 and Web backends to all emit a Resumed event
immediately after the initial `NewEvents(StartCause::Init)` event.

The documentation for Suspended and Resumed has also been updated
to provide general recommendations for how to handle Suspended and
Resumed events in portable applications as well as providing
Android and iOS specific details.

This consistency makes it possible to write applications that lazily
initialize their graphics state when the application resumes without
any platform-specific knowledge. Previously, applications that wanted
to run on Android and other systems would have to maintain two,
mutually-exclusive, initialization paths.

Note: This patch does nothing to guarantee that Suspended events will
be delivered. It's still reasonable to say that most OSs without a
formal lifecycle for applications will simply never "suspend" your
application. There are currently no known portability issues caused
by not delivering `Suspended` events consistently and technically
it's not possible to guarantee the delivery of `Suspended` events if
the OS doesn't define an application lifecycle. (app can always be
terminated without any kind of clean up notification on most
non-mobile OSs)

Resolves: rust-windowing#2185

Co-authored-by: Marijn Suijten <[email protected]>
Co-authored-by: Markus Røyset <[email protected]>
@rib rib force-pushed the consistent-resumed-event branch from 9ebeafc to 1b95746 Compare July 25, 2022 13:24
@kchibisov kchibisov merged commit 6cdb317 into rust-windowing:master Jul 26, 2022
rib added a commit to rib/egui that referenced this pull request Aug 20, 2022
Conceptually the Winit `Resumed` event signifies that the application is
ready to run and render and since
rust-windowing/winit#2331 all platforms now
consistently emit a Resumed event that can be used to initialize
graphics state for an application.

On Android in particular it's important to wait until the application
has Resumed before initializing graphics state since it won't have an
associated SurfaceView while paused.

Without this change then Android applications are likely to just show
a black screen.

This updates the Wgpu+Winit and Glow+Winit integration for eframe but
it's worth noting that the Glow integration is still not able to fully
support Android due to limitations in with Glutin's API that mean
we can't destroy and create a Window without also destroying the
GL context, and therefore the entire application.

There is a plan (and progress on) to improve the Glutin API here:
rust-windowing/glutin#1435 and with that change
it should be an incremental change to enable Android support with Glow
later.

In the mean time the Glow changes keep the implementation consistent
with the wgpu integration and it should now at least be possible to
start an Android application - even though it won't be able to suspend
correctly.
rib added a commit to rib/egui that referenced this pull request Aug 21, 2022
Conceptually the Winit `Resumed` event signifies that the application is
ready to run and render and since
rust-windowing/winit#2331 all platforms now
consistently emit a Resumed event that can be used to initialize
graphics state for an application.

On Android in particular it's important to wait until the application
has Resumed before initializing graphics state since it won't have an
associated SurfaceView while paused.

Without this change then Android applications are likely to just show
a black screen.

This updates the Wgpu+Winit and Glow+Winit integration for eframe but
it's worth noting that the Glow integration is still not able to fully
support Android due to limitations in with Glutin's API that mean
we can't destroy and create a Window without also destroying the
GL context, and therefore the entire application.

There is a plan (and progress on) to improve the Glutin API here:
rust-windowing/glutin#1435 and with that change
it should be an incremental change to enable Android support with Glow
later.

In the mean time the Glow changes keep the implementation consistent
with the wgpu integration and it should now at least be possible to
start an Android application - even though it won't be able to suspend
correctly.
rib added a commit to rib/egui that referenced this pull request Aug 21, 2022
Conceptually the Winit `Resumed` event signifies that the application is
ready to run and render and since
rust-windowing/winit#2331 all platforms now
consistently emit a Resumed event that can be used to initialize
graphics state for an application.

On Android in particular it's important to wait until the application
has Resumed before initializing graphics state since it won't have an
associated SurfaceView while paused.

Without this change then Android applications are likely to just show
a black screen.

This updates the Wgpu+Winit and Glow+Winit integration for eframe but
it's worth noting that the Glow integration is still not able to fully
support Android due to limitations in with Glutin's API that mean
we can't destroy and create a Window without also destroying the
GL context, and therefore the entire application.

There is a plan (and progress on) to improve the Glutin API here:
rust-windowing/glutin#1435 and with that change
it should be an incremental change to enable Android support with Glow
later.

In the mean time the Glow changes keep the implementation consistent
with the wgpu integration and it should now at least be possible to
start an Android application - even though it won't be able to suspend
correctly.
rib added a commit to rib/egui that referenced this pull request Aug 21, 2022
Conceptually the Winit `Resumed` event signifies that the application is
ready to run and render and since
rust-windowing/winit#2331 all platforms now
consistently emit a Resumed event that can be used to initialize
graphics state for an application.

On Android in particular it's important to wait until the application
has Resumed before initializing graphics state since it won't have an
associated SurfaceView while paused.

Without this change then Android applications are likely to just show
a black screen.

This updates the Wgpu+Winit and Glow+Winit integration for eframe but
it's worth noting that the Glow integration is still not able to fully
support Android due to limitations in with Glutin's API that mean
we can't destroy and create a Window without also destroying the
GL context, and therefore the entire application.

There is a plan (and progress on) to improve the Glutin API here:
rust-windowing/glutin#1435 and with that change
it should be an incremental change to enable Android support with Glow
later.

In the mean time the Glow changes keep the implementation consistent
with the wgpu integration and it should now at least be possible to
start an Android application - even though it won't be able to suspend
correctly.
rib added a commit to rib/egui that referenced this pull request Aug 21, 2022
Conceptually the Winit `Resumed` event signifies that the application is
ready to run and render and since
rust-windowing/winit#2331 all platforms now
consistently emit a Resumed event that can be used to initialize
graphics state for an application.

On Android in particular it's important to wait until the application
has Resumed before initializing graphics state since it won't have an
associated SurfaceView while paused.

Without this change then Android applications are likely to just show
a black screen.

This updates the Wgpu+Winit and Glow+Winit integration for eframe but
it's worth noting that the Glow integration is still not able to fully
support suspend and resume on Android due to limitations with Glutin's
API that mean we can't destroy and create a Window without also
destroying the GL context, and therefore (practically) the entire
application.

There is a plan (and progress on) to improve the Glutin API here:
rust-windowing/glutin#1435 and with that change
it should be an incremental change to enable Android suspend/resume
support with Glow later.

In the mean time the Glow changes keep the implementation consistent
with the wgpu integration and it should now at least be possible to
start an Android application - even though it won't be able to suspend
correctly.
rib added a commit to rib/egui that referenced this pull request Aug 21, 2022
Conceptually the Winit `Resumed` event signifies that the application is
ready to run and render and since
rust-windowing/winit#2331 all platforms now
consistently emit a Resumed event that can be used to initialize
graphics state for an application.

On Android in particular it's important to wait until the application
has Resumed before initializing graphics state since it won't have an
associated SurfaceView while paused.

Without this change then Android applications are likely to just show
a black screen.

This updates the Wgpu+Winit and Glow+Winit integration for eframe but
it's worth noting that the Glow integration is still not able to fully
support suspend and resume on Android due to limitations with Glutin's
API that mean we can't destroy and create a Window without also
destroying the GL context, and therefore (practically) the entire
application.

There is a plan (and progress on) to improve the Glutin API here:
rust-windowing/glutin#1435 and with that change
it should be an incremental change to enable Android suspend/resume
support with Glow later.

In the mean time the Glow changes keep the implementation consistent
with the wgpu integration and it should now at least be possible to
start an Android application - even though it won't be able to suspend
correctly.
rib added a commit to rib/egui that referenced this pull request Aug 21, 2022
Conceptually the Winit `Resumed` event signifies that the application is
ready to run and render and since
rust-windowing/winit#2331 all platforms now
consistently emit a Resumed event that can be used to initialize
graphics state for an application.

On Android in particular it's important to wait until the application
has Resumed before initializing graphics state since it won't have an
associated SurfaceView while paused.

Without this change then Android applications are likely to just show
a black screen.

This updates the Wgpu+Winit and Glow+Winit integration for eframe but
it's worth noting that the Glow integration is still not able to fully
support suspend and resume on Android due to limitations with Glutin's
API that mean we can't destroy and create a Window without also
destroying the GL context, and therefore (practically) the entire
application.

There is a plan (and progress on) to improve the Glutin API here:
rust-windowing/glutin#1435 and with that change
it should be an incremental change to enable Android suspend/resume
support with Glow later.

In the mean time the Glow changes keep the implementation consistent
with the wgpu integration and it should now at least be possible to
start an Android application - even though it won't be able to suspend
correctly.
rib added a commit to rib/egui that referenced this pull request Aug 21, 2022
Conceptually the Winit `Resumed` event signifies that the application is
ready to run and render and since
rust-windowing/winit#2331 all platforms now
consistently emit a Resumed event that can be used to initialize
graphics state for an application.

On Android in particular it's important to wait until the application
has Resumed before initializing graphics state since it won't have an
associated SurfaceView while paused.

Without this change then Android applications are likely to just show
a black screen.

This updates the Wgpu+Winit and Glow+Winit integration for eframe but
it's worth noting that the Glow integration is still not able to fully
support suspend and resume on Android due to limitations with Glutin's
API that mean we can't destroy and create a Window without also
destroying the GL context, and therefore (practically) the entire
application.

There is a plan (and progress on) to improve the Glutin API here:
rust-windowing/glutin#1435 and with that change
it should be an incremental change to enable Android suspend/resume
support with Glow later.

In the mean time the Glow changes keep the implementation consistent
with the wgpu integration and it should now at least be possible to
start an Android application - even though it won't be able to suspend
correctly.

Fixes emilk#1951
rib added a commit to rib/egui that referenced this pull request Aug 21, 2022
Conceptually the Winit `Resumed` event signifies that the application is
ready to run and render and since
rust-windowing/winit#2331 all platforms now
consistently emit a Resumed event that can be used to initialize
graphics state for an application.

On Android in particular it's important to wait until the application
has Resumed before initializing graphics state since it won't have an
associated SurfaceView while paused.

Without this change then Android applications are likely to just show
a black screen.

This updates the Wgpu+Winit and Glow+Winit integration for eframe but
it's worth noting that the Glow integration is still not able to fully
support suspend and resume on Android due to limitations with Glutin's
API that mean we can't destroy and create a Window without also
destroying the GL context, and therefore (practically) the entire
application.

There is a plan (and progress on) to improve the Glutin API here:
rust-windowing/glutin#1435 and with that change
it should be an incremental change to enable Android suspend/resume
support with Glow later.

In the mean time the Glow changes keep the implementation consistent
with the wgpu integration and it should now at least be possible to
start an Android application - even though it won't be able to suspend
correctly.

Fixes emilk#1951
rib added a commit to rib/egui that referenced this pull request Aug 21, 2022
Conceptually the Winit `Resumed` event signifies that the application is
ready to run and render and since
rust-windowing/winit#2331 all platforms now
consistently emit a Resumed event that can be used to initialize
graphics state for an application.

On Android in particular it's important to wait until the application
has Resumed before initializing graphics state since it won't have an
associated SurfaceView while paused.

Without this change then Android applications are likely to just show
a black screen.

This updates the Wgpu+Winit and Glow+Winit integration for eframe but
it's worth noting that the Glow integration is still not able to fully
support suspend and resume on Android due to limitations with Glutin's
API that mean we can't destroy and create a Window without also
destroying the GL context, and therefore (practically) the entire
application.

There is a plan (and progress on) to improve the Glutin API here:
rust-windowing/glutin#1435 and with that change
it should be an incremental change to enable Android suspend/resume
support with Glow later.

In the mean time the Glow changes keep the implementation consistent
with the wgpu integration and it should now at least be possible to
start an Android application - even though it won't be able to suspend
correctly.

Fixes emilk#1951
emilk pushed a commit to emilk/egui that referenced this pull request Aug 23, 2022
* eframe: allow hooking into EventLoop building

This enables native applications to add an `event_loop_builder` callback
to the `NativeOptions` struct that lets them modify the Winit
`EventLoopBuilder` before the final `EventLoop` is built and run.

This makes it practical for applications to change platform
specific config options that Egui doesn't need to be directly aware of.

For example the `android-activity` glue crate that supports writing
Android applications in Rust requires that the Winit event loop be
passed a reference to the `AndroidApp` that is given to the
`android_main` entrypoint for the application.

Since the `AndroidApp` itself is abstracted by Winit then there's no
real need for Egui/EFrame to have a dependency on the `android-activity`
crate just for the sake of associating this state with the event loop.

Addresses: #1951

* eframe: defer graphics state initialization until app Resumed

Conceptually the Winit `Resumed` event signifies that the application is
ready to run and render and since
rust-windowing/winit#2331 all platforms now
consistently emit a Resumed event that can be used to initialize
graphics state for an application.

On Android in particular it's important to wait until the application
has Resumed before initializing graphics state since it won't have an
associated SurfaceView while paused.

Without this change then Android applications are likely to just show
a black screen.

This updates the Wgpu+Winit and Glow+Winit integration for eframe but
it's worth noting that the Glow integration is still not able to fully
support suspend and resume on Android due to limitations with Glutin's
API that mean we can't destroy and create a Window without also
destroying the GL context, and therefore (practically) the entire
application.

There is a plan (and progress on) to improve the Glutin API here:
rust-windowing/glutin#1435 and with that change
it should be an incremental change to enable Android suspend/resume
support with Glow later.

In the mean time the Glow changes keep the implementation consistent
with the wgpu integration and it should now at least be possible to
start an Android application - even though it won't be able to suspend
correctly.

Fixes #1951
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

Documentation on Event::{Suspended, Resumed} is lacking
4 participants