From d1ab3f672673180d70c4ee164fd57924f5ab1be4 Mon Sep 17 00:00:00 2001 From: Okko Hakola Date: Mon, 28 Mar 2022 16:28:51 +0300 Subject: [PATCH] Fix game of life example on macos (#1829) --- .../multi_window_game_of_life/vulkano_window.rs | 4 ++-- vulkano-win/src/raw_window_handle.rs | 5 ++++- vulkano-win/src/winit.rs | 16 ++++++++++++---- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/examples/src/bin/multi_window_game_of_life/vulkano_window.rs b/examples/src/bin/multi_window_game_of_life/vulkano_window.rs index 7a652122a4..77f08bc118 100644 --- a/examples/src/bin/multi_window_game_of_life/vulkano_window.rs +++ b/examples/src/bin/multi_window_game_of_life/vulkano_window.rs @@ -23,7 +23,7 @@ use vulkano::{ sync, sync::{FlushError, GpuFuture}, }; -use vulkano_win::create_surface_from_handle; +use vulkano_win::create_surface_from_winit; use winit::window::Window; pub struct VulkanoWindow { @@ -52,7 +52,7 @@ impl VulkanoWindow { vsync: bool, ) -> VulkanoWindow { // Create rendering surface from window - let surface = create_surface_from_handle(window, vulkano_context.instance()).unwrap(); + let surface = create_surface_from_winit(window, vulkano_context.instance()).unwrap(); // Create swap chain & frame(s) to which we'll render let (swapchain, final_views) = vulkano_context.create_swapchain( surface.clone(), diff --git a/vulkano-win/src/raw_window_handle.rs b/vulkano-win/src/raw_window_handle.rs index 015fdd3463..5c55d8c848 100644 --- a/vulkano-win/src/raw_window_handle.rs +++ b/vulkano-win/src/raw_window_handle.rs @@ -5,7 +5,10 @@ use vulkano::swapchain::Surface; use vulkano::swapchain::SurfaceCreationError; /// Creates a vulkan surface from a generic window -/// which implements HasRawWindowHandle and thus can reveal the os-dependent handle +/// 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( window: W, instance: Arc, diff --git a/vulkano-win/src/winit.rs b/vulkano-win/src/winit.rs index 61380d6abe..0fc905a30a 100644 --- a/vulkano-win/src/winit.rs +++ b/vulkano-win/src/winit.rs @@ -172,11 +172,10 @@ use objc::runtime::YES; #[cfg(target_os = "macos")] use std::mem; +/// Ensure `CAMetalLayer` (native rendering surface on MacOs) is used by the ns_view. +/// This is necessary to be able to render on Mac. #[cfg(target_os = "macos")] -unsafe fn winit_to_surface>( - instance: Arc, - win: W, -) -> Result>, SurfaceCreationError> { +unsafe fn set_ca_metal_layer_to_winit>(win: W) { use winit::platform::macos::WindowExtMacOS; let wnd: cocoa_id = mem::transmute(win.borrow().ns_window()); @@ -191,7 +190,16 @@ unsafe fn winit_to_surface>( layer.set_contents_scale(view.backingScaleFactor()); view.setLayer(mem::transmute(layer.as_ref())); // Bombs here with out of memory view.setWantsLayer(YES); +} + +#[cfg(target_os = "macos")] +unsafe fn winit_to_surface>( + instance: Arc, + win: W, +) -> Result>, SurfaceCreationError> { + use winit::platform::macos::WindowExtMacOS; + set_ca_metal_layer_to_winit(win.borrow()); Surface::from_mac_os(instance, win.borrow().ns_view() as *const (), win) }