Skip to content

Commit ffabb52

Browse files
committed
[metal] Use raw-window-metal to do layer creation
This uses observers internally, which fixes resizing when using Wgpu together with an auto-layout NSView. Though it probably won't matter much, it's also more reliable to update the scale factor this way, rather than haphazardly in `configure`.
1 parent 5c7389a commit ffabb52

File tree

6 files changed

+121
-282
lines changed

6 files changed

+121
-282
lines changed

Cargo.lock

Lines changed: 80 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ block = "0.1"
138138
core-graphics-types = "0.1"
139139
metal = { version = "0.29.0" }
140140
objc = "0.2.5"
141+
raw-window-metal = "1.0"
141142

142143
# Vulkan dependencies
143144
android_system_properties = "0.1.1"

wgpu-hal/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ metal = [
4444
# Metal is only available on Apple platforms, therefore request MSL output also only if we target an Apple platform.
4545
"naga/msl-out-if-target-apple",
4646
"dep:block",
47+
"dep:raw-window-metal",
4748
]
4849
vulkan = [
4950
"naga/spv-out",
@@ -53,6 +54,7 @@ vulkan = [
5354
"dep:libloading",
5455
"dep:smallvec",
5556
"dep:android_system_properties",
57+
"dep:raw-window-metal",
5658
]
5759
gles = [
5860
"naga/glsl-out",
@@ -166,6 +168,9 @@ glutin_wgl_sys = { workspace = true, optional = true }
166168
# backend: Metal
167169
block = { workspace = true, optional = true }
168170

171+
# backend: Metal + Vulkan
172+
raw-window-metal = { workspace = true, optional = true }
173+
169174
metal.workspace = true
170175
objc.workspace = true
171176
core-graphics-types.workspace = true

wgpu-hal/src/metal/mod.rs

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use std::{
3434

3535
use arrayvec::ArrayVec;
3636
use bitflags::bitflags;
37-
use metal::foreign_types::ForeignTypeRef as _;
37+
use metal::foreign_types::{ForeignType as _, ForeignTypeRef as _};
3838
use parking_lot::{Mutex, RwLock};
3939

4040
#[derive(Clone, Debug)]
@@ -100,7 +100,7 @@ pub struct Instance {}
100100

101101
impl Instance {
102102
pub fn create_surface_from_layer(&self, layer: &metal::MetalLayerRef) -> Surface {
103-
unsafe { Surface::from_layer(layer) }
103+
Surface::from_layer(layer)
104104
}
105105
}
106106

@@ -119,19 +119,25 @@ impl crate::Instance for Instance {
119119
_display_handle: raw_window_handle::RawDisplayHandle,
120120
window_handle: raw_window_handle::RawWindowHandle,
121121
) -> Result<Surface, crate::InstanceError> {
122-
match window_handle {
123-
#[cfg(target_os = "ios")]
124-
raw_window_handle::RawWindowHandle::UiKit(handle) => {
125-
Ok(unsafe { Surface::from_view(handle.ui_view.cast()) })
122+
let layer = match window_handle {
123+
raw_window_handle::RawWindowHandle::AppKit(handle) => unsafe {
124+
raw_window_metal::Layer::from_ns_view(handle.ns_view)
125+
},
126+
raw_window_handle::RawWindowHandle::UiKit(handle) => unsafe {
127+
raw_window_metal::Layer::from_ui_view(handle.ui_view)
128+
},
129+
_ => {
130+
return Err(crate::InstanceError::new(format!(
131+
"window handle {window_handle:?} is not a Metal-compatible handle"
132+
)))
126133
}
127-
#[cfg(target_os = "macos")]
128-
raw_window_handle::RawWindowHandle::AppKit(handle) => {
129-
Ok(unsafe { Surface::from_view(handle.ns_view.cast()) })
130-
}
131-
_ => Err(crate::InstanceError::new(format!(
132-
"window handle {window_handle:?} is not a Metal-compatible handle"
133-
))),
134-
}
134+
};
135+
136+
// SAFETY: The layer is an initialized instance of `CAMetalLayer`, and
137+
// we transfer the retain count to `MetalLayer` using `into_raw`.
138+
let layer = unsafe { metal::MetalLayer::from_ptr(layer.into_raw().cast().as_ptr()) };
139+
140+
Ok(Surface::new(layer))
135141
}
136142

137143
unsafe fn enumerate_adapters(

0 commit comments

Comments
 (0)