Skip to content

Commit

Permalink
Merge pull request #1385 from Noahnoah55/master
Browse files Browse the repository at this point in the history
Upgrade to raw-window-handle 0.6
  • Loading branch information
Cobrand authored Jun 13, 2024
2 parents 28063b7 + fd63cab commit 726613e
Show file tree
Hide file tree
Showing 4 changed files with 238 additions and 136 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
17 changes: 11 additions & 6 deletions examples/raw-window-handle-with-wgpu/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()),
}
Expand All @@ -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,
)) {
Expand Down Expand Up @@ -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 {
Expand All @@ -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);

Expand Down Expand Up @@ -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;
}
};

Expand All @@ -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, &[]);
Expand Down
190 changes: 135 additions & 55 deletions src/sdl2/raw_window_handle.rs
Original file line number Diff line number Diff line change
@@ -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() };
Expand All @@ -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;

RawWindowHandle::Win32(handle)
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;

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",
Expand All @@ -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",
Expand All @@ -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 {
Expand All @@ -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() };
Expand All @@ -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",
Expand All @@ -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",
Expand All @@ -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 {
Expand Down
Loading

0 comments on commit 726613e

Please sign in to comment.