-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
Introduce a WindowWrapper
to extend the lifetime of the window when using pipelined rendering
#12978
Introduce a WindowWrapper
to extend the lifetime of the window when using pipelined rendering
#12978
Conversation
… using pipelined rendering
/// which gets picked up by the renderer during extraction. | ||
#[derive(Debug)] | ||
pub struct WindowWrapper<W> { | ||
reference: Arc<dyn Any + Send + Sync>, |
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.
Why does this need to be type erased instead of storing a Arc<W>
?
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.
This is so that we can later store this Arc in the RawHandleWrapper
without static typing:
bevy/crates/bevy_window/src/raw_handle.rs
Lines 47 to 48 in 5a01357
pub struct RawHandleWrapper { | |
_window: Arc<dyn Any + Send + Sync>, |
That Android CI failure is an oversight of mine. I've fixed it, so that it now compiles and runs successfully on my phone. |
I noticed that bevyengine#12978 introduces a reference counted wrapper around windows, but still uses `RawWindowHandle` and `RawDisplayHandle`, with `wgpu::Instance::create_surface_unsafe`. This can be changed easily enough to use `wgpu::Instance::create_surface`, and not use the raw handles anywhere. Apparently we can just cast a `Arc<W>` to an `Arc<dyn Trait>`, so that makes `WindowWrapper` a little simpler too.
I noticed that bevyengine#12978 introduces a reference counted wrapper around windows, but still uses `RawWindowHandle` and `RawDisplayHandle`, with `wgpu::Instance::create_surface_unsafe`. This can be changed easily enough to use `wgpu::Instance::create_surface`, and not use the raw handles anywhere. Apparently we can just cast a `Arc<W>` to an `Arc<dyn Trait>`, so that makes `WindowWrapper` a little simpler too.
I noticed that bevyengine#12978 introduces a reference counted wrapper around windows, but still uses `RawWindowHandle` and `RawDisplayHandle`, with `wgpu::Instance::create_surface_unsafe`. This can be changed easily enough to use `wgpu::Instance::create_surface`, and not use the raw handles anywhere. Apparently we can just cast a `Arc<W>` to an `Arc<dyn Trait>`, so that makes `WindowWrapper` a little simpler too.
Fixes two issues related to bevyengine#13208. First, we ensure render resources for a window are always dropped first to ensure that the `winit::Window` always drops on the main thread when it is removed from `WinitWindows`. Previously, changes in bevyengine#12978 caused the window to drop in the render world, causing issues. We accomplish this by delaying despawning the window by a frame by inserting a marker component `ClosingWindow` that indicates the window has been requested to close and is in the process of closing. The render world now responds to the equivalent `WindowClosing` event rather than `WindowCloseed` which now fires after the render resources are guarunteed to be cleaned up. Secondly, fixing the above caused (revealed?) that additional events were being delivered to the the event loop handler after exit had already been requested: in my testing `RedrawRequested` and `LoopExiting`. This caused errors to be reported try to send an exit event on the close channel. There are two options here: - Guard the handler so no additional events are delivered once the app is exiting. I considered this but worried it might be confusing or bug prone if in the future someone wants to handle `LoopExiting` or some other event to clean-up while exiting. - Only send an exit signal if we are not already exiting. It doesn't appear to cause any problems to handle the extra events so this seems safer. Fixing this also appears to have fixed bevyengine#13231.
Fixes two issues related to bevyengine#13208. First, we ensure render resources for a window are always dropped first to ensure that the `winit::Window` always drops on the main thread when it is removed from `WinitWindows`. Previously, changes in bevyengine#12978 caused the window to drop in the render world, causing issues. We accomplish this by delaying despawning the window by a frame by inserting a marker component `ClosingWindow` that indicates the window has been requested to close and is in the process of closing. The render world now responds to the equivalent `WindowClosing` event rather than `WindowCloseed` which now fires after the render resources are guarunteed to be cleaned up. Secondly, fixing the above caused (revealed?) that additional events were being delivered to the the event loop handler after exit had already been requested: in my testing `RedrawRequested` and `LoopExiting`. This caused errors to be reported try to send an exit event on the close channel. There are two options here: - Guard the handler so no additional events are delivered once the app is exiting. I considered this but worried it might be confusing or bug prone if in the future someone wants to handle `LoopExiting` or some other event to clean-up while exiting. - Only send an exit signal if we are not already exiting. It doesn't appear to cause any problems to handle the extra events so this seems safer. Fixing this also appears to have fixed bevyengine#13231.
Fixes two issues related to bevyengine#13208. First, we ensure render resources for a window are always dropped first to ensure that the `winit::Window` always drops on the main thread when it is removed from `WinitWindows`. Previously, changes in bevyengine#12978 caused the window to drop in the render world, causing issues. We accomplish this by delaying despawning the window by a frame by inserting a marker component `ClosingWindow` that indicates the window has been requested to close and is in the process of closing. The render world now responds to the equivalent `WindowClosing` event rather than `WindowCloseed` which now fires after the render resources are guarunteed to be cleaned up. Secondly, fixing the above caused (revealed?) that additional events were being delivered to the the event loop handler after exit had already been requested: in my testing `RedrawRequested` and `LoopExiting`. This caused errors to be reported try to send an exit event on the close channel. There are two options here: - Guard the handler so no additional events are delivered once the app is exiting. I considered this but worried it might be confusing or bug prone if in the future someone wants to handle `LoopExiting` or some other event to clean-up while exiting. - Only send an exit signal if we are not already exiting. It doesn't appear to cause any problems to handle the extra events so this seems safer. Fixing this also appears to have fixed bevyengine#13231.
# Objective Fixes two issues related to #13208. First, we ensure render resources for a window are always dropped first to ensure that the `winit::Window` always drops on the main thread when it is removed from `WinitWindows`. Previously, changes in #12978 caused the window to drop in the render world, causing issues. We accomplish this by delaying despawning the window by a frame by inserting a marker component `ClosingWindow` that indicates the window has been requested to close and is in the process of closing. The render world now responds to the equivalent `WindowClosing` event rather than `WindowCloseed` which now fires after the render resources are guarunteed to be cleaned up. Secondly, fixing the above caused (revealed?) that additional events were being delivered to the the event loop handler after exit had already been requested: in my testing `RedrawRequested` and `LoopExiting`. This caused errors to be reported try to send an exit event on the close channel. There are two options here: - Guard the handler so no additional events are delivered once the app is exiting. I ~considered this but worried it might be confusing or bug prone if in the future someone wants to handle `LoopExiting` or some other event to clean-up while exiting.~ We are now taking this approach. - Only send an exit signal if we are not already exiting. ~It doesn't appear to cause any problems to handle the extra events so this seems safer.~ Fixing this also appears to have fixed #13231. Fixes #10260. ## Testing Tested on mac only. --- ## Changelog ### Added - A `WindowClosing` event has been added that indicates the window will be despawned on the next frame. ### Changed - Windows now close a frame after their exit has been requested. ## Migration Guide - Ensure custom exit logic does not rely on the app exiting the same frame as a window is closed.
Objective
A
RawWindowHandle
is only valid as long as the window it was retrieved from is alive. Extend the lifetime of the window, so that theRawWindowHandle
doesn't outlive it, and bevy doesn't crash when closing a window a pipelined renderer is drawing to.BadWindow (invalid Window parameter)
when closing windows at seemingly random #11150Solution
Introduce a
WindowWrapper
that takes ownership of the window. Require it to be used when constructing aRawHandleWrapper
. This forces windowing backends to store their window in this wrapper.The
WindowWrapper
is implemented by storing the window in anArc<dyn Any + Send + Sync>
.We use dynamic dispatch here because we later want the
RawHandleWrapper
to be able dynamically hold a reference to any windowing backend's window.But alas, the
WindowWrapper
itself is still practically invisible to windowing backends, because it implementsDeref
to the underlying window, by storing its type in aPhantomData
.Changelog
Added
WindowWrapper
, which windowing backends are now required to use to store their underlying window.Fixed
Migration Guide
WindowWrapper
.