mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-10-29 21:42:26 +00:00
Ios fix (#1950)
* Fix iOS, use similar approach for metal layer as wgpu * Use correct return type * Handle ios resizing * Add changelog notes * Fix typo * Update raw-window-handle * Ensure mac changes correspond master version
This commit is contained in:
parent
d4e760caa7
commit
062b5e2f96
@ -8,6 +8,7 @@
|
||||
-->
|
||||
- **Breaking** Public dependency updates:
|
||||
- Winit 0.27
|
||||
- raw-window-handle 0.5
|
||||
- **Breaking** Changes to `Instance` and Vulkan initialization:
|
||||
- `FunctionPointers` is renamed to `VulkanLibrary`, and now resides in a separate `library` module. It is re-exported from the crate root.
|
||||
- The `Loader` trait is now in the `library` module.
|
||||
@ -36,6 +37,12 @@
|
||||
- **Breaking** Changes to memory pools:
|
||||
- Renamed `StdMemoryPool[Alloc]`, `StdHostVisibleMemoryTypePool[Alloc]`, `StdNonHostVisibleMemoryTypePool[Alloc]` to `Standard{...}`.
|
||||
- Removed `Device::standard_pool` in favor of `Device::standard_memory_pool`, which returns `&Arc<StandardMemoryPool>`.
|
||||
- **Potentially Breaking** Fix iOS compilation:
|
||||
- Removed dependency to `cocoa` and `metal`
|
||||
- Fixed iOS compilation errors
|
||||
- Added `winit_to_surface` method for iOS, ensuring we can draw to a sub `CAMetalLayer` layer
|
||||
- Added `Surface::update_ios_sublayer_on_resize` to ensure iOS sublayer is fullscreen if initial window size was not the same as device's
|
||||
- Ensure both iOS and MacOS have `CAMetalLayer` when using `create_surface_from_handle`
|
||||
- Bugs fixed:
|
||||
- [#1896](https://github.com/vulkano-rs/vulkano/issues/1896): Vulkano-shaders generates invalid struct definitions when struct field names are stripped out by the compiler.
|
||||
|
||||
|
@ -339,6 +339,10 @@ impl VulkanoWindowRenderer {
|
||||
self.remove_additional_image_view(i);
|
||||
self.add_additional_image_view(i, format, usage);
|
||||
}
|
||||
#[cfg(target_os = "ios")]
|
||||
unsafe {
|
||||
self.surface.update_ios_sublayer_on_resize();
|
||||
}
|
||||
self.recreate_swapchain = false;
|
||||
}
|
||||
}
|
||||
|
@ -13,15 +13,14 @@ categories = ["rendering::graphics-api"]
|
||||
|
||||
[features]
|
||||
default = ["winit_", "raw-window-handle_"]
|
||||
winit_ = ["winit", "metal", "cocoa", "objc"]
|
||||
winit_ = ["winit", "objc", "core-graphics-types"]
|
||||
raw-window-handle_ = ["raw-window-handle"]
|
||||
|
||||
[dependencies]
|
||||
raw-window-handle = { version = "0.4", optional = true }
|
||||
raw-window-handle = { version = "0.5", optional = true }
|
||||
vulkano = { version = "0.30.0", path = "../vulkano" }
|
||||
winit = { version = "0.27", optional = true }
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
cocoa = { version = "0.24", optional = true }
|
||||
metal = { version = "0.23", optional = true }
|
||||
objc = { version = "0.2", optional = true }
|
||||
[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies]
|
||||
objc = { version = "0.2.5", optional = true }
|
||||
core-graphics-types = { version = "0.1", optional = true }
|
@ -1,4 +1,10 @@
|
||||
use raw_window_handle::{HasRawWindowHandle, RawWindowHandle};
|
||||
#[cfg(target_os = "ios")]
|
||||
use crate::get_metal_layer_ios;
|
||||
#[cfg(target_os = "macos")]
|
||||
use crate::get_metal_layer_macos;
|
||||
use raw_window_handle::{
|
||||
HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
use vulkano::instance::Instance;
|
||||
use vulkano::swapchain::Surface;
|
||||
@ -6,29 +12,64 @@ use vulkano::swapchain::SurfaceCreationError;
|
||||
|
||||
/// Creates a vulkan surface from a generic window
|
||||
/// which implements HasRawWindowHandle and thus can reveal the os-dependent handle.
|
||||
/// - Note that if you wish to use this function with MacOS, you will need to ensure that the
|
||||
/// `CAMetalLayer` is set to the ns_view. An example of how one might do that can be found in
|
||||
/// `vulkano_win::set_ca_metal_layer_to_winit`
|
||||
pub fn create_surface_from_handle<W>(
|
||||
window: W,
|
||||
instance: Arc<Instance>,
|
||||
) -> Result<Arc<Surface<W>>, SurfaceCreationError>
|
||||
where
|
||||
W: HasRawWindowHandle,
|
||||
W: HasRawWindowHandle + HasRawDisplayHandle,
|
||||
{
|
||||
unsafe {
|
||||
match window.raw_window_handle() {
|
||||
RawWindowHandle::AndroidNdk(h) => {
|
||||
Surface::from_android(instance, h.a_native_window, window)
|
||||
}
|
||||
RawWindowHandle::UiKit(h) => Surface::from_ios(instance, h.ui_view, window),
|
||||
RawWindowHandle::AppKit(h) => Surface::from_mac_os(instance, h.ns_view, window),
|
||||
RawWindowHandle::UiKit(_h) => {
|
||||
#[cfg(target_os = "ios")]
|
||||
{
|
||||
// Ensure the layer is CAMetalLayer
|
||||
let layer = get_metal_layer_ios(_h.ui_view);
|
||||
Surface::from_ios(instance, layer, window)
|
||||
}
|
||||
#[cfg(not(target_os = "ios"))]
|
||||
{
|
||||
panic!("UiKit handle should only be used when target_os == 'ios'");
|
||||
}
|
||||
}
|
||||
RawWindowHandle::AppKit(_h) => {
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
// Ensure the layer is CAMetalLayer
|
||||
let layer = get_metal_layer_macos(_h.ns_view);
|
||||
Surface::from_mac_os(instance, layer as *const (), window)
|
||||
}
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
{
|
||||
panic!("AppKit handle should only be used when target_os == 'macos'");
|
||||
}
|
||||
}
|
||||
RawWindowHandle::Wayland(h) => {
|
||||
Surface::from_wayland(instance, h.display, h.surface, window)
|
||||
let d = match window.raw_display_handle() {
|
||||
RawDisplayHandle::Wayland(d) => d,
|
||||
_ => panic!("Invalid RawDisplayHandle"),
|
||||
};
|
||||
Surface::from_wayland(instance, d.display, h.surface, window)
|
||||
}
|
||||
RawWindowHandle::Win32(h) => Surface::from_win32(instance, h.hinstance, h.hwnd, window),
|
||||
RawWindowHandle::Xcb(h) => Surface::from_xcb(instance, h.connection, h.window, window),
|
||||
RawWindowHandle::Xlib(h) => Surface::from_xlib(instance, h.display, h.window, window),
|
||||
RawWindowHandle::Xcb(h) => {
|
||||
let d = match window.raw_display_handle() {
|
||||
RawDisplayHandle::Xcb(d) => d,
|
||||
_ => panic!("Invalid RawDisplayHandle"),
|
||||
};
|
||||
Surface::from_xcb(instance, d.connection, h.window, window)
|
||||
}
|
||||
RawWindowHandle::Xlib(h) => {
|
||||
let d = match window.raw_display_handle() {
|
||||
RawDisplayHandle::Xlib(d) => d,
|
||||
_ => panic!("Invalid RawDisplayHandle"),
|
||||
};
|
||||
Surface::from_xlib(instance, d.display, h.window, window)
|
||||
}
|
||||
RawWindowHandle::Web(_) => unimplemented!(),
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
|
@ -123,7 +123,12 @@ unsafe fn winit_to_surface<W: SafeBorrow<Window>>(
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(unix, not(target_os = "android"), not(target_os = "macos")))]
|
||||
#[cfg(all(
|
||||
unix,
|
||||
not(target_os = "android"),
|
||||
not(target_os = "macos"),
|
||||
not(target_os = "ios")
|
||||
))]
|
||||
unsafe fn winit_to_surface<W: SafeBorrow<Window>>(
|
||||
instance: Arc<Instance>,
|
||||
win: W,
|
||||
@ -157,36 +162,37 @@ unsafe fn winit_to_surface<W: SafeBorrow<Window>>(
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
use cocoa::{
|
||||
appkit::{NSView, NSWindow},
|
||||
base::id as cocoa_id,
|
||||
};
|
||||
#[cfg(target_os = "macos")]
|
||||
use metal::MetalLayer;
|
||||
#[cfg(target_os = "macos")]
|
||||
use objc::runtime::YES;
|
||||
#[cfg(target_os = "macos")]
|
||||
use std::mem;
|
||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||
use objc::{class, msg_send, runtime::Object, sel, sel_impl};
|
||||
|
||||
/// Ensure `CAMetalLayer` (native rendering surface on MacOs) is used by the ns_view.
|
||||
/// Get (and set) `CAMetalLayer` to ns_view.
|
||||
/// This is necessary to be able to render on Mac.
|
||||
#[cfg(target_os = "macos")]
|
||||
unsafe fn set_ca_metal_layer_to_winit<W: SafeBorrow<Window>>(win: W) {
|
||||
use winit::platform::macos::WindowExtMacOS;
|
||||
pub(crate) unsafe fn get_metal_layer_macos(view: *mut std::ffi::c_void) -> *mut Object {
|
||||
use core_graphics_types::base::CGFloat;
|
||||
use objc::runtime::YES;
|
||||
use objc::runtime::{BOOL, NO};
|
||||
|
||||
let wnd: cocoa_id = mem::transmute(win.borrow().ns_window());
|
||||
let layer = MetalLayer::new();
|
||||
|
||||
layer.set_edge_antialiasing_mask(0);
|
||||
layer.set_presents_with_transaction(false);
|
||||
layer.remove_all_animations();
|
||||
|
||||
let view = wnd.contentView();
|
||||
|
||||
layer.set_contents_scale(view.backingScaleFactor());
|
||||
view.setLayer(mem::transmute(layer.as_ref())); // Bombs here with out of memory
|
||||
view.setWantsLayer(YES);
|
||||
let view: *mut Object = std::mem::transmute(view);
|
||||
let main_layer: *mut Object = msg_send![view, layer];
|
||||
let class = class!(CAMetalLayer);
|
||||
let is_valid_layer: BOOL = msg_send![main_layer, isKindOfClass: class];
|
||||
if is_valid_layer == NO {
|
||||
let new_layer: *mut Object = msg_send![class, new];
|
||||
let () = msg_send![new_layer, setEdgeAntialiasingMask: 0];
|
||||
let () = msg_send![new_layer, setPresentsWithTransaction: false];
|
||||
let () = msg_send![new_layer, removeAllAnimations];
|
||||
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() {
|
||||
let scale_factor: CGFloat = msg_send![window, backingScaleFactor];
|
||||
let () = msg_send![new_layer, setContentsScale: scale_factor];
|
||||
}
|
||||
new_layer
|
||||
} else {
|
||||
main_layer
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
@ -195,9 +201,39 @@ unsafe fn winit_to_surface<W: SafeBorrow<Window>>(
|
||||
win: W,
|
||||
) -> Result<Arc<Surface<W>>, SurfaceCreationError> {
|
||||
use winit::platform::macos::WindowExtMacOS;
|
||||
let layer = get_metal_layer_macos(win.borrow().ns_view());
|
||||
Surface::from_mac_os(instance, layer as *const (), win)
|
||||
}
|
||||
|
||||
set_ca_metal_layer_to_winit(win.borrow());
|
||||
Surface::from_mac_os(instance, win.borrow().ns_view() as *const (), win)
|
||||
#[cfg(target_os = "ios")]
|
||||
use vulkano::swapchain::IOSMetalLayer;
|
||||
|
||||
/// Get sublayer from iOS main view (ui_view). The sublayer is created as CAMetalLayer
|
||||
#[cfg(target_os = "ios")]
|
||||
pub(crate) unsafe fn get_metal_layer_ios(view: *mut std::ffi::c_void) -> IOSMetalLayer {
|
||||
use core_graphics_types::{base::CGFloat, geometry::CGRect};
|
||||
|
||||
let view: *mut Object = std::mem::transmute(view);
|
||||
let main_layer: *mut Object = msg_send![view, layer];
|
||||
let class = class!(CAMetalLayer);
|
||||
let new_layer: *mut Object = msg_send![class, new];
|
||||
let frame: CGRect = msg_send![main_layer, bounds];
|
||||
let () = msg_send![new_layer, setFrame: frame];
|
||||
let () = msg_send![main_layer, addSublayer: new_layer];
|
||||
let screen: *mut Object = msg_send![class!(UIScreen), mainScreen];
|
||||
let scale_factor: CGFloat = msg_send![screen, nativeScale];
|
||||
let () = msg_send![view, setContentScaleFactor: scale_factor];
|
||||
IOSMetalLayer::new(view, new_layer)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
unsafe fn winit_to_surface<W: SafeBorrow<Window>>(
|
||||
instance: Arc<Instance>,
|
||||
win: W,
|
||||
) -> Result<Arc<Surface<W>>, SurfaceCreationError> {
|
||||
use winit::platform::ios::WindowExtIOS;
|
||||
let layer = get_metal_layer_ios(win.borrow().ui_view());
|
||||
Surface::from_ios(instance, layer, win)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
|
@ -26,6 +26,10 @@ once_cell = { version = "1.13", features = ["parking_lot"] }
|
||||
parking_lot = { version = "0.12", features = ["send_guard"] }
|
||||
smallvec = "1.8"
|
||||
|
||||
[target.'cfg(target_os = "ios")'.dependencies]
|
||||
objc = "0.2.5"
|
||||
core-graphics-types = "0.1"
|
||||
|
||||
[build-dependencies]
|
||||
heck = "0.4"
|
||||
indexmap = "1.8"
|
||||
|
@ -42,8 +42,8 @@ impl VulkanLibrary {
|
||||
pub fn new() -> Result<Arc<Self>, LoadingError> {
|
||||
#[cfg(target_os = "ios")]
|
||||
#[allow(non_snake_case)]
|
||||
fn def_loader_impl() -> Result<Box<Loader>, LoadingError> {
|
||||
let loader = statically_linked_vulkan_loader!();
|
||||
fn def_loader_impl() -> Result<Box<dyn Loader>, LoadingError> {
|
||||
let loader = crate::statically_linked_vulkan_loader!();
|
||||
Ok(Box::new(loader))
|
||||
}
|
||||
|
||||
@ -84,7 +84,6 @@ impl VulkanLibrary {
|
||||
.get_instance_proc_addr(ash::vk::Instance::null(), name.as_ptr())
|
||||
.map_or(ptr::null(), |func| func as _)
|
||||
});
|
||||
|
||||
// Per the Vulkan spec:
|
||||
// If the vkGetInstanceProcAddr returns NULL for vkEnumerateInstanceVersion, it is a
|
||||
// Vulkan 1.0 implementation. Otherwise, the application can call vkEnumerateInstanceVersion
|
||||
@ -325,12 +324,12 @@ macro_rules! statically_linked_vulkan_loader {
|
||||
|
||||
struct StaticallyLinkedVulkanLoader;
|
||||
unsafe impl Loader for StaticallyLinkedVulkanLoader {
|
||||
fn get_instance_proc_addr(
|
||||
unsafe fn get_instance_proc_addr(
|
||||
&self,
|
||||
instance: ash::vk::Instance,
|
||||
name: *const c_char,
|
||||
) -> extern "system" fn() -> () {
|
||||
unsafe { vkGetInstanceProcAddr(instance, name) }
|
||||
) -> ash::vk::PFN_vkVoidFunction {
|
||||
vkGetInstanceProcAddr(instance, name)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -330,6 +330,9 @@ pub use self::{
|
||||
SwapchainAcquireFuture, SwapchainCreateInfo, SwapchainCreationError, Win32Monitor,
|
||||
},
|
||||
};
|
||||
#[cfg(target_os = "ios")]
|
||||
pub use surface::IOSMetalLayer;
|
||||
|
||||
use std::sync::atomic::AtomicBool;
|
||||
|
||||
pub mod display;
|
||||
|
@ -18,6 +18,10 @@ use crate::{
|
||||
},
|
||||
Error, OomError, VulkanObject,
|
||||
};
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
use objc::{class, msg_send, runtime::Object, sel, sel_impl};
|
||||
|
||||
use std::{
|
||||
error, fmt,
|
||||
hash::{Hash, Hasher},
|
||||
@ -35,10 +39,11 @@ pub struct Surface<W> {
|
||||
instance: Arc<Instance>,
|
||||
api: SurfaceApi,
|
||||
window: W,
|
||||
|
||||
// If true, a swapchain has been associated to this surface, and that any new swapchain
|
||||
// creation should be forbidden.
|
||||
has_swapchain: AtomicBool,
|
||||
#[cfg(target_os = "ios")]
|
||||
metal_layer: IOSMetalLayer,
|
||||
}
|
||||
|
||||
impl<W> Surface<W> {
|
||||
@ -63,6 +68,8 @@ impl<W> Surface<W> {
|
||||
window: win,
|
||||
|
||||
has_swapchain: AtomicBool::new(false),
|
||||
#[cfg(target_os = "ios")]
|
||||
metal_layer: IOSMetalLayer::new(std::ptr::null_mut(), std::ptr::null_mut()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,6 +138,8 @@ impl<W> Surface<W> {
|
||||
window: (),
|
||||
|
||||
has_swapchain: AtomicBool::new(false),
|
||||
#[cfg(target_os = "ios")]
|
||||
metal_layer: IOSMetalLayer::new(std::ptr::null_mut(), std::ptr::null_mut()),
|
||||
}))
|
||||
}
|
||||
|
||||
@ -177,6 +186,8 @@ impl<W> Surface<W> {
|
||||
window: win,
|
||||
|
||||
has_swapchain: AtomicBool::new(false),
|
||||
#[cfg(target_os = "ios")]
|
||||
metal_layer: IOSMetalLayer::new(std::ptr::null_mut(), std::ptr::null_mut()),
|
||||
}))
|
||||
}
|
||||
|
||||
@ -188,9 +199,10 @@ impl<W> Surface<W> {
|
||||
/// - The object referred to by `view` must outlive the created `Surface`.
|
||||
/// The `win` parameter can be used to ensure this.
|
||||
/// - The `UIView` must be backed by a `CALayer` instance of type `CAMetalLayer`.
|
||||
pub unsafe fn from_ios<T>(
|
||||
#[cfg(target_os = "ios")]
|
||||
pub unsafe fn from_ios(
|
||||
instance: Arc<Instance>,
|
||||
view: *const T,
|
||||
metal_layer: IOSMetalLayer,
|
||||
win: W,
|
||||
) -> Result<Arc<Surface<W>>, SurfaceCreationError> {
|
||||
if !instance.enabled_extensions().mvk_ios_surface {
|
||||
@ -201,7 +213,7 @@ impl<W> Surface<W> {
|
||||
|
||||
let create_info = ash::vk::IOSSurfaceCreateInfoMVK {
|
||||
flags: ash::vk::IOSSurfaceCreateFlagsMVK::empty(),
|
||||
p_view: view as *const _,
|
||||
p_view: metal_layer.render_layer.0 as *const _,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
@ -224,6 +236,7 @@ impl<W> Surface<W> {
|
||||
window: win,
|
||||
|
||||
has_swapchain: AtomicBool::new(false),
|
||||
metal_layer,
|
||||
}))
|
||||
}
|
||||
|
||||
@ -235,6 +248,7 @@ impl<W> Surface<W> {
|
||||
/// - The object referred to by `view` must outlive the created `Surface`.
|
||||
/// The `win` parameter can be used to ensure this.
|
||||
/// - The `NSView` must be backed by a `CALayer` instance of type `CAMetalLayer`.
|
||||
#[cfg(target_os = "macos")]
|
||||
pub unsafe fn from_mac_os<T>(
|
||||
instance: Arc<Instance>,
|
||||
view: *const T,
|
||||
@ -271,6 +285,8 @@ impl<W> Surface<W> {
|
||||
window: win,
|
||||
|
||||
has_swapchain: AtomicBool::new(false),
|
||||
#[cfg(target_os = "ios")]
|
||||
metal_layer: IOSMetalLayer::new(std::ptr::null_mut(), std::ptr::null_mut()),
|
||||
}))
|
||||
}
|
||||
|
||||
@ -317,6 +333,8 @@ impl<W> Surface<W> {
|
||||
window: win,
|
||||
|
||||
has_swapchain: AtomicBool::new(false),
|
||||
#[cfg(target_os = "ios")]
|
||||
metal_layer: IOSMetalLayer::new(std::ptr::null_mut(), std::ptr::null_mut()),
|
||||
}))
|
||||
}
|
||||
|
||||
@ -363,6 +381,8 @@ impl<W> Surface<W> {
|
||||
window: win,
|
||||
|
||||
has_swapchain: AtomicBool::new(false),
|
||||
#[cfg(target_os = "ios")]
|
||||
metal_layer: IOSMetalLayer::new(std::ptr::null_mut(), std::ptr::null_mut()),
|
||||
}))
|
||||
}
|
||||
|
||||
@ -413,6 +433,8 @@ impl<W> Surface<W> {
|
||||
window: win,
|
||||
|
||||
has_swapchain: AtomicBool::new(false),
|
||||
#[cfg(target_os = "ios")]
|
||||
metal_layer: IOSMetalLayer::new(std::ptr::null_mut(), std::ptr::null_mut()),
|
||||
}))
|
||||
}
|
||||
|
||||
@ -463,6 +485,8 @@ impl<W> Surface<W> {
|
||||
window: win,
|
||||
|
||||
has_swapchain: AtomicBool::new(false),
|
||||
#[cfg(target_os = "ios")]
|
||||
metal_layer: IOSMetalLayer::new(std::ptr::null_mut(), std::ptr::null_mut()),
|
||||
}))
|
||||
}
|
||||
|
||||
@ -513,6 +537,8 @@ impl<W> Surface<W> {
|
||||
window: win,
|
||||
|
||||
has_swapchain: AtomicBool::new(false),
|
||||
#[cfg(target_os = "ios")]
|
||||
metal_layer: IOSMetalLayer::new(std::ptr::null_mut(), std::ptr::null_mut()),
|
||||
}))
|
||||
}
|
||||
|
||||
@ -563,6 +589,8 @@ impl<W> Surface<W> {
|
||||
window: win,
|
||||
|
||||
has_swapchain: AtomicBool::new(false),
|
||||
#[cfg(target_os = "ios")]
|
||||
metal_layer: IOSMetalLayer::new(std::ptr::null_mut(), std::ptr::null_mut()),
|
||||
}))
|
||||
}
|
||||
|
||||
@ -583,6 +611,24 @@ impl<W> Surface<W> {
|
||||
pub fn window(&self) -> &W {
|
||||
&self.window
|
||||
}
|
||||
|
||||
/// Resizes the sublayer bounds on iOS.
|
||||
/// It may not be necessary if original window size matches device's, but often it does not.
|
||||
/// Thus this should be called after a resize has occurred abd swapchain has been recreated.
|
||||
///
|
||||
/// On iOS, we've created CAMetalLayer as a sublayer. However, when the view changes size,
|
||||
/// its sublayers are not automatically resized, and we must resize
|
||||
/// it here.
|
||||
#[cfg(target_os = "ios")]
|
||||
#[inline]
|
||||
pub unsafe fn update_ios_sublayer_on_resize(&self) {
|
||||
use core_graphics_types::geometry::CGRect;
|
||||
let class = class!(CAMetalLayer);
|
||||
let main_layer: *mut Object = self.metal_layer.main_layer.0;
|
||||
let bounds: CGRect = msg_send![main_layer, bounds];
|
||||
let render_layer: *mut Object = self.metal_layer.render_layer.0;
|
||||
let () = msg_send![render_layer, setFrame: bounds];
|
||||
}
|
||||
}
|
||||
|
||||
impl<W> Drop for Surface<W> {
|
||||
@ -616,8 +662,8 @@ impl<W> fmt::Debug for Surface<W> {
|
||||
instance,
|
||||
api,
|
||||
window: _,
|
||||
|
||||
has_swapchain,
|
||||
..
|
||||
} = self;
|
||||
|
||||
fmt.debug_struct("Surface")
|
||||
@ -1226,6 +1272,38 @@ impl Default for SurfaceInfo {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
struct LayerHandle(*mut Object);
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
unsafe impl Send for LayerHandle {}
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
unsafe impl Sync for LayerHandle {}
|
||||
|
||||
/// Represents the metal layer for IOS
|
||||
#[cfg(target_os = "ios")]
|
||||
pub struct IOSMetalLayer {
|
||||
main_layer: LayerHandle,
|
||||
render_layer: LayerHandle,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
impl IOSMetalLayer {
|
||||
pub fn new(main_layer: *mut Object, render_layer: *mut Object) -> Self {
|
||||
Self {
|
||||
main_layer: LayerHandle(main_layer),
|
||||
render_layer: LayerHandle(render_layer),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
unsafe impl Send for IOSMetalLayer {}
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
unsafe impl Sync for IOSMetalLayer {}
|
||||
|
||||
/// The capabilities of a surface when used by a physical device.
|
||||
///
|
||||
/// You have to match these capabilities when you create a swapchain.
|
||||
|
Loading…
Reference in New Issue
Block a user