1#[cfg(not(target_os = "ios"))]
11#[allow(unused_imports)]
12use raw_window_handle::{
13 HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle as RwhRawDisplayHandle,
14 RawWindowHandle as RwhRawWindowHandle,
15};
16
17#[cfg(target_os = "windows")]
18fn current_module_hinstance() -> Option<std::num::NonZeroIsize> {
19 unsafe extern "system" {
20 fn GetModuleHandleW(lpModuleName: *const u16) -> isize;
21 }
22 let hmodule = unsafe { GetModuleHandleW(std::ptr::null()) };
26 std::num::NonZeroIsize::new(hmodule)
27}
28
29#[must_use]
35pub fn editor_wgpu_backends() -> wgpu::Backends {
36 #[cfg(target_os = "windows")]
37 {
38 wgpu::Backends::DX12
39 }
40 #[cfg(target_os = "macos")]
41 {
42 wgpu::Backends::METAL
43 }
44 #[cfg(not(any(target_os = "windows", target_os = "macos")))]
45 {
46 wgpu::Backends::PRIMARY
47 }
48}
49
50#[must_use]
56pub fn editor_instance_descriptor() -> wgpu::InstanceDescriptor {
57 let mut desc = wgpu::InstanceDescriptor::new_without_display_handle();
58 desc.backends = editor_wgpu_backends();
59 desc.backend_options.dx12.shader_compiler = wgpu::Dx12Compiler::Fxc;
60 desc
61}
62
63#[cfg(not(target_os = "ios"))]
69#[must_use]
70pub unsafe fn create_wgpu_surface(
71 instance: &wgpu::Instance,
72 window: &baseview::Window,
73) -> Option<wgpu::Surface<'static>> {
74 unsafe {
75 let rwh = window.raw_window_handle();
76 let surface_target = match rwh {
77 #[cfg(target_os = "macos")]
78 RwhRawWindowHandle::AppKit(handle) => {
79 let ns_view = handle.ns_view;
80 if ns_view.is_null() {
81 return None;
82 }
83 let rwh6_window = wgpu::rwh::RawWindowHandle::AppKit(
84 wgpu::rwh::AppKitWindowHandle::new(std::ptr::NonNull::new(ns_view)?),
85 );
86 let rwh6_display =
87 wgpu::rwh::RawDisplayHandle::AppKit(wgpu::rwh::AppKitDisplayHandle::new());
88 wgpu::SurfaceTargetUnsafe::RawHandle {
89 raw_display_handle: Some(rwh6_display),
90 raw_window_handle: rwh6_window,
91 }
92 }
93 #[cfg(target_os = "windows")]
94 RwhRawWindowHandle::Win32(handle) => {
95 let hwnd = handle.hwnd;
96 if hwnd.is_null() {
97 return None;
98 }
99 let mut win32 =
100 wgpu::rwh::Win32WindowHandle::new(std::num::NonZeroIsize::new(hwnd as isize)?);
101 win32.hinstance = current_module_hinstance();
106 let rwh6_window = wgpu::rwh::RawWindowHandle::Win32(win32);
107 let rwh6_display =
108 wgpu::rwh::RawDisplayHandle::Windows(wgpu::rwh::WindowsDisplayHandle::new());
109 wgpu::SurfaceTargetUnsafe::RawHandle {
110 raw_display_handle: Some(rwh6_display),
111 raw_window_handle: rwh6_window,
112 }
113 }
114 #[cfg(target_os = "linux")]
115 RwhRawWindowHandle::Xlib(handle) => {
116 let RwhRawDisplayHandle::Xlib(display_handle) = window.raw_display_handle() else {
117 return None;
118 };
119 let display_ptr = std::ptr::NonNull::new(display_handle.display);
120 let rwh6_window = wgpu::rwh::RawWindowHandle::Xlib(
121 wgpu::rwh::XlibWindowHandle::new(handle.window),
122 );
123 let rwh6_display = wgpu::rwh::RawDisplayHandle::Xlib(
124 wgpu::rwh::XlibDisplayHandle::new(display_ptr, display_handle.screen),
125 );
126 wgpu::SurfaceTargetUnsafe::RawHandle {
127 raw_display_handle: Some(rwh6_display),
128 raw_window_handle: rwh6_window,
129 }
130 }
131 _ => return None,
132 };
133
134 instance.create_surface_unsafe(surface_target).ok()
135 }
136}