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

Use raw-window-handle #1279

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,13 @@ default = [
dynamic = ["bevy_dylib"]

# Rendering support
render = ["bevy_internal/bevy_pbr", "bevy_internal/bevy_render", "bevy_internal/bevy_sprite", "bevy_internal/bevy_text", "bevy_internal/bevy_ui"]
render = [
"bevy_internal/bevy_pbr",
"bevy_internal/bevy_render",
Copy link
Member Author

Choose a reason for hiding this comment

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

This was a drive by automatic formatting, although I think this is nicer anyway

"bevy_internal/bevy_sprite",
"bevy_internal/bevy_text",
"bevy_internal/bevy_ui",
]

# Optional bevy crates
bevy_audio = ["bevy_internal/bevy_audio"]
Expand Down Expand Up @@ -76,14 +82,14 @@ x11 = ["bevy_internal/x11"]
subpixel_glyph_atlas = ["bevy_internal/subpixel_glyph_atlas"]

[dependencies]
bevy_dylib = {path = "crates/bevy_dylib", version = "0.4.0", default-features = false, optional = true}
bevy_internal = {path = "crates/bevy_internal", version = "0.4.0", default-features = false}
bevy_dylib = { path = "crates/bevy_dylib", version = "0.4.0", default-features = false, optional = true }
bevy_internal = { path = "crates/bevy_internal", version = "0.4.0", default-features = false }

[dev-dependencies]
anyhow = "1.0"
rand = "0.8.0"
ron = "0.6.2"
serde = {version = "1", features = ["derive"]}
serde = { version = "1", features = ["derive"] }

[[example]]
name = "hello_world"
Expand Down Expand Up @@ -406,3 +412,7 @@ icon = "@mipmap/ic_launcher"
build_targets = ["aarch64-linux-android", "armv7-linux-androideabi"]
min_sdk_version = 16
target_sdk_version = 29

[patch.crates-io]
# Latest commit breaks the entire ecosystem
raw-window-handle = { git = "https://github.com/rust-windowing/raw-window-handle", rev = "31d91a932c03b81dc0f3e05e4c11aa7a727b799b" }
2 changes: 0 additions & 2 deletions crates/bevy_wgpu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ license = "MIT"
keywords = ["bevy"]

[features]
default = ["bevy_winit"]
trace = ["wgpu/trace"]

[dependencies]
Expand All @@ -25,7 +24,6 @@ bevy_diagnostic = { path = "../bevy_diagnostic", version = "0.4.0" }
bevy_ecs = { path = "../bevy_ecs", version = "0.4.0" }
bevy_render = { path = "../bevy_render", version = "0.4.0" }
bevy_window = { path = "../bevy_window", version = "0.4.0" }
bevy_winit = { path = "../bevy_winit", optional = true, version = "0.4.0" }
bevy_utils = { path = "../bevy_utils", version = "0.4.0" }

# other
Expand Down
21 changes: 8 additions & 13 deletions crates/bevy_wgpu/src/wgpu_renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use bevy_render::{
render_graph::{DependentNodeStager, RenderGraph, RenderGraphStager},
renderer::RenderResourceContext,
};
use bevy_window::{WindowCreated, WindowResized, Windows};
use std::{ops::Deref, sync::Arc};
use bevy_window::{WindowCreated, WindowHandles, WindowResized};
use std::sync::Arc;

pub struct WgpuRenderer {
pub instance: wgpu::Instance,
Expand Down Expand Up @@ -79,22 +79,17 @@ impl WgpuRenderer {
let render_resource_context = render_resource_context
.downcast_mut::<WgpuRenderResourceContext>()
.unwrap();
let windows = resources.get::<Windows>().unwrap();
let handles = resources.get_thread_local::<WindowHandles>().unwrap();
let window_created_events = resources.get::<Events<WindowCreated>>().unwrap();
for window_created_event in self
for WindowCreated { id } in self
.window_created_event_reader
.iter(&window_created_events)
{
let window = windows
.get(window_created_event.id)
let handle = handles
.get(*id)
.expect("Received window created event for non-existent window.");
#[cfg(feature = "bevy_winit")]
{
let winit_windows = resources.get::<bevy_winit::WinitWindows>().unwrap();
let winit_window = winit_windows.get_window(window.id()).unwrap();
let surface = unsafe { self.instance.create_surface(winit_window.deref()) };
render_resource_context.set_window_surface(window.id(), surface);
}
let surface = unsafe { self.instance.create_surface(handle) };
render_resource_context.set_window_surface(*id, surface);
}
}

Expand Down
1 change: 1 addition & 0 deletions crates/bevy_window/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ bevy_app = { path = "../bevy_app", version = "0.4.0" }
bevy_ecs = { path = "../bevy_ecs", version = "0.4.0" }
bevy_math = { path = "../bevy_math", version = "0.4.0" }
bevy_utils = { path = "../bevy_utils", version = "0.4.0" }
raw-window-handle = "0.3.3"

# other

Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_window/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ impl Plugin for WindowPlugin {
.add_event::<WindowScaleFactorChanged>()
.add_event::<WindowBackendScaleFactorChanged>()
.add_event::<FileDragAndDrop>()
.init_resource::<Windows>();
.init_resource::<Windows>()
.init_thread_local_resource::<WindowHandles>();

if self.add_primary_window {
let resources = app.resources();
Expand Down
35 changes: 31 additions & 4 deletions crates/bevy_window/src/windows.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
use super::{Window, WindowId};
use bevy_utils::HashMap;
pub use raw_window_handle::TrustedWindowHandle;

#[derive(Debug, Default)]
pub struct Windows {
windows: HashMap<WindowId, Window>,
}

impl Windows {
pub fn add(&mut self, window: Window) {
self.windows.insert(window.id(), window);
}

pub fn get(&self, id: WindowId) -> Option<&Window> {
self.windows.get(&id)
}
Expand All @@ -35,3 +32,33 @@ impl Windows {
self.windows.values_mut()
}
}

#[derive(Default)]
/// A map from [`WindowId`] to [`TrustedWindowHandle`], stored as a thread_local_resource on the main thread.
///
/// Accessed by graphics backends to allow them to create surfaces for their windows
pub struct WindowHandles {
handles: HashMap<WindowId, TrustedWindowHandle>,
}

impl WindowHandles {
pub fn get(&self, id: WindowId) -> Option<&TrustedWindowHandle> {
self.handles.get(&id)
}
}

// This is the only way to add to windows, which ensures handles and Windows are kept in sync
/// Add a window to the `bevy` windowing system.
/// In general, this should only called by the windowing backend (which is by default provided by `bevy_winit`)
///
/// To create a window in a bevy application, send a [`crate::CreateWindow`] `Event`.
pub fn create_window(
windows: &mut Windows,
window: Window,
handles: &mut WindowHandles,
handle: TrustedWindowHandle,
) {
let id = window.id();
windows.windows.insert(id, window);
handles.handles.insert(id, handle);
}
1 change: 1 addition & 0 deletions crates/bevy_winit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ bevy_utils = { path = "../bevy_utils", version = "0.4.0" }

# other
winit = { version = "0.24.0", default-features = false }
raw-window-handle = "0.3.3"

[target.'cfg(target_arch = "wasm32")'.dependencies]
winit = { version = "0.24.0", features = ["web-sys"], default-features = false }
Expand Down
21 changes: 8 additions & 13 deletions crates/bevy_winit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ use bevy_ecs::{IntoSystem, Resources, World};
use bevy_math::Vec2;
use bevy_utils::tracing::{error, trace, warn};
use bevy_window::{
CreateWindow, CursorEntered, CursorLeft, CursorMoved, FileDragAndDrop, ReceivedCharacter,
WindowBackendScaleFactorChanged, WindowCloseRequested, WindowCreated, WindowFocused,
WindowResized, WindowScaleFactorChanged, Windows,
create_window, CreateWindow, CursorEntered, CursorLeft, CursorMoved, FileDragAndDrop,
ReceivedCharacter, WindowBackendScaleFactorChanged, WindowCloseRequested, WindowCreated,
WindowFocused, WindowHandles, WindowResized, WindowScaleFactorChanged, Windows,
};
use winit::{
event::{self, DeviceEvent, Event, WindowEvent},
Expand Down Expand Up @@ -461,17 +461,12 @@ fn handle_create_window_events(
) {
let mut winit_windows = resources.get_mut::<WinitWindows>().unwrap();
let mut windows = resources.get_mut::<Windows>().unwrap();
let mut handles = resources.get_thread_local_mut::<WindowHandles>().unwrap();
let create_window_events = resources.get::<Events<CreateWindow>>().unwrap();
let mut window_created_events = resources.get_mut::<Events<WindowCreated>>().unwrap();
for create_window_event in create_window_event_reader.iter(&create_window_events) {
let window = winit_windows.create_window(
event_loop,
create_window_event.id,
&create_window_event.descriptor,
);
windows.add(window);
window_created_events.send(WindowCreated {
id: create_window_event.id,
});
for CreateWindow { id, descriptor } in create_window_event_reader.iter(&create_window_events) {
let (window, handle) = winit_windows.create_window(event_loop, *id, descriptor);
create_window(&mut *windows, window, &mut *handles, handle);
window_created_events.send(WindowCreated { id: *id });
}
}
22 changes: 15 additions & 7 deletions crates/bevy_winit/src/winit_windows.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use bevy_utils::HashMap;
use bevy_window::{Window, WindowDescriptor, WindowId, WindowMode};
use raw_window_handle::{HasRawWindowHandle, TrustedWindowHandle};

#[derive(Debug, Default)]
pub struct WinitWindows {
Expand All @@ -14,7 +15,7 @@ impl WinitWindows {
event_loop: &winit::event_loop::EventLoopWindowTarget<()>,
window_id: WindowId,
window_descriptor: &WindowDescriptor,
) -> Window {
) -> (Window, TrustedWindowHandle) {
#[cfg(target_os = "windows")]
let mut winit_window_builder = {
use winit::platform::windows::WindowBuilderExtWindows;
Expand Down Expand Up @@ -112,14 +113,21 @@ impl WinitWindows {

let inner_size = winit_window.inner_size();
let scale_factor = winit_window.scale_factor();
// Safety: Winit returns a valid raw window handle
let handle = unsafe {
raw_window_handle::TrustedWindowHandle::new(winit_window.raw_window_handle())
};
self.windows.insert(winit_window.id(), winit_window);

Window::new(
window_id,
&window_descriptor,
inner_size.width,
inner_size.height,
scale_factor,
(
Window::new(
window_id,
&window_descriptor,
inner_size.width,
inner_size.height,
scale_factor,
),
handle,
)
}

Expand Down