From 716b294cb185938308850633989a1ae5cba04bf7 Mon Sep 17 00:00:00 2001 From: vitalyr Date: Sat, 8 Oct 2022 03:51:56 +0800 Subject: [PATCH] Update `wgpu` to 0.14.0, `winit` to 0.27.4, `raw-window-handle` to 0.5.0 --- crates/bevy_asset/Cargo.toml | 2 +- crates/bevy_internal/Cargo.toml | 2 +- crates/bevy_render/Cargo.toml | 2 +- crates/bevy_render/src/lib.rs | 2 +- crates/bevy_render/src/view/window.rs | 7 +-- crates/bevy_window/Cargo.toml | 3 +- crates/bevy_window/src/raw_window_handle.rs | 50 ++++++++++++------ crates/bevy_window/src/window.rs | 57 ++++++++++++--------- crates/bevy_winit/Cargo.toml | 7 ++- crates/bevy_winit/src/lib.rs | 13 ++++- crates/bevy_winit/src/winit_windows.rs | 35 ++++++++----- deny.toml | 2 +- 12 files changed, 115 insertions(+), 67 deletions(-) diff --git a/crates/bevy_asset/Cargo.toml b/crates/bevy_asset/Cargo.toml index bd6874d683f834..bc8602b21e9064 100644 --- a/crates/bevy_asset/Cargo.toml +++ b/crates/bevy_asset/Cargo.toml @@ -40,7 +40,7 @@ wasm-bindgen-futures = "0.4" js-sys = "0.3" [target.'cfg(target_os = "android")'.dependencies] -ndk-glue = { version = "0.5" } +ndk-glue = { version = "0.7" } [dev-dependencies] futures-lite = "1.4.0" diff --git a/crates/bevy_internal/Cargo.toml b/crates/bevy_internal/Cargo.toml index f38c60c203f9aa..f4648d1ef02297 100644 --- a/crates/bevy_internal/Cargo.toml +++ b/crates/bevy_internal/Cargo.toml @@ -100,4 +100,4 @@ bevy_gilrs = { path = "../bevy_gilrs", optional = true, version = "0.9.0-dev" } [target.'cfg(target_os = "android")'.dependencies] # This version *must* be the same as the version used by winit, # or Android will break: https://github.com/rust-windowing/winit#android -ndk-glue = {version = "0.5", features = ["logger"]} +ndk-glue = {version = "0.7", features = ["logger"]} diff --git a/crates/bevy_render/Cargo.toml b/crates/bevy_render/Cargo.toml index 9e7c676ac15642..c3508a590d1652 100644 --- a/crates/bevy_render/Cargo.toml +++ b/crates/bevy_render/Cargo.toml @@ -49,7 +49,7 @@ bevy_utils = { path = "../bevy_utils", version = "0.9.0-dev" } image = { version = "0.24", default-features = false } # misc -wgpu = { version = "0.13.1", features = ["spirv"] } +wgpu = { version = "0.14.0", features = ["spirv"] } codespan-reporting = "0.11.0" naga = { version = "0.9.0", features = ["glsl-in", "spv-in", "spv-out", "wgsl-in", "wgsl-out"] } serde = { version = "1", features = ["derive"] } diff --git a/crates/bevy_render/src/lib.rs b/crates/bevy_render/src/lib.rs index adf5a97c19a8d7..40b6616b11a28a 100644 --- a/crates/bevy_render/src/lib.rs +++ b/crates/bevy_render/src/lib.rs @@ -147,7 +147,7 @@ impl Plugin for RenderPlugin { let surface = { let windows = app.world.resource_mut::(); let raw_handle = windows.get_primary().map(|window| unsafe { - let handle = window.raw_window_handle().get_handle(); + let handle = window.raw_handle().get_handle(); instance.create_surface(&handle) }); raw_handle diff --git a/crates/bevy_render/src/view/window.rs b/crates/bevy_render/src/view/window.rs index 6fe1bc8627fdaf..d9792c1b1a0503 100644 --- a/crates/bevy_render/src/view/window.rs +++ b/crates/bevy_render/src/view/window.rs @@ -7,7 +7,7 @@ use crate::{ use bevy_app::{App, Plugin}; use bevy_ecs::prelude::*; use bevy_utils::{tracing::debug, HashMap, HashSet}; -use bevy_window::{PresentMode, RawWindowHandleWrapper, WindowClosed, WindowId, Windows}; +use bevy_window::{PresentMode, RawHandleWrapper, WindowClosed, WindowId, Windows}; use std::ops::{Deref, DerefMut}; use wgpu::TextureFormat; @@ -40,7 +40,7 @@ impl Plugin for WindowRenderPlugin { pub struct ExtractedWindow { pub id: WindowId, - pub handle: RawWindowHandleWrapper, + pub handle: RawHandleWrapper, pub physical_width: u32, pub physical_height: u32, pub present_mode: PresentMode, @@ -85,7 +85,7 @@ fn extract_windows( .entry(window.id()) .or_insert(ExtractedWindow { id: window.id(), - handle: window.raw_window_handle(), + handle: window.raw_handle(), physical_width: new_width, physical_height: new_height, present_mode: window.present_mode(), @@ -184,6 +184,7 @@ pub fn prepare_windows( PresentMode::AutoVsync => wgpu::PresentMode::AutoVsync, PresentMode::AutoNoVsync => wgpu::PresentMode::AutoNoVsync, }, + alpha_mode: wgpu::CompositeAlphaMode::Auto, }; // Do the initial surface configuration if it hasn't been configured yet. Or if size or diff --git a/crates/bevy_window/Cargo.toml b/crates/bevy_window/Cargo.toml index f1402447072de8..239bf9a9fab7e0 100644 --- a/crates/bevy_window/Cargo.toml +++ b/crates/bevy_window/Cargo.toml @@ -21,7 +21,8 @@ bevy_reflect = { path = "../bevy_reflect", version = "0.9.0-dev" } bevy_utils = { path = "../bevy_utils", version = "0.9.0-dev" } # Used for close_on_esc bevy_input = { path = "../bevy_input", version = "0.9.0-dev" } -raw-window-handle = "0.4.2" +raw-window-handle = "0.5.0" +winit = { git = "https://github.com/rust-windowing/winit", default-features = false } # other serde = { version = "1.0", features = ["derive"], optional = true } diff --git a/crates/bevy_window/src/raw_window_handle.rs b/crates/bevy_window/src/raw_window_handle.rs index 967b3c33016368..63a8c2fb17d580 100644 --- a/crates/bevy_window/src/raw_window_handle.rs +++ b/crates/bevy_window/src/raw_window_handle.rs @@ -1,4 +1,6 @@ -use raw_window_handle::{HasRawWindowHandle, RawWindowHandle}; +use raw_window_handle::{ + HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle, +}; /// A wrapper over [`RawWindowHandle`] that allows us to safely pass it across threads. /// @@ -6,13 +8,12 @@ use raw_window_handle::{HasRawWindowHandle, RawWindowHandle}; /// and so we cannot simply make it (or any type that has a safe operation to get a [`RawWindowHandle`]) /// thread-safe. #[derive(Debug, Clone)] -pub struct RawWindowHandleWrapper(RawWindowHandle); - -impl RawWindowHandleWrapper { - pub(crate) fn new(handle: RawWindowHandle) -> Self { - Self(handle) - } +pub struct RawHandleWrapper { + pub window_handle: RawWindowHandle, + pub display_handle: RawDisplayHandle, +} +impl RawHandleWrapper { /// Returns a [`HasRawWindowHandle`] impl, which exposes [`RawWindowHandle`]. /// /// # Safety @@ -20,7 +21,15 @@ impl RawWindowHandleWrapper { /// Some platforms have constraints on where/how this handle can be used. For example, some platforms don't support doing window /// operations off of the main thread. The caller must ensure the [`RawWindowHandle`] is only used in valid contexts. pub unsafe fn get_handle(&self) -> ThreadLockedRawWindowHandleWrapper { - ThreadLockedRawWindowHandleWrapper(self.0) + ThreadLockedRawWindowHandleWrapper(self.clone()) + } + + pub fn get_display_handle(&self) -> RawDisplayHandle { + self.display_handle + } + + pub fn get_window_handle(&self) -> RawWindowHandle { + self.window_handle } } @@ -29,17 +38,17 @@ impl RawWindowHandleWrapper { // support doing window operations off of the main thread). // A recommendation for this pattern (and more context) is available here: // https://github.com/rust-windowing/raw-window-handle/issues/59 -unsafe impl Send for RawWindowHandleWrapper {} -unsafe impl Sync for RawWindowHandleWrapper {} +unsafe impl Send for RawHandleWrapper {} +unsafe impl Sync for RawHandleWrapper {} -/// A [`RawWindowHandleWrapper`] that cannot be sent across threads. +/// A [`RawHandleWrapper`] that cannot be sent across threads. /// -/// This safely exposes a [`RawWindowHandle`], but care must be taken to ensure that the construction itself is correct. +/// This safely exposes a [`RawHandle`], but care must be taken to ensure that the construction itself is correct. /// -/// This can only be constructed via the [`RawWindowHandleWrapper::get_handle()`] method; +/// This can only be constructed via the [`RawHandleWrapper::get_handle()`] method; /// be sure to read the safety docs there about platform-specific limitations. /// In many cases, this should only be constructed on the main thread. -pub struct ThreadLockedRawWindowHandleWrapper(RawWindowHandle); +pub struct ThreadLockedRawWindowHandleWrapper(RawHandleWrapper); // SAFETY: the caller has validated that this is a valid context to get RawWindowHandle // as otherwise an instance of this type could not have been constructed @@ -49,6 +58,17 @@ pub struct ThreadLockedRawWindowHandleWrapper(RawWindowHandle); // and so exposing a safe method to get a `RawWindowHandle` directly would be UB. unsafe impl HasRawWindowHandle for ThreadLockedRawWindowHandleWrapper { fn raw_window_handle(&self) -> RawWindowHandle { - self.0 + self.0.get_window_handle() + } +} +// SAFETY: the caller has validated that this is a valid context to get RawDisplayHandle +// as otherwise an instance of this type could not have been constructed +// NOTE: we cannot simply impl HasRawDisplayHandle for RawWindowHandleWrapper, +// as the `raw_display_handle` method is safe. We cannot guarantee that all calls +// of this method are correct (as it may be off the main thread on an incompatible platform), +// and so exposing a safe method to get a `RawDisplayHandle` directly would be UB. +unsafe impl HasRawDisplayHandle for ThreadLockedRawWindowHandleWrapper { + fn raw_display_handle(&self) -> RawDisplayHandle { + self.0.get_display_handle() } } diff --git a/crates/bevy_window/src/window.rs b/crates/bevy_window/src/window.rs index 8ebf978efcfd6c..f53dc2247d1c88 100644 --- a/crates/bevy_window/src/window.rs +++ b/crates/bevy_window/src/window.rs @@ -2,7 +2,6 @@ use bevy_ecs::system::Resource; use bevy_math::{DVec2, IVec2, UVec2, Vec2}; use bevy_reflect::{FromReflect, Reflect}; use bevy_utils::{tracing::warn, Uuid}; -use raw_window_handle::RawWindowHandle; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Reflect, FromReflect)] #[reflect_value(PartialEq, Hash)] @@ -76,7 +75,7 @@ impl WindowId { use crate::CursorIcon; use std::fmt; -use crate::raw_window_handle::RawWindowHandleWrapper; +use crate::raw_window_handle::RawHandleWrapper; impl fmt::Display for WindowId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -204,9 +203,9 @@ pub struct Window { decorations: bool, cursor_icon: CursorIcon, cursor_visible: bool, - cursor_locked: bool, + cursor_grab_mode: CursorGrabMode, physical_cursor_position: Option, - raw_window_handle: RawWindowHandleWrapper, + raw_handle: RawHandleWrapper, focused: bool, mode: WindowMode, canvas: Option, @@ -253,8 +252,8 @@ pub enum WindowCommand { decorations: bool, }, /// Set whether or not the cursor's position is locked. - SetCursorLockMode { - locked: bool, + SetCursorGrabMode { + grab_mode: CursorGrabMode, }, /// Set the cursor's [`CursorIcon`]. SetCursorIcon { @@ -290,6 +289,18 @@ pub enum WindowCommand { Close, } +/// Defines if and how the cursor is grabbed. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] +pub enum CursorGrabMode { + /// The cursor can freely leave the window + None, + /// The cursor is confined to the window area. + Confined, + /// The cursor is locked inside the window area to a certain position. + Locked, +} + /// Defines the way a window is displayed. #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] @@ -315,7 +326,7 @@ impl Window { physical_height: u32, scale_factor: f64, position: Option, - raw_window_handle: RawWindowHandle, + raw_handle: RawHandleWrapper, ) -> Self { Window { id, @@ -332,10 +343,10 @@ impl Window { resizable: window_descriptor.resizable, decorations: window_descriptor.decorations, cursor_visible: window_descriptor.cursor_visible, - cursor_locked: window_descriptor.cursor_locked, + cursor_grab_mode: window_descriptor.cursor_grab_mode, cursor_icon: CursorIcon::Default, physical_cursor_position: None, - raw_window_handle: RawWindowHandleWrapper::new(raw_window_handle), + raw_handle, focused: true, mode: window_descriptor.mode, canvas: window_descriptor.canvas.clone(), @@ -592,28 +603,28 @@ impl Window { self.command_queue .push(WindowCommand::SetDecorations { decorations }); } - /// Get whether or not the cursor is locked. + /// Get whether or how the cursor is grabed. /// /// ## Platform-specific /// - /// - **`macOS`** doesn't support cursor lock, but most windowing plugins can emulate it. See [issue #4875](https://github.com/bevyengine/bevy/issues/4875#issuecomment-1153977546) for more information. + /// - **`macOS`** doesn't support cursor grabed, but most windowing plugins can emulate it. See [issue #4875](https://github.com/bevyengine/bevy/issues/4875#issuecomment-1153977546) for more information. /// - **`iOS/Android`** don't have cursors. #[inline] - pub fn cursor_locked(&self) -> bool { - self.cursor_locked + pub fn cursor_grab_mode(&self) -> CursorGrabMode { + self.cursor_grab_mode } - /// Set whether or not the cursor is locked. + /// Set whether and how the cursor is grabed. /// /// This doesn't hide the cursor. For that, use [`set_cursor_visibility`](Window::set_cursor_visibility) /// /// ## Platform-specific /// - /// - **`macOS`** doesn't support cursor lock, but most windowing plugins can emulate it. See [issue #4875](https://github.com/bevyengine/bevy/issues/4875#issuecomment-1153977546) for more information. + /// - **`macOS`** doesn't support cursor grabed, but most windowing plugins can emulate it. See [issue #4875](https://github.com/bevyengine/bevy/issues/4875#issuecomment-1153977546) for more information. /// - **`iOS/Android`** don't have cursors. - pub fn set_cursor_lock_mode(&mut self, lock_mode: bool) { - self.cursor_locked = lock_mode; + pub fn set_cursor_grab_mode(&mut self, grab_mode: CursorGrabMode) { + self.cursor_grab_mode = grab_mode; self.command_queue - .push(WindowCommand::SetCursorLockMode { locked: lock_mode }); + .push(WindowCommand::SetCursorGrabMode { grab_mode }); } /// Get whether or not the cursor is visible. /// @@ -720,8 +731,8 @@ impl Window { self.focused } /// Get the [`RawWindowHandleWrapper`] corresponding to this window - pub fn raw_window_handle(&self) -> RawWindowHandleWrapper { - self.raw_window_handle.clone() + pub fn raw_handle(&self) -> RawHandleWrapper { + self.raw_handle.clone() } /// The "html canvas" element selector. @@ -836,8 +847,8 @@ pub struct WindowDescriptor { pub decorations: bool, /// Sets whether the cursor is visible when the window has focus. pub cursor_visible: bool, - /// Sets whether the window locks the cursor inside its borders when the window has focus. - pub cursor_locked: bool, + /// Sets whether and how the window grabs the cursor. + pub cursor_grab_mode: CursorGrabMode, /// Sets the [`WindowMode`](crate::WindowMode). /// /// The monitor to go fullscreen on can be selected with the `monitor` field. @@ -882,7 +893,7 @@ impl Default for WindowDescriptor { present_mode: PresentMode::Fifo, resizable: true, decorations: true, - cursor_locked: false, + cursor_grab_mode: CursorGrabMode::None, cursor_visible: true, mode: WindowMode::Windowed, transparent: false, diff --git a/crates/bevy_winit/Cargo.toml b/crates/bevy_winit/Cargo.toml index 5c7014ecbfa8ab..d5b9673befc64d 100644 --- a/crates/bevy_winit/Cargo.toml +++ b/crates/bevy_winit/Cargo.toml @@ -22,12 +22,11 @@ bevy_window = { path = "../bevy_window", version = "0.9.0-dev" } bevy_utils = { path = "../bevy_utils", version = "0.9.0-dev" } # other -winit = { version = "0.26.0", default-features = false } -approx = { version = "0.5.0", default-features = false } -raw-window-handle = "0.4.2" +winit = { version = "0.27.4", default-features = false } +approx = { version = "0.5", default-features = false } +raw-window-handle = "0.5" [target.'cfg(target_arch = "wasm32")'.dependencies] -winit = { version = "0.26.0", default-features = false } wasm-bindgen = { version = "0.2" } web-sys = "0.3" crossbeam-channel = "0.5" diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index 66804c5a426b42..43ccac9359c199 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -137,10 +137,10 @@ fn change_window( let window = winit_windows.get_window(id).unwrap(); window.set_cursor_icon(converters::convert_cursor_icon(icon)); } - bevy_window::WindowCommand::SetCursorLockMode { locked } => { + bevy_window::WindowCommand::SetCursorGrabMode { grab_mode } => { let window = winit_windows.get_window(id).unwrap(); window - .set_cursor_grab(locked) + .set_cursor_grab(winit_grab_mode(grab_mode)) .unwrap_or_else(|e| error!("Unable to un/grab cursor: {}", e)); } bevy_window::WindowCommand::SetCursorVisibility { visible } => { @@ -727,3 +727,12 @@ fn handle_create_window_events( } } } + +/// Map `bevy_window::CursorGrabMode` to `winit::window::CursorGrabMode`. +fn winit_grab_mode(mode: bevy_window::CursorGrabMode) -> winit::window::CursorGrabMode { + match mode { + bevy_window::CursorGrabMode::None => winit::window::CursorGrabMode::None, + bevy_window::CursorGrabMode::Confined => winit::window::CursorGrabMode::Confined, + bevy_window::CursorGrabMode::Locked => winit::window::CursorGrabMode::Locked, + } +} diff --git a/crates/bevy_winit/src/winit_windows.rs b/crates/bevy_winit/src/winit_windows.rs index 4467574874c611..f7c6e3d2d4a4d8 100644 --- a/crates/bevy_winit/src/winit_windows.rs +++ b/crates/bevy_winit/src/winit_windows.rs @@ -1,11 +1,13 @@ use bevy_math::{DVec2, IVec2}; use bevy_utils::HashMap; -use bevy_window::{MonitorSelection, Window, WindowDescriptor, WindowId, WindowMode}; -use raw_window_handle::HasRawWindowHandle; -use winit::{ - dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize}, - window::Fullscreen, +use bevy_window::{ + MonitorSelection, RawHandleWrapper, Window, WindowDescriptor, WindowId, WindowMode, }; +use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle}; +use winit::dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize}; +use winit::window::Fullscreen; + +use crate::winit_grab_mode; #[derive(Debug, Default)] pub struct WinitWindows { @@ -158,11 +160,9 @@ impl WinitWindows { } } - if window_descriptor.cursor_locked { - match winit_window.set_cursor_grab(true) { - Ok(_) | Err(winit::error::ExternalError::NotSupported(_)) => {} - Err(err) => Err(err).unwrap(), - } + match winit_window.set_cursor_grab(winit_grab_mode(window_descriptor.cursor_grab_mode)) { + Ok(_) | Err(winit::error::ExternalError::NotSupported(_)) => {} + Err(err) => Err(err).unwrap(), } winit_window.set_cursor_visible(window_descriptor.cursor_visible); @@ -192,7 +192,10 @@ impl WinitWindows { .map(|position| IVec2::new(position.x, position.y)); let inner_size = winit_window.inner_size(); let scale_factor = winit_window.scale_factor(); - let raw_window_handle = winit_window.raw_window_handle(); + let raw_handle = RawHandleWrapper { + window_handle: winit_window.raw_window_handle(), + display_handle: winit_window.raw_display_handle(), + }; self.windows.insert(winit_window.id(), winit_window); Window::new( window_id, @@ -201,7 +204,7 @@ impl WinitWindows { inner_size.height, scale_factor, position, - raw_window_handle, + raw_handle, ) } @@ -241,7 +244,9 @@ pub fn get_fitting_videomode( match abs_diff(a.size().width, width).cmp(&abs_diff(b.size().width, width)) { Equal => { match abs_diff(a.size().height, height).cmp(&abs_diff(b.size().height, height)) { - Equal => b.refresh_rate().cmp(&a.refresh_rate()), + Equal => b + .refresh_rate_millihertz() + .cmp(&a.refresh_rate_millihertz()), default => default, } } @@ -258,7 +263,9 @@ pub fn get_best_videomode(monitor: &winit::monitor::MonitorHandle) -> winit::mon use std::cmp::Ordering::*; match b.size().width.cmp(&a.size().width) { Equal => match b.size().height.cmp(&a.size().height) { - Equal => b.refresh_rate().cmp(&a.refresh_rate()), + Equal => b + .refresh_rate_millihertz() + .cmp(&a.refresh_rate_millihertz()), default => default, }, default => default, diff --git a/deny.toml b/deny.toml index 31a26b8ee5e183..39ae64f1babb7e 100644 --- a/deny.toml +++ b/deny.toml @@ -46,7 +46,7 @@ skip = [ { name = "ndk-sys", version = "0.3" }, # from rodio v0.16.0 { name = "parking_lot", version = "0.11" }, # from winit v0.26.1 { name = "parking_lot_core", version = "0.8" }, # from winit v0.26.1 - { name = "raw-window-handle", version = "0.4" }, # from wgpu v0.13.0 + { name = "raw-window-handle", version = "0.5" }, # from wgpu v0.13.0 { name = "nix", version = "0.23.1" }, # from alsa v0.6.0 { name = "windows_aarch64_msvc", version = "0.36" }, # from notify v5.0.0 { name = "windows_i686_gnu", version = "0.36" }, # from notify v5.0.0