Skip to content

Commit fef8f2a

Browse files
committed
Introduce AbstractWindowHandle enum
1 parent da96f15 commit fef8f2a

File tree

4 files changed

+87
-77
lines changed

4 files changed

+87
-77
lines changed

crates/bevy_render/src/lib.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub mod view;
2121

2222
use bevy_core::FrameCount;
2323
use bevy_hierarchy::ValidParentCheckPlugin;
24+
use bevy_window::AbstractWindowHandle;
2425
pub use extract_param::Extract;
2526

2627
pub mod prelude {
@@ -144,17 +145,19 @@ impl Plugin for RenderPlugin {
144145
.register_type::<Color>();
145146

146147
if let Some(backends) = options.backends {
147-
let windows = app.world.resource_mut::<bevy_window::Windows>();
148148
let instance = wgpu::Instance::new(backends);
149-
150-
let surface = windows
151-
.get_primary()
152-
.and_then(|window| window.raw_window_handle())
153-
.map(|wrapper| unsafe {
154-
let handle = wrapper.get_handle();
155-
instance.create_surface(&handle)
149+
let surface = {
150+
let windows = app.world.resource_mut::<bevy_window::Windows>();
151+
let raw_handle = windows.get_primary().and_then(|window| unsafe {
152+
match window.window_handle() {
153+
AbstractWindowHandle::RawWindowHandle(handle) => {
154+
Some(instance.create_surface(&handle.get_handle()))
155+
}
156+
AbstractWindowHandle::Virtual => None,
157+
}
156158
});
157-
159+
raw_handle
160+
};
158161
let request_adapter_options = wgpu::RequestAdapterOptions {
159162
power_preference: options.power_preference,
160163
compatible_surface: surface.as_ref(),

crates/bevy_render/src/view/window.rs

Lines changed: 49 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::{
66
use bevy_app::{App, Plugin};
77
use bevy_ecs::prelude::*;
88
use bevy_utils::{tracing::debug, HashMap, HashSet};
9-
use bevy_window::{PresentMode, RawWindowHandleWrapper, WindowClosed, WindowId, Windows};
9+
use bevy_window::{AbstractWindowHandle, PresentMode, WindowClosed, WindowId, Windows};
1010
use std::ops::{Deref, DerefMut};
1111

1212
/// Token to ensure a system runs on the main thread.
@@ -38,7 +38,7 @@ impl Plugin for WindowRenderPlugin {
3838

3939
pub struct ExtractedWindow {
4040
pub id: WindowId,
41-
pub raw_window_handle: Option<RawWindowHandleWrapper>,
41+
pub handle: AbstractWindowHandle,
4242
pub physical_width: u32,
4343
pub physical_height: u32,
4444
pub present_mode: PresentMode,
@@ -83,7 +83,7 @@ fn extract_windows(
8383
.entry(window.id())
8484
.or_insert(ExtractedWindow {
8585
id: window.id(),
86-
raw_window_handle: window.raw_window_handle(),
86+
handle: window.window_handle(),
8787
physical_width: new_width,
8888
physical_height: new_height,
8989
present_mode: window.present_mode(),
@@ -132,7 +132,7 @@ pub struct WindowSurfaces {
132132

133133
/// Creates and (re)configures window surfaces, and obtains a swapchain texture for rendering.
134134
///
135-
/// This will not handle [virtual windows](bevy_window::Window::new_virtual).
135+
/// This will not handle [virtual windows](bevy_window::AbstractWindowHandle::Virtual).
136136
///
137137
/// NOTE: `get_current_texture` in `prepare_windows` can take a long time if the GPU workload is
138138
/// the performance bottleneck. This can be seen in profiles as multiple prepare-stage systems all
@@ -165,58 +165,59 @@ pub fn prepare_windows(
165165
) {
166166
let window_surfaces = window_surfaces.deref_mut();
167167
for window in windows.windows.values_mut() {
168-
if let Some(handle) = &window.handle {
169-
let surface = window_surfaces
168+
let surface = match &window.handle {
169+
AbstractWindowHandle::RawWindowHandle(handle) => window_surfaces
170170
.surfaces
171171
.entry(window.id)
172172
.or_insert_with(|| unsafe {
173173
// NOTE: On some OSes this MUST be called from the main thread.
174174
render_instance.create_surface(&handle.get_handle())
175-
});
175+
}),
176+
AbstractWindowHandle::Virtual => continue,
177+
};
178+
179+
let swap_chain_descriptor = wgpu::SurfaceConfiguration {
180+
format: *surface
181+
.get_supported_formats(&render_adapter)
182+
.get(0)
183+
.unwrap_or_else(|| {
184+
panic!(
185+
"No supported formats found for surface {:?} on adapter {:?}",
186+
surface, render_adapter
187+
)
188+
}),
189+
width: window.physical_width,
190+
height: window.physical_height,
191+
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
192+
present_mode: match window.present_mode {
193+
PresentMode::Fifo => wgpu::PresentMode::Fifo,
194+
PresentMode::Mailbox => wgpu::PresentMode::Mailbox,
195+
PresentMode::Immediate => wgpu::PresentMode::Immediate,
196+
PresentMode::AutoVsync => wgpu::PresentMode::AutoVsync,
197+
PresentMode::AutoNoVsync => wgpu::PresentMode::AutoNoVsync,
198+
},
199+
};
200+
201+
// Do the initial surface configuration if it hasn't been configured yet. Or if size or
202+
// present mode changed.
203+
if window_surfaces.configured_windows.insert(window.id)
204+
|| window.size_changed
205+
|| window.present_mode_changed
206+
{
207+
render_device.configure_surface(surface, &swap_chain_descriptor);
208+
}
176209

177-
let swap_chain_descriptor = wgpu::SurfaceConfiguration {
178-
format: *surface
179-
.get_supported_formats(&render_adapter)
180-
.get(0)
181-
.unwrap_or_else(|| {
182-
panic!(
183-
"No supported formats found for surface {:?} on adapter {:?}",
184-
surface, render_adapter
185-
)
186-
}),
187-
width: window.physical_width,
188-
height: window.physical_height,
189-
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
190-
present_mode: match window.present_mode {
191-
PresentMode::Fifo => wgpu::PresentMode::Fifo,
192-
PresentMode::Mailbox => wgpu::PresentMode::Mailbox,
193-
PresentMode::Immediate => wgpu::PresentMode::Immediate,
194-
PresentMode::AutoVsync => wgpu::PresentMode::AutoVsync,
195-
PresentMode::AutoNoVsync => wgpu::PresentMode::AutoNoVsync,
196-
},
197-
};
198-
199-
// Do the initial surface configuration if it hasn't been configured yet. Or if size or
200-
// present mode changed.
201-
if window_surfaces.configured_windows.insert(window.id)
202-
|| window.size_changed
203-
|| window.present_mode_changed
204-
{
210+
let frame = match surface.get_current_texture() {
211+
Ok(swap_chain_frame) => swap_chain_frame,
212+
Err(wgpu::SurfaceError::Outdated) => {
205213
render_device.configure_surface(surface, &swap_chain_descriptor);
214+
surface
215+
.get_current_texture()
216+
.expect("Error reconfiguring surface")
206217
}
218+
err => err.expect("Failed to acquire next swap chain texture!"),
219+
};
207220

208-
let frame = match surface.get_current_texture() {
209-
Ok(swap_chain_frame) => swap_chain_frame,
210-
Err(wgpu::SurfaceError::Outdated) => {
211-
render_device.configure_surface(surface, &swap_chain_descriptor);
212-
surface
213-
.get_current_texture()
214-
.expect("Error reconfiguring surface")
215-
}
216-
err => err.expect("Failed to acquire next swap chain texture!"),
217-
};
218-
219-
window.swap_chain_texture = Some(TextureView::from(frame));
220-
}
221+
window.swap_chain_texture = Some(TextureView::from(frame));
221222
}
222223
}

crates/bevy_window/src/window.rs

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,21 @@ impl WindowResizeConstraints {
151151
}
152152
}
153153

154+
/// Handle used for creating surfaces in the render plugin
155+
///
156+
/// Either a raw handle to an OS window or `Virtual` to signify that there is no corresponding OS window.
157+
#[derive(Clone, Debug)]
158+
pub enum AbstractWindowHandle {
159+
/// The window corresponds to an operator system window.
160+
RawWindowHandle(RawWindowHandleWrapper),
161+
/// The window does not to correspond to an operator system window.
162+
///
163+
/// It differs from a non-virtual window, in that the caller is responsible
164+
/// for creating and presenting surface textures and inserting them into
165+
/// [`ExtractedWindow`](https://docs.rs/bevy/*/bevy/render/view/struct.ExtractedWindow.html).
166+
Virtual,
167+
}
168+
154169
/// An operating system or virtual window that can present content and receive user input.
155170
///
156171
/// To create a window, use a [`EventWriter<CreateWindow>`](`crate::CreateWindow`).
@@ -259,7 +274,7 @@ pub struct Window {
259274
cursor_visible: bool,
260275
cursor_locked: bool,
261276
physical_cursor_position: Option<DVec2>,
262-
raw_window_handle: Option<RawWindowHandleWrapper>,
277+
window_handle: AbstractWindowHandle,
263278
focused: bool,
264279
mode: WindowMode,
265280
canvas: Option<String>,
@@ -368,7 +383,7 @@ impl Window {
368383
physical_height: u32,
369384
scale_factor: f64,
370385
position: Option<IVec2>,
371-
raw_window_handle: Option<RawWindowHandle>,
386+
raw_window_handle: RawWindowHandle,
372387
) -> Self {
373388
Window {
374389
id,
@@ -388,7 +403,9 @@ impl Window {
388403
cursor_locked: window_descriptor.cursor_locked,
389404
cursor_icon: CursorIcon::Default,
390405
physical_cursor_position: None,
391-
raw_window_handle: Some(RawWindowHandleWrapper::new(raw_window_handle)),
406+
window_handle: AbstractWindowHandle::RawWindowHandle(RawWindowHandleWrapper::new(
407+
raw_window_handle,
408+
)),
392409
focused: true,
393410
mode: window_descriptor.mode,
394411
canvas: window_descriptor.canvas.clone(),
@@ -399,11 +416,7 @@ impl Window {
399416

400417
/// Creates a new virtual [`Window`].
401418
///
402-
/// This window does not have to correspond to an operator system window.
403-
///
404-
/// It differs from a non-virtual window, in that the caller is responsible
405-
/// for creating and presenting surface textures and inserting them into
406-
/// [`ExtractedWindow`](https://docs.rs/bevy/*/bevy/render/view/struct.ExtractedWindow.html).
419+
/// See [`AbstractWindowHandle::Virtual`].
407420
pub fn new_virtual(
408421
id: WindowId,
409422
window_descriptor: &WindowDescriptor,
@@ -430,7 +443,7 @@ impl Window {
430443
cursor_locked: window_descriptor.cursor_locked,
431444
cursor_icon: CursorIcon::Default,
432445
physical_cursor_position: None,
433-
raw_window_handle: None,
446+
window_handle: AbstractWindowHandle::Virtual,
434447
focused: true,
435448
mode: window_descriptor.mode,
436449
canvas: window_descriptor.canvas.clone(),
@@ -816,16 +829,9 @@ impl Window {
816829
self.focused
817830
}
818831

819-
/// Get the [`RawWindowHandleWrapper`] corresponding to this window.
820-
///
821-
/// A return value of `None` signifies that this is a virtual window and does not
822-
/// correspond to an OS window. The creator of the window is responsible
823-
/// for creating and presenting surface textures and inserting them into
824-
/// [`ExtractedWindow`](https://docs.rs/bevy/*/bevy/render/view/struct.ExtractedWindow.html).
825-
///
826-
/// See [`Self::new_virtual`].
827-
pub fn raw_window_handle(&self) -> Option<RawWindowHandleWrapper> {
828-
self.raw_window_handle.clone()
832+
/// Get the [`AbstractWindowHandle`] corresponding to this window.
833+
pub fn window_handle(&self) -> AbstractWindowHandle {
834+
self.window_handle.clone()
829835
}
830836

831837
/// The "html canvas" element selector.

crates/bevy_winit/src/winit_windows.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ impl WinitWindows {
201201
inner_size.height,
202202
scale_factor,
203203
position,
204-
Some(raw_window_handle),
204+
raw_window_handle,
205205
)
206206
}
207207

0 commit comments

Comments
 (0)