Merge pull request #1385 from Noahnoah55/master

Upgrade to raw-window-handle 0.6
This commit is contained in:
Cobrand
2024-06-13 11:51:47 +02:00
committed by GitHub
4 changed files with 237 additions and 135 deletions

View File

@@ -31,12 +31,12 @@ optional = true
[dev-dependencies]
rand = "0.7"
wgpu = { version = "0.15", features = ["spirv"] }
wgpu = { version = "0.19", features = ["spirv"] }
pollster = "0.2.4"
env_logger = "0.9.0"
[dependencies.raw-window-handle]
version = "0.5.0"
version = "0.6.0"
optional = true
[features]

View File

@@ -27,9 +27,10 @@ fn main() -> Result<(), String> {
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
backends: wgpu::Backends::PRIMARY,
dx12_shader_compiler: Default::default(),
..Default::default()
});
let surface = unsafe {
match instance.create_surface(&window) {
match instance.create_surface_unsafe(wgpu::SurfaceTargetUnsafe::from_window(&window).unwrap()) {
Ok(s) => s,
Err(e) => return Err(e.to_string()),
}
@@ -46,9 +47,9 @@ fn main() -> Result<(), String> {
let (device, queue) = match pollster::block_on(adapter.request_device(
&wgpu::DeviceDescriptor {
limits: wgpu::Limits::default(),
required_limits: wgpu::Limits::default(),
label: Some("device"),
features: wgpu::Features::empty(),
required_features: wgpu::Features::empty(),
},
None,
)) {
@@ -117,7 +118,7 @@ fn main() -> Result<(), String> {
.formats
.iter()
.copied()
.find(|f| f.describe().srgb)
.find(|f| f.is_srgb())
.unwrap_or(surface_caps.formats[0]);
let mut config = wgpu::SurfaceConfiguration {
@@ -128,6 +129,7 @@ fn main() -> Result<(), String> {
present_mode: wgpu::PresentMode::Fifo,
alpha_mode: wgpu::CompositeAlphaMode::Auto,
view_formats: Vec::default(),
desired_maximum_frame_latency: 2,
};
surface.configure(&device, &config);
@@ -166,7 +168,8 @@ fn main() -> Result<(), String> {
SurfaceError::Lost => "Lost",
SurfaceError::OutOfMemory => "OutOfMemory",
};
panic!("Failed to get current surface texture! Reason: {}", reason)
println!("Failed to get current surface texture! Reason: {}", reason);
continue 'running;
}
};
@@ -184,11 +187,13 @@ fn main() -> Result<(), String> {
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(wgpu::Color::GREEN),
store: true,
store: wgpu::StoreOp::Store,
},
})],
depth_stencil_attachment: None,
label: None,
timestamp_writes: None,
occlusion_query_set: None,
});
rpass.set_pipeline(&render_pipeline);
rpass.set_bind_group(0, &bind_group, &[]);

View File

