hal/vk: Refactor create_surface_from_ns_view , make it both correct on iOS macOS

This commit is contained in:
Jinlei Li 2022-02-18 11:36:45 +08:00 committed by Dzmitry Malyshau
parent fa35c0a0f4
commit 8dd711ed3d

View File

@ -368,7 +368,7 @@ impl super::Instance {
} }
#[cfg(any(target_os = "macos", target_os = "ios"))] #[cfg(any(target_os = "macos", target_os = "ios"))]
fn create_surface_from_ns_view(&self, view: *mut c_void) -> super::Surface { fn create_surface_from_view(&self, view: *mut c_void) -> super::Surface {
use core_graphics_types::{base::CGFloat, geometry::CGRect}; use core_graphics_types::{base::CGFloat, geometry::CGRect};
use objc::{ use objc::{
class, msg_send, class, msg_send,
@ -381,27 +381,33 @@ impl super::Instance {
let existing: *mut Object = msg_send![view, layer]; let existing: *mut Object = msg_send![view, layer];
let class = class!(CAMetalLayer); let class = class!(CAMetalLayer);
let use_current = if existing.is_null() { let use_current: BOOL = msg_send![existing, isKindOfClass: class];
false if use_current == YES {
} else {
let result: BOOL = msg_send![existing, isKindOfClass: class];
result == YES
};
if use_current {
existing existing
} else { } else {
let layer: *mut Object = msg_send![class, new]; let new_layer: *mut Object = msg_send![class, new];
let () = msg_send![view, setLayer: layer]; let frame: CGRect = msg_send![existing, bounds];
let bounds: CGRect = msg_send![view, bounds]; let () = msg_send![new_layer, setFrame: frame];
let () = msg_send![layer, setBounds: bounds];
let window: *mut Object = msg_send![view, window]; let scale_factor: CGFloat = if cfg!(target_os = "ios") {
if !window.is_null() { let () = msg_send![existing, addSublayer: new_layer];
let scale_factor: CGFloat = msg_send![window, backingScaleFactor]; // On iOS, `create_surface_from_view` may be called before the application initialization is complete,
let () = msg_send![layer, setContentsScale: scale_factor]; // `msg_send![view, window]` and `msg_send![window, screen]` will get null.
} let screen: *mut Object = msg_send![class!(UIScreen), mainScreen];
layer msg_send![screen, nativeScale]
} else {
let () = msg_send![view, setLayer: new_layer];
let () = msg_send![view, setWantsLayer: YES];
let window: *mut Object = msg_send![view, window];
if !window.is_null() {
msg_send![window, backingScaleFactor]
} else {
1.0
}
};
let () = msg_send![new_layer, setContentsScale: scale_factor];
new_layer
} }
}; };
@ -586,13 +592,13 @@ impl crate::Instance<super::Api> for super::Instance {
RawWindowHandle::AppKit(handle) RawWindowHandle::AppKit(handle)
if self.extensions.contains(&ext::MetalSurface::name()) => if self.extensions.contains(&ext::MetalSurface::name()) =>
{ {
Ok(self.create_surface_from_ns_view(handle.ns_view)) Ok(self.create_surface_from_view(handle.ns_view))
} }
#[cfg(target_os = "ios")] #[cfg(target_os = "ios")]
RawWindowHandle::UiKit(handle) RawWindowHandle::UiKit(handle)
if self.extensions.contains(&ext::MetalSurface::name()) => if self.extensions.contains(&ext::MetalSurface::name()) =>
{ {
Ok(self.create_surface_from_ns_view(handle.ui_view)) Ok(self.create_surface_from_view(handle.ui_view))
} }
_ => Err(crate::InstanceError), _ => Err(crate::InstanceError),
} }