mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-25 08:13:27 +00:00
hal/metal: inherit scaling from NSView
This commit is contained in:
parent
9c0b519373
commit
50f5deed6c
@ -61,7 +61,9 @@ impl crate::Api for Api {
|
||||
type ComputePipeline = ComputePipeline;
|
||||
}
|
||||
|
||||
pub struct Instance {}
|
||||
pub struct Instance {
|
||||
managed_metal_layer_delegate: surface::HalManagedMetalLayerDelegate,
|
||||
}
|
||||
|
||||
impl Instance {
|
||||
pub fn create_surface_from_layer(&self, layer: &mtl::MetalLayerRef) -> Surface {
|
||||
@ -72,7 +74,9 @@ impl Instance {
|
||||
impl crate::Instance<Api> for Instance {
|
||||
unsafe fn init(_desc: &crate::InstanceDescriptor) -> Result<Self, crate::InstanceError> {
|
||||
//TODO: enable `METAL_DEVICE_WRAPPER_TYPE` environment based on the flags?
|
||||
Ok(Instance {})
|
||||
Ok(Instance {
|
||||
managed_metal_layer_delegate: surface::HalManagedMetalLayerDelegate::new(),
|
||||
})
|
||||
}
|
||||
|
||||
unsafe fn create_surface(
|
||||
@ -82,12 +86,14 @@ impl crate::Instance<Api> for Instance {
|
||||
match has_handle.raw_window_handle() {
|
||||
#[cfg(target_os = "ios")]
|
||||
raw_window_handle::RawWindowHandle::IOS(handle) => {
|
||||
let _ = &self.managed_metal_layer_delegate;
|
||||
Ok(Surface::from_uiview(handle.ui_view))
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
raw_window_handle::RawWindowHandle::MacOS(handle) => {
|
||||
Ok(Surface::from_nsview(handle.ns_view))
|
||||
}
|
||||
raw_window_handle::RawWindowHandle::MacOS(handle) => Ok(Surface::from_nsview(
|
||||
handle.ns_view,
|
||||
&self.managed_metal_layer_delegate,
|
||||
)),
|
||||
_ => Err(crate::InstanceError),
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,15 @@
|
||||
use std::{mem, os::raw::c_void, ptr::NonNull, thread};
|
||||
use std::{mem, os::raw::c_void, ptr::NonNull, sync::Once, thread};
|
||||
|
||||
use core_graphics_types::{
|
||||
base::CGFloat,
|
||||
geometry::{CGRect, CGSize},
|
||||
};
|
||||
use objc::{
|
||||
class, msg_send,
|
||||
class,
|
||||
declare::ClassDecl,
|
||||
msg_send,
|
||||
rc::autoreleasepool,
|
||||
runtime::{Object, BOOL, YES},
|
||||
runtime::{Class, Object, Sel, BOOL, YES},
|
||||
sel, sel_impl,
|
||||
};
|
||||
use parking_lot::Mutex;
|
||||
@ -19,6 +21,40 @@ extern "C" {
|
||||
static kCAGravityTopLeft: *mut Object;
|
||||
}
|
||||
|
||||
extern "C" fn layer_should_inherit_contents_scale_from_window(
|
||||
_: &Class,
|
||||
_: Sel,
|
||||
_layer: *mut Object,
|
||||
_new_scale: CGFloat,
|
||||
_from_window: *mut Object,
|
||||
) -> BOOL {
|
||||
YES
|
||||
}
|
||||
|
||||
const CAML_DELEGATE_CLASS: &str = "HalManagedMetalLayerDelegate";
|
||||
static CAML_DELEGATE_REGISTER: Once = Once::new();
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct HalManagedMetalLayerDelegate(&'static Class);
|
||||
|
||||
impl HalManagedMetalLayerDelegate {
|
||||
pub fn new() -> Self {
|
||||
CAML_DELEGATE_REGISTER.call_once(|| {
|
||||
type Fun = extern "C" fn(&Class, Sel, *mut Object, CGFloat, *mut Object) -> BOOL;
|
||||
let mut decl = ClassDecl::new(CAML_DELEGATE_CLASS, class!(NSObject)).unwrap();
|
||||
#[allow(trivial_casts)] // false positive
|
||||
unsafe {
|
||||
decl.add_class_method(
|
||||
sel!(layer:shouldInheritContentsScale:fromWindow:),
|
||||
layer_should_inherit_contents_scale_from_window as Fun,
|
||||
);
|
||||
}
|
||||
decl.register();
|
||||
});
|
||||
Self(Class::get(CAML_DELEGATE_CLASS).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl super::Surface {
|
||||
fn new(view: Option<NonNull<Object>>, layer: mtl::MetalLayer) -> Self {
|
||||
Self {
|
||||
@ -74,7 +110,10 @@ impl super::Surface {
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[allow(clippy::transmute_ptr_to_ref)]
|
||||
pub unsafe fn from_nsview(nsview: *mut c_void) -> Self {
|
||||
pub unsafe fn from_nsview(
|
||||
nsview: *mut c_void,
|
||||
delegate: &HalManagedMetalLayerDelegate,
|
||||
) -> Self {
|
||||
let view = nsview as *mut Object;
|
||||
if view.is_null() {
|
||||
panic!("window does not have a valid contentView");
|
||||
@ -109,7 +148,7 @@ impl super::Surface {
|
||||
let scale_factor: CGFloat = msg_send![window, backingScaleFactor];
|
||||
let () = msg_send![layer, setContentsScale: scale_factor];
|
||||
}
|
||||
//let () = msg_send![layer, setDelegate: self.gfx_managed_metal_layer_delegate.0];
|
||||
let () = msg_send![layer, setDelegate: delegate.0];
|
||||
layer
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user