@@ -1,22 +1,23 @@
extern crate raw_window_handle;
use self::raw_window_handle::{
HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle,
RawDisplayHandle, RawWindowHandle,
HasWindowHandle, HasDisplayHandle, DisplayHandle, WindowHandle, HandleError
};
use crate::{sys::SDL_Window, video::Window};
unsafe impl HasRawWindowHandle for Window {
#[doc(alias = "SDL_GetVersion")]
fn raw_window_handle(&self) -> RawWindowHandle {
impl HasWindowHandle for Window {
fn window_handle(&self) -> Result<WindowHandle<'_>, HandleError> {
use self::SDL_SYSWM_TYPE::*;
// Check if running on web before continuing,
// since SDL_GetWindowWMInfo will fail on emscripten
if cfg!(target_os = "emscripten") {
use self::raw_window_handle::WebWindowHandle;
let mut handle = WebWindowHandle::empty();
handle.id = 1;
return RawWindowHandle::Web(handle);
let handle = WebWindowHandle::new(1);
let handle = RawWindowHandle::Web(handle);
let handle = unsafe{WindowHandle::borrow_raw(handle)};
return Ok(handle);
}
let mut wm_info: SDL_SysWMinfo = unsafe { std::mem::zeroed() };
@@ -35,20 +36,40 @@ unsafe impl HasRawWindowHandle for Window {
SDL_SYSWM_WINDOWS => {
use self::raw_window_handle::Win32WindowHandle;
let mut handle = Win32WindowHandle::empty();
handle.hwnd = unsafe { wm_info.info.win }.window as *mut libc::c_void;
handle.hinstance = unsafe { wm_info.info.win }.hinstance as *mut libc::c_void;
let hwnd = unsafe { wm_info.info.win }.window as *mut isize;
let hwnd = core::num::NonZeroIsize::new(hwnd as isize);
let hwnd = match hwnd {
Some(hwnd) => hwnd,
None => {
return Err(HandleError::Unavailable);
}
};
let mut handle = Win32WindowHandle::new(hwnd);
let hinstance = unsafe { wm_info.info.win }.hinstance as *mut libc::c_void;
let hinstance = core::num::NonZeroIsize::new(hinstance as isize);
handle.hinstance = hinstance;
RawWindowHandle::Win32(handle)
let handle = RawWindowHandle::Win32(handle);
let handle = unsafe {WindowHandle::borrow_raw(handle)};
Ok(handle)
}
#[cfg(target_os = "windows")]
SDL_SYSWM_WINRT => {
use self::raw_window_handle::WinRtWindowHandle;
let mut handle = WinRtWindowHandle::empty();
handle.core_window = unsafe { wm_info.info.winrt }.core_window;
let core_window = unsafe { wm_info.info.winrt }.core_window;
let core_window = core::ptr::NonNull::<libc::c_void>::new(core_window);
let core_window = match core_window {
Some(cw) => cw,
None => {
return Err(HandleError::Unavailable);
}
};
let handle = WinRtWindowHandle::new(core_window);
let handle = RawWindowHandle::WinRt(handle);
let handle = unsafe {WindowHandle::borrow_raw(handle)};
RawWindowHandle::WinRt(handle)
Ok(handle)
}
#[cfg(any(
target_os = "linux",
@@ -60,10 +81,21 @@ unsafe impl HasRawWindowHandle for Window {
SDL_SYSWM_WAYLAND => {
use self::raw_window_handle::WaylandWindowHandle;
let mut handle = WaylandWindowHandle::empty();
handle.surface = unsafe { wm_info.info.wl }.surface as *mut libc::c_void;
let surf = unsafe {wm_info.info.wl}.surface as *mut libc::c_void;
let surf = core::ptr::NonNull::<libc::c_void>::new(surf);
match surf {
Some(surf) => {
let handle = WaylandWindowHandle::new(surf);
let handle = RawWindowHandle::Wayland(handle);
let handle = unsafe {WindowHandle::borrow_raw(handle)};
Ok(handle)
}
None => {
Err(HandleError::Unavailable)
}
}
RawWindowHandle::Wayland(handle)
}
#[cfg(any(
target_os = "linux",
@@ -75,44 +107,69 @@ unsafe impl HasRawWindowHandle for Window {
SDL_SYSWM_X11 => {
use self::raw_window_handle::XlibWindowHandle;
let mut handle = XlibWindowHandle::empty();
handle.window = unsafe { wm_info.info.x11 }.window;
let window = unsafe { wm_info.info.x11 }.window;
let xlib_handle = XlibWindowHandle::new(window);
let raw_handle = RawWindowHandle::Xlib(xlib_handle);
let handle = unsafe{WindowHandle::borrow_raw(raw_handle)};
RawWindowHandle::Xlib(handle)
Ok(handle)
}
#[cfg(target_os = "macos")]
SDL_SYSWM_COCOA => {
use self::raw_window_handle::AppKitWindowHandle;
let mut handle = AppKitWindowHandle::empty();
handle.ns_window = unsafe { wm_info.info.cocoa }.window as *mut libc::c_void;
handle.ns_view = if self.context().metal_view.is_null() {
panic!("metal_view not initialized, please call WindowBuilder::metal_view() when building the window");
} else {
self.context().metal_view
let ns_view = core::ptr::NonNull::<libc::c_void>::new(self.context().metal_view);
let ns_view = match ns_view {
Some(nv) => nv,
None => {
panic!("metal_view not initialized, please call WindowBuilder::metal_view() when building the window");
}
};
let handle = AppKitWindowHandle::new(ns_view);
let handle = RawWindowHandle::AppKit(handle);
let handle = unsafe {WindowHandle::borrow_raw(handle)};
RawWindowHandle::AppKit(handle)
Ok(handle)
}
#[cfg(any(target_os = "ios"))]
SDL_SYSWM_UIKIT => {
use self::raw_window_handle::UiKitWindowHandle;
let mut handle = UiKitHandle::empty();
handle.ui_window = unsafe { wm_info.info.uikit }.window as *mut libc::c_void;
handle.ui_view = 0 as *mut libc::c_void; // consumer of RawWindowHandle should determine this
let ui_window = unsafe { wm_info.info.uikit }.window as *mut libc::c_void;
let ui_window = core::ptr::NonNull::<libc::c_void>::new(ui_window);
let ui_window = match ui_window {
Some(uiw) => uiw,
None => {
return Err(HandleError::Unavailable);
}
};
RawWindowHandle::UiKit(handle)
// https://developer.apple.com/documentation/uikit/uiwindow
// If this doesn't work then the actual fix is a lot more involved
// Someone with an IOS device please test
let handle = UiKitWindowHandle::new(ui_window);
let handle = RawWindowHandle::UiKit(handle);
let handle = unsafe {WindowHandle::borrow_raw(handle)};
Ok(handle)
}
#[cfg(any(target_os = "android"))]
SDL_SYSWM_ANDROID => {
use self::raw_window_handle::AndroidNdkWindowHandle;
let mut handle = AndroidNdkWindowHandle::empty();
handle.a_native_window =
let a_native_window =
unsafe { wm_info.info.android }.window as *mut libc::c_void;
RawWindowHandle::AndroidNdk(handle)
let a_native_window = core::ptr::NonNull::<libc::c_void>::new(a_native_window);
let a_native_window = match a_native_window {
Some(anw) => anw,
None => {
return Err(HandleError::Unavailable);
}
};
let handle = AndroidNdkWindowHandle::new(a_native_window);
let handle = RawWindowHandle::AndroidNdk(handle);
let handle = unsafe{WindowHandle::borrow_raw(handle)};
Ok(handle)
}
x => {
let window_system = match x {
@@ -127,17 +184,19 @@ unsafe impl HasRawWindowHandle for Window {
}
}
unsafe impl HasRawDisplayHandle for Window {
impl HasDisplayHandle for Window {
#[doc(alias = "SDL_GetVersion")]
fn raw_display_handle(&self) -> RawDisplayHandle {
fn display_handle(&self) -> Result<DisplayHandle, HandleError> {
use self::SDL_SYSWM_TYPE::*;
// Check if running on web before continuing,
// since SDL_GetWindowWMInfo will fail on emscripten
if cfg!(target_os = "emscripten") {
use self::raw_window_handle::WebDisplayHandle;
let handle = WebDisplayHandle::empty();
return RawDisplayHandle::Web(handle);
let handle = WebDisplayHandle::new();
let handle = RawDisplayHandle::Web(handle);
let handle = unsafe{DisplayHandle::borrow_raw(handle)};
return Ok(handle);
}
let mut wm_info: SDL_SysWMinfo = unsafe { std::mem::zeroed() };
@@ -156,9 +215,11 @@ unsafe impl HasRawDisplayHandle for Window {
SDL_SYSWM_WINDOWS | SDL_SYSWM_WINRT => {
use self::raw_window_handle::WindowsDisplayHandle;
let handle = WindowsDisplayHandle::empty();
let handle = WindowsDisplayHandle::new();
let handle = RawDisplayHandle::Windows(handle);
let handle = unsafe {DisplayHandle::borrow_raw(handle)};
RawDisplayHandle::Windows(handle)
Ok(handle)
}
#[cfg(any(
target_os = "linux",
@@ -170,10 +231,19 @@ unsafe impl HasRawDisplayHandle for Window {
SDL_SYSWM_WAYLAND => {
use self::raw_window_handle::WaylandDisplayHandle;
let mut handle = WaylandDisplayHandle::empty();
handle.display = unsafe { wm_info.info.wl }.display as *mut libc::c_void;
RawDisplayHandle::Wayland(handle)
let display = unsafe { wm_info.info.wl }.display as *mut libc::c_void;
let display = core::ptr::NonNull::<libc::c_void>::new(display);
match display {
Some(display) => {
let mut handle = WaylandDisplayHandle::new(display);
let handle = RawDisplayHandle::Wayland(handle);
let handle = unsafe{DisplayHandle::borrow_raw(handle)};
Ok(handle)
}
None => {
Err(HandleError::Unavailable)
}
}
}
#[cfg(any(
target_os = "linux",
@@ -185,32 +255,42 @@ unsafe impl HasRawDisplayHandle for Window {
SDL_SYSWM_X11 => {
use self::raw_window_handle::XlibDisplayHandle;
let mut handle = XlibDisplayHandle::empty();
handle.display = unsafe { wm_info.info.x11 }.display as *mut libc::c_void;
let display = unsafe { wm_info.info.x11 }.display as *mut libc::c_void;
let display = core::ptr::NonNull::<libc::c_void>::new(display);
let window = unsafe { wm_info.info.x11 }.window as i32;
let handle = XlibDisplayHandle::new(display, window);
let handle = RawDisplayHandle::Xlib(handle);
let handle = unsafe {DisplayHandle::borrow_raw(handle)};
RawDisplayHandle::Xlib(handle)
Ok(handle)
}
#[cfg(target_os = "macos")]
SDL_SYSWM_COCOA => {
use self::raw_window_handle::AppKitDisplayHandle;
let handle = AppKitDisplayHandle::empty();
RawDisplayHandle::AppKit(handle)
let handle = AppKitDisplayHandle::new();
let handle = RawDisplayHandle::AppKit(handle);
let handle = unsafe {DisplayHandle::borrow_raw(handle)};
Ok(handle)
}
#[cfg(any(target_os = "ios"))]
SDL_SYSWM_UIKIT => {
use self::raw_window_handle::UiKitDisplayHandle;
let handle = UiKitDisplayHandle::empty();
let handle = UiKitDisplayHandle::new();
let handle = RawDisplayHandle::UiKit(handle);
let handle = unsafe {DisplayHandle::borrow_raw(handle)};
RawDisplayHandle::UiKit(handle)
Ok(handle)
}
#[cfg(any(target_os = "android"))]
SDL_SYSWM_ANDROID => {
use self::raw_window_handle::AndroidDisplayHandle;
let handle = AndroidDisplayHandle::empty();
let handle = AndroidDisplayHandle::new();
let handle = RawDisplayHandle::Android(handle);
let handle = unsafe {DisplayHandle::borrow_raw(handle)};
RawDisplayHandle::Android(handle)
Ok(handle)
}
x => {
let window_system = match x {

View File

@@ -4,7 +4,7 @@ mod raw_window_handle_test {
extern crate sdl2;
use self::raw_window_handle::{
HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle,
HasDisplayHandle, HasWindowHandle, RawDisplayHandle, RawWindowHandle,
};
use self::sdl2::video::Window;
@@ -12,24 +12,38 @@ mod raw_window_handle_test {
#[test]
fn get_windows_handle() {
let window = new_hidden_window();
match window.raw_window_handle() {
RawWindowHandle::Win32(windows_handle) => {
assert_ne!(windows_handle.hwnd, 0 as *mut libc::c_void);
println!("Successfully received Windows RawWindowHandle!");
match window.window_handle() {
Ok(window_handle) => {
match window_handle.as_raw() {
RawWindowHandle::Win32(_) => {
println!("Successfully received Win32 window handle")
},
RawWindowHandle::WinRt(_) => {
println!("Successfully received WinRt window handle")
}
raw_handle => {
assert!(false, "Wrong window handle type for Windows: {:?}", raw_handle)
}
}
},
Err(e) => {
assert!(false, "Failed to recieve window handle on Windows: {:?}", e)
}
x => assert!(
false,
"Received wrong RawWindowHandle type for Windows: {:?}",
x
),
}
match window.raw_display_handle() {
RawDisplayHandle::Windows(_) => {}
x => assert!(
false,
"Received wrong RawDisplayHandle type for Windows: {:?}",
x
),
match window.display_handle() {
Ok(display_handle) => {
match display_handle.as_raw() {
RawDisplayHandle::Windows(_) => {
println!("Successfully received Windows display handle")
},
raw_handle => {
assert!(false, "Wrong display handle type for Windows: {:?}", raw_handle)
}
}
},
Err(e) => {
assert!(false, "Failed to recieve display handle on Windows: {:?}", e)
}
}
}
@@ -43,42 +57,41 @@ mod raw_window_handle_test {
#[test]
fn get_linux_handle() {
let window = new_hidden_window();
match window.raw_window_handle() {
RawWindowHandle::Xlib(x11_handle) => {
assert_ne!(x11_handle.window, 0, "Window for X11 should not be 0");
println!("Successfully received linux X11 RawWindowHandle!");
match window.window_handle() {
Ok(handle) => {
match handle.as_raw() {
RawWindowHandle::Xlib(_) => {
println!("Successfully received X11 window handle")
}
RawWindowHandle::Wayland(_) => {
println!("Successfully received Wayland window handle")
}
raw_handle => {
assert!(false, "Wrong window handle type for Linux: {:?}", raw_handle)
}
}
},
Err(e) => {
assert!(false, "Failed to recieve window handle on Linux: {:?}", e)
}
RawWindowHandle::Wayland(wayland_handle) => {
assert_ne!(
wayland_handle.surface, 0 as *mut libc::c_void,
"Surface for Wayland should not be null"
);
println!("Successfully received linux Wayland RawWindowHandle!");
}
x => assert!(
false,
"Received wrong RawWindowHandle type for linux: {:?}",
x
),
}
match window.raw_display_handle() {
RawDisplayHandle::Xlib(x11_display) => {
assert_ne!(
x11_display.display, 0 as *mut libc::c_void,
"Display for X11 should not be null"
);
match window.display_handle() {
Ok(handle) => {
match handle.as_raw() {
RawDisplayHandle::Xlib(_) => {
println!("Successfully recieved X11 display handle")
}
RawDisplayHandle::Wayland(_) => {
println!("Successfully recieved Wayland display handle")
}
raw_handle => {
assert!(false, "Wrong display handle type for Linux: {:?}", raw_handle)
}
}
}
RawDisplayHandle::Wayland(wayland_display) => {
assert_ne!(
wayland_display.display, 0 as *mut libc::c_void,
"Display for Wayland should not be null"
);
}
x => assert!(
false,
"Received wrong RawDisplayHandle type for linux: {:?}",
x
),
Err(e) => {
assert!(false, "Failed to recieve display handle on Linux: {:?}", e)
},
}
}
@@ -86,31 +99,35 @@ mod raw_window_handle_test {
#[test]
fn get_macos_handle() {
let window = new_hidden_window();
match window.raw_window_handle() {
RawWindowHandle::AppKit(macos_handle) => {
assert_ne!(
macos_handle.ns_window, 0 as *mut libc::c_void,
"ns_window should not be null"
);
assert_ne!(
macos_handle.ns_view, 0 as *mut libc::c_void,
"nw_view should not be null"
);
println!("Successfully received macOS RawWindowHandle!");
match window.window_handle() {
Ok(handle) => {
match handle.as_raw() {
RawWindowHandle::AppKit(_) => {
println!("Successfully recieved AppKit window handle")
}
raw_handle => {
assert!(false, "Wrong window handle type for macOS: {:?}", raw_handle)
}
}
}
Err(e) => {
assert!(false, "Failed to recieve window handle on macOS: {:?}", e)
}
x => assert!(
false,
"Received wrong RawWindowHandle type for macOS: {:?}",
x
),
};
match window.raw_display_handle() {
RawDisplayHandle::AppKit(_) => {}
x => assert!(
false,
"Received wrong RawDisplayHandle type for macOS: {:?}",
x
),
match window.display_handle() {
Ok(handle) => {
match handle.as_raw(){
RawDisplayHandle::AppKit(_) => {
println!("Successfully recieved AppKit display handle")
}
raw_handle => {
assert!(false, "Wrong display handle type for macOS: {:?}", raw_handle)
}
}
},
Err(e) => {
assert!(false, "Failed to recieve display handle on macOS: {:?}", e)
}
}
}