From 53f67a82414fa0429fe8f8bdc2098700f65aa4b6 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Wed, 24 Apr 2024 13:02:11 -0700 Subject: [PATCH] Update blade with transparency and exclusive fullscreen fixes (#10880) Release Notes: - N/A Picks up https://github.com/kvark/blade/pull/113 and a bunch of other fixes. Should prevent the exclusive full-screen on Vulkan - related to #9728 cc @kazatsuyu Note: this PR doesn't enable transparency, this is left to follow-up --- Cargo.lock | 29 ++++++----- Cargo.toml | 5 +- crates/gpui/Cargo.toml | 4 +- .../gpui/src/platform/blade/blade_renderer.rs | 49 +++++++++---------- .../gpui/src/platform/linux/wayland/window.rs | 36 ++++++-------- crates/gpui/src/platform/linux/x11/window.rs | 37 +++++--------- crates/gpui/src/platform/mac/window.rs | 27 +++++----- crates/gpui/src/platform/windows/window.rs | 46 +++++++++-------- 8 files changed, 104 insertions(+), 129 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f980ce11fc..34f4720b75 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -284,21 +284,21 @@ checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16" [[package]] name = "ash" -version = "0.37.3+1.3.251" +version = "0.38.0+1.3.281" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e9c3835d686b0a6084ab4234fcd1b07dbf6e4767dce60874b12356a25ecd4a" +checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f" dependencies = [ - "libloading 0.7.4", + "libloading 0.8.0", ] [[package]] name = "ash-window" -version = "0.12.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b912285a7c29f3a8f87ca6f55afc48768624e5e33ec17dbd2f2075903f5e35ab" +checksum = "52bca67b61cb81e5553babde81b8211f713cb6db79766f80168f3e5f40ea6c82" dependencies = [ "ash", - "raw-window-handle 0.5.2", + "raw-window-handle 0.6.0", "raw-window-metal", ] @@ -1479,7 +1479,7 @@ dependencies = [ [[package]] name = "blade-graphics" version = "0.4.0" -source = "git+https://github.com/kvark/blade?rev=810ec594358aafea29a4a3d8ab601d25292b2ce4#810ec594358aafea29a4a3d8ab601d25292b2ce4" +source = "git+https://github.com/kvark/blade?rev=e82eec97691c3acdb43494484be60d661edfebf3#e82eec97691c3acdb43494484be60d661edfebf3" dependencies = [ "ash", "ash-window", @@ -1500,7 +1500,7 @@ dependencies = [ "mint", "naga", "objc", - "raw-window-handle 0.5.2", + "raw-window-handle 0.6.0", "slab", "wasm-bindgen", "web-sys", @@ -1509,7 +1509,7 @@ dependencies = [ [[package]] name = "blade-macros" version = "0.2.1" -source = "git+https://github.com/kvark/blade?rev=810ec594358aafea29a4a3d8ab601d25292b2ce4#810ec594358aafea29a4a3d8ab601d25292b2ce4" +source = "git+https://github.com/kvark/blade?rev=e82eec97691c3acdb43494484be60d661edfebf3#e82eec97691c3acdb43494484be60d661edfebf3" dependencies = [ "proc-macro2", "quote", @@ -4486,9 +4486,9 @@ dependencies = [ [[package]] name = "gpu-alloc-ash" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2424bc9be88170e1a56e57c25d3d0e2dfdd22e8f328e892786aeb4da1415732" +checksum = "cbda7a18a29bc98c2e0de0435c347df935bf59489935d0cbd0b73f1679b6f79a" dependencies = [ "ash", "gpu-alloc-types", @@ -4555,7 +4555,6 @@ dependencies = [ "postage", "profiling", "rand 0.8.5", - "raw-window-handle 0.5.2", "raw-window-handle 0.6.0", "refineable", "resvg", @@ -7726,14 +7725,14 @@ checksum = "42a9830a0e1b9fb145ebb365b8bc4ccd75f290f98c0247deafbbe2c75cefb544" [[package]] name = "raw-window-metal" -version = "0.3.2" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac4ea493258d54c24cb46aa9345d099e58e2ea3f30dd63667fc54fc892f18e76" +checksum = "76e8caa82e31bb98fee12fa8f051c94a6aa36b07cddb03f0d4fc558988360ff1" dependencies = [ "cocoa", "core-graphics", "objc", - "raw-window-handle 0.5.2", + "raw-window-handle 0.6.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 7a883e4586..5e2c1b27c5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -249,9 +249,8 @@ async-recursion = "1.0.0" async-tar = "0.4.2" async-trait = "0.1" bitflags = "2.4.2" -blade-graphics = { git = "https://github.com/kvark/blade", rev = "810ec594358aafea29a4a3d8ab601d25292b2ce4" } -blade-macros = { git = "https://github.com/kvark/blade", rev = "810ec594358aafea29a4a3d8ab601d25292b2ce4" } -blade-rwh = { package = "raw-window-handle", version = "0.5" } +blade-graphics = { git = "https://github.com/kvark/blade", rev = "e82eec97691c3acdb43494484be60d661edfebf3" } +blade-macros = { git = "https://github.com/kvark/blade", rev = "e82eec97691c3acdb43494484be60d661edfebf3" } cap-std = "3.0" chrono = { version = "0.4", features = ["serde"] } clap = { version = "4.4", features = ["derive"] } diff --git a/crates/gpui/Cargo.toml b/crates/gpui/Cargo.toml index f49ab6e571..9198c99b7e 100644 --- a/crates/gpui/Cargo.toml +++ b/crates/gpui/Cargo.toml @@ -14,7 +14,7 @@ workspace = true default = [] test-support = ["backtrace", "collections/test-support", "util/test-support"] runtime_shaders = [] -macos-blade = ["blade-graphics", "blade-macros", "blade-rwh", "bytemuck"] +macos-blade = ["blade-graphics", "blade-macros", "bytemuck"] [lib] path = "src/gpui.rs" @@ -26,7 +26,6 @@ async-task = "4.7" backtrace = { version = "0.3", optional = true } blade-graphics = { workspace = true, optional = true } blade-macros = { workspace = true, optional = true } -blade-rwh = { workspace = true, optional = true } bytemuck = { version = "1", optional = true } collections.workspace = true ctor.workspace = true @@ -95,7 +94,6 @@ flume = "0.11" #TODO: use these on all platforms blade-graphics.workspace = true blade-macros.workspace = true -blade-rwh.workspace = true bytemuck = "1" cosmic-text = "0.11.2" copypasta = "0.10.1" diff --git a/crates/gpui/src/platform/blade/blade_renderer.rs b/crates/gpui/src/platform/blade/blade_renderer.rs index ae7dda2f92..56234058f5 100644 --- a/crates/gpui/src/platform/blade/blade_renderer.rs +++ b/crates/gpui/src/platform/blade/blade_renderer.rs @@ -12,7 +12,7 @@ use collections::HashMap; #[cfg(target_os = "macos")] use media::core_video::CVMetalTextureCache; #[cfg(target_os = "macos")] -use std::ffi::c_void; +use std::{ffi::c_void, ptr::NonNull}; use blade_graphics as gpu; use std::{mem, sync::Arc}; @@ -25,35 +25,32 @@ pub type Renderer = BladeRenderer; #[cfg(target_os = "macos")] pub unsafe fn new_renderer( _context: self::Context, - native_window: *mut c_void, + _native_window: *mut c_void, native_view: *mut c_void, bounds: crate::Size, ) -> Renderer { + use raw_window_handle as rwh; struct RawWindow { - window: *mut c_void, view: *mut c_void, } - unsafe impl blade_rwh::HasRawWindowHandle for RawWindow { - fn raw_window_handle(&self) -> blade_rwh::RawWindowHandle { - let mut wh = blade_rwh::AppKitWindowHandle::empty(); - wh.ns_window = self.window; - wh.ns_view = self.view; - wh.into() + impl rwh::HasWindowHandle for RawWindow { + fn window_handle(&self) -> Result { + let view = NonNull::new(self.view).unwrap(); + let handle = rwh::AppKitWindowHandle::new(view); + Ok(unsafe { rwh::WindowHandle::borrow_raw(handle.into()) }) } } - - unsafe impl blade_rwh::HasRawDisplayHandle for RawWindow { - fn raw_display_handle(&self) -> blade_rwh::RawDisplayHandle { - let dh = blade_rwh::AppKitDisplayHandle::empty(); - dh.into() + impl rwh::HasDisplayHandle for RawWindow { + fn display_handle(&self) -> Result { + let handle = rwh::AppKitDisplayHandle::new(); + Ok(unsafe { rwh::DisplayHandle::borrow_raw(handle.into()) }) } } let gpu = Arc::new( gpu::Context::init_windowed( &RawWindow { - window: native_window as *mut _, view: native_view as *mut _, }, gpu::ContextDesc { @@ -184,7 +181,7 @@ struct BladePipelines { } impl BladePipelines { - fn new(gpu: &gpu::Context, surface_format: gpu::TextureFormat) -> Self { + fn new(gpu: &gpu::Context, surface_info: gpu::SurfaceInfo) -> Self { use gpu::ShaderData as _; let shader = gpu.create_shader(gpu::ShaderDesc { @@ -216,7 +213,7 @@ impl BladePipelines { depth_stencil: None, fragment: shader.at("fs_quad"), color_targets: &[gpu::ColorTargetState { - format: surface_format, + format: surface_info.format, blend: Some(gpu::BlendState::ALPHA_BLENDING), write_mask: gpu::ColorWrites::default(), }], @@ -233,7 +230,7 @@ impl BladePipelines { depth_stencil: None, fragment: shader.at("fs_shadow"), color_targets: &[gpu::ColorTargetState { - format: surface_format, + format: surface_info.format, blend: Some(gpu::BlendState::ALPHA_BLENDING), write_mask: gpu::ColorWrites::default(), }], @@ -267,7 +264,7 @@ impl BladePipelines { depth_stencil: None, fragment: shader.at("fs_path"), color_targets: &[gpu::ColorTargetState { - format: surface_format, + format: surface_info.format, blend: Some(gpu::BlendState::ALPHA_BLENDING), write_mask: gpu::ColorWrites::default(), }], @@ -284,7 +281,7 @@ impl BladePipelines { depth_stencil: None, fragment: shader.at("fs_underline"), color_targets: &[gpu::ColorTargetState { - format: surface_format, + format: surface_info.format, blend: Some(gpu::BlendState::ALPHA_BLENDING), write_mask: gpu::ColorWrites::default(), }], @@ -301,7 +298,7 @@ impl BladePipelines { depth_stencil: None, fragment: shader.at("fs_mono_sprite"), color_targets: &[gpu::ColorTargetState { - format: surface_format, + format: surface_info.format, blend: Some(gpu::BlendState::ALPHA_BLENDING), write_mask: gpu::ColorWrites::default(), }], @@ -318,7 +315,7 @@ impl BladePipelines { depth_stencil: None, fragment: shader.at("fs_poly_sprite"), color_targets: &[gpu::ColorTargetState { - format: surface_format, + format: surface_info.format, blend: Some(gpu::BlendState::ALPHA_BLENDING), write_mask: gpu::ColorWrites::default(), }], @@ -335,7 +332,7 @@ impl BladePipelines { depth_stencil: None, fragment: shader.at("fs_surface"), color_targets: &[gpu::ColorTargetState { - format: surface_format, + format: surface_info.format, blend: Some(gpu::BlendState::ALPHA_BLENDING), write_mask: gpu::ColorWrites::default(), }], @@ -367,16 +364,18 @@ impl BladeRenderer { //Note: this matches the original logic of the Metal backend, // but ultimaterly we need to switch to `Linear`. color_space: gpu::ColorSpace::Srgb, + allow_exclusive_full_screen: false, + transparent: false, } } pub fn new(gpu: Arc, size: gpu::Extent) -> Self { - let surface_format = gpu.resize(Self::make_surface_config(size)); + let surface_info = gpu.resize(Self::make_surface_config(size)); let command_encoder = gpu.create_command_encoder(gpu::CommandEncoderDesc { name: "main", buffer_count: 2, }); - let pipelines = BladePipelines::new(&gpu, surface_format); + let pipelines = BladePipelines::new(&gpu, surface_info); let instance_belt = BladeBelt::new(BladeBeltDescriptor { memory: gpu::Memory::Shared, min_chunk_size: 0x1000, diff --git a/crates/gpui/src/platform/linux/wayland/window.rs b/crates/gpui/src/platform/linux/wayland/window.rs index 56f2b876b8..2b1b8d1c7f 100644 --- a/crates/gpui/src/platform/linux/wayland/window.rs +++ b/crates/gpui/src/platform/linux/wayland/window.rs @@ -2,16 +2,14 @@ use std::any::Any; use std::cell::{Ref, RefCell, RefMut}; use std::ffi::c_void; use std::num::NonZeroU32; +use std::ptr::NonNull; use std::rc::{Rc, Weak}; use std::sync::Arc; use blade_graphics as gpu; -use blade_rwh::{HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle}; use collections::{HashMap, HashSet}; use futures::channel::oneshot::Receiver; -use raw_window_handle::{ - DisplayHandle, HandleError, HasDisplayHandle, HasWindowHandle, WindowHandle, -}; +use raw_window_handle as rwh; use wayland_backend::client::ObjectId; use wayland_client::WEnum; use wayland_client::{protocol::wl_surface, Proxy}; @@ -49,19 +47,18 @@ struct RawWindow { display: *mut c_void, } -unsafe impl HasRawWindowHandle for RawWindow { - fn raw_window_handle(&self) -> RawWindowHandle { - let mut wh = blade_rwh::WaylandWindowHandle::empty(); - wh.surface = self.window; - wh.into() +impl rwh::HasWindowHandle for RawWindow { + fn window_handle(&self) -> Result, rwh::HandleError> { + let window = NonNull::new(self.window).unwrap(); + let handle = rwh::WaylandWindowHandle::new(window); + Ok(unsafe { rwh::WindowHandle::borrow_raw(handle.into()) }) } } - -unsafe impl HasRawDisplayHandle for RawWindow { - fn raw_display_handle(&self) -> RawDisplayHandle { - let mut dh = blade_rwh::WaylandDisplayHandle::empty(); - dh.display = self.display; - dh.into() +impl rwh::HasDisplayHandle for RawWindow { + fn display_handle(&self) -> Result, rwh::HandleError> { + let display = NonNull::new(self.display).unwrap(); + let handle = rwh::WaylandDisplayHandle::new(display); + Ok(unsafe { rwh::DisplayHandle::borrow_raw(handle.into()) }) } } @@ -520,14 +517,13 @@ impl WaylandWindowStatePtr { } } -impl HasWindowHandle for WaylandWindow { - fn window_handle(&self) -> Result, HandleError> { +impl rwh::HasWindowHandle for WaylandWindow { + fn window_handle(&self) -> Result, rwh::HandleError> { unimplemented!() } } - -impl HasDisplayHandle for WaylandWindow { - fn display_handle(&self) -> Result, HandleError> { +impl rwh::HasDisplayHandle for WaylandWindow { + fn display_handle(&self) -> Result, rwh::HandleError> { unimplemented!() } } diff --git a/crates/gpui/src/platform/linux/x11/window.rs b/crates/gpui/src/platform/linux/x11/window.rs index 884011a376..a1d8532f71 100644 --- a/crates/gpui/src/platform/linux/x11/window.rs +++ b/crates/gpui/src/platform/linux/x11/window.rs @@ -77,8 +77,8 @@ pub struct Callbacks { } pub(crate) struct X11WindowState { - raw: RawWindow, atoms: XcbAtoms, + raw: RawWindow, bounds: Bounds, scale_factor: f32, renderer: BladeRenderer, @@ -96,40 +96,29 @@ pub(crate) struct X11Window { } // todo(linux): Remove other RawWindowHandle implementation -unsafe impl blade_rwh::HasRawWindowHandle for RawWindow { - fn raw_window_handle(&self) -> blade_rwh::RawWindowHandle { - let mut wh = blade_rwh::XcbWindowHandle::empty(); - wh.window = self.window_id; - wh.visual_id = self.visual_id; - wh.into() +impl rwh::HasWindowHandle for RawWindow { + fn window_handle(&self) -> Result { + let non_zero = NonZeroU32::new(self.window_id).unwrap(); + let handle = rwh::XcbWindowHandle::new(non_zero); + Ok(unsafe { rwh::WindowHandle::borrow_raw(handle.into()) }) } } -unsafe impl blade_rwh::HasRawDisplayHandle for RawWindow { - fn raw_display_handle(&self) -> blade_rwh::RawDisplayHandle { - let mut dh = blade_rwh::XcbDisplayHandle::empty(); - dh.connection = self.connection; - dh.screen = self.screen_id as i32; - dh.into() +impl rwh::HasDisplayHandle for RawWindow { + fn display_handle(&self) -> Result { + let non_zero = NonNull::new(self.connection).unwrap(); + let handle = rwh::XcbDisplayHandle::new(Some(non_zero), self.screen_id as i32); + Ok(unsafe { rwh::DisplayHandle::borrow_raw(handle.into()) }) } } impl rwh::HasWindowHandle for X11Window { fn window_handle(&self) -> Result { - Ok(unsafe { - let non_zero = NonZeroU32::new(self.state.borrow().raw.window_id).unwrap(); - let handle = rwh::XcbWindowHandle::new(non_zero); - rwh::WindowHandle::borrow_raw(handle.into()) - }) + unimplemented!() } } impl rwh::HasDisplayHandle for X11Window { fn display_handle(&self) -> Result { - Ok(unsafe { - let this = self.state.borrow(); - let non_zero = NonNull::new(this.raw.connection).unwrap(); - let handle = rwh::XcbDisplayHandle::new(Some(non_zero), this.raw.screen_id as i32); - rwh::DisplayHandle::borrow_raw(handle.into()) - }) + unimplemented!() } } diff --git a/crates/gpui/src/platform/mac/window.rs b/crates/gpui/src/platform/mac/window.rs index bcabaa786f..0780d89e7b 100644 --- a/crates/gpui/src/platform/mac/window.rs +++ b/crates/gpui/src/platform/mac/window.rs @@ -31,10 +31,7 @@ use objc::{ sel, sel_impl, }; use parking_lot::Mutex; -use raw_window_handle::{ - AppKitDisplayHandle, AppKitWindowHandle, DisplayHandle, HasDisplayHandle, HasWindowHandle, - RawWindowHandle, WindowHandle, -}; +use raw_window_handle as rwh; use smallvec::SmallVec; use std::{ any::Any, @@ -1141,25 +1138,25 @@ impl PlatformWindow for MacWindow { } } -impl HasWindowHandle for MacWindow { - fn window_handle( - &self, - ) -> Result, raw_window_handle::HandleError> { +impl rwh::HasWindowHandle for MacWindow { + fn window_handle(&self) -> Result, rwh::HandleError> { // SAFETY: The AppKitWindowHandle is a wrapper around a pointer to an NSView unsafe { - Ok(WindowHandle::borrow_raw(RawWindowHandle::AppKit( - AppKitWindowHandle::new(self.0.lock().native_view.cast()), + Ok(rwh::WindowHandle::borrow_raw(rwh::RawWindowHandle::AppKit( + rwh::AppKitWindowHandle::new(self.0.lock().native_view.cast()), ))) } } } -impl HasDisplayHandle for MacWindow { - fn display_handle( - &self, - ) -> Result, raw_window_handle::HandleError> { +impl rwh::HasDisplayHandle for MacWindow { + fn display_handle(&self) -> Result, rwh::HandleError> { // SAFETY: This is a no-op on macOS - unsafe { Ok(DisplayHandle::borrow_raw(AppKitDisplayHandle::new().into())) } + unsafe { + Ok(rwh::DisplayHandle::borrow_raw( + rwh::AppKitDisplayHandle::new().into(), + )) + } } } diff --git a/crates/gpui/src/platform/windows/window.rs b/crates/gpui/src/platform/windows/window.rs index 77b80eed2e..301dab271f 100644 --- a/crates/gpui/src/platform/windows/window.rs +++ b/crates/gpui/src/platform/windows/window.rs @@ -3,7 +3,6 @@ use std::{ any::Any, cell::{Cell, RefCell}, - ffi::c_void, iter::once, num::NonZeroIsize, path::PathBuf, @@ -18,7 +17,7 @@ use anyhow::Context; use blade_graphics as gpu; use futures::channel::oneshot::{self, Receiver}; use itertools::Itertools; -use raw_window_handle::{HasDisplayHandle, HasWindowHandle}; +use raw_window_handle as rwh; use smallvec::SmallVec; use std::result::Result; use windows::{ @@ -77,20 +76,24 @@ impl WindowsWindowInner { let scale_factor = Cell::new(monitor_dpi / USER_DEFAULT_SCREEN_DPI as f32); let input_handler = Cell::new(None); struct RawWindow { - hwnd: *mut c_void, + hwnd: isize, } - unsafe impl blade_rwh::HasRawWindowHandle for RawWindow { - fn raw_window_handle(&self) -> blade_rwh::RawWindowHandle { - let mut handle = blade_rwh::Win32WindowHandle::empty(); - handle.hwnd = self.hwnd; - handle.into() + impl rwh::HasWindowHandle for RawWindow { + fn window_handle(&self) -> Result, rwh::HandleError> { + Ok(unsafe { + let hwnd = NonZeroIsize::new_unchecked(self.hwnd); + let handle = rwh::Win32WindowHandle::new(hwnd); + rwh::WindowHandle::borrow_raw(handle.into()) + }) } } - unsafe impl blade_rwh::HasRawDisplayHandle for RawWindow { - fn raw_display_handle(&self) -> blade_rwh::RawDisplayHandle { - blade_rwh::WindowsDisplayHandle::empty().into() + impl rwh::HasDisplayHandle for RawWindow { + fn display_handle(&self) -> Result, rwh::HandleError> { + let handle = rwh::WindowsDisplayHandle::new(); + Ok(unsafe { rwh::DisplayHandle::borrow_raw(handle.into()) }) } } + let raw = RawWindow { hwnd: hwnd.0 as _ }; let gpu = Arc::new( unsafe { @@ -1316,23 +1319,18 @@ impl WindowsWindow { } } -impl HasWindowHandle for WindowsWindow { - fn window_handle( - &self, - ) -> Result, raw_window_handle::HandleError> { - let raw = raw_window_handle::Win32WindowHandle::new(unsafe { - NonZeroIsize::new_unchecked(self.inner.hwnd.0) - }) - .into(); - Ok(unsafe { raw_window_handle::WindowHandle::borrow_raw(raw) }) +impl rwh::HasWindowHandle for WindowsWindow { + fn window_handle(&self) -> Result, rwh::HandleError> { + let raw = + rwh::Win32WindowHandle::new(unsafe { NonZeroIsize::new_unchecked(self.inner.hwnd.0) }) + .into(); + Ok(unsafe { rwh::WindowHandle::borrow_raw(raw) }) } } // todo(windows) -impl HasDisplayHandle for WindowsWindow { - fn display_handle( - &self, - ) -> Result, raw_window_handle::HandleError> { +impl rwh::HasDisplayHandle for WindowsWindow { + fn display_handle(&self) -> Result, rwh::HandleError> { unimplemented!() } }