From 7853e7d084cb89e8db2d7117da7f766e1b5b94aa Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Sun, 17 Nov 2024 00:42:47 -0800 Subject: [PATCH] Wrap surface creation with configuration into a shared method --- blade-graphics/src/gles/egl.rs | 88 +++++++++++++--------------- blade-graphics/src/gles/web.rs | 11 ++-- blade-graphics/src/lib.rs | 14 +++++ blade-graphics/src/metal/surface.rs | 25 ++++---- blade-graphics/src/vulkan/surface.rs | 7 +-- examples/bunnymark/main.rs | 2 +- examples/particle/main.rs | 4 +- examples/ray-query/main.rs | 4 +- examples/scene/main.rs | 4 +- src/lib.rs | 4 +- 10 files changed, 85 insertions(+), 78 deletions(-) diff --git a/blade-graphics/src/gles/egl.rs b/blade-graphics/src/gles/egl.rs index 6076f8e..84997d1 100644 --- a/blade-graphics/src/gles/egl.rs +++ b/blade-graphics/src/gles/egl.rs @@ -260,36 +260,64 @@ impl super::Context { }) } - pub fn create_surface< - I: raw_window_handle::HasWindowHandle + raw_window_handle::HasDisplayHandle, - >( + pub fn create_surface( &self, window: I, - config: crate::SurfaceConfig, ) -> Result { - use raw_window_handle::RawDisplayHandle as Rdh; + use raw_window_handle::RawWindowHandle as Rwh; - let library = match window.display_handle().unwrap().as_raw() { - Rdh::Xlib(_) => Some(find_x_library().unwrap()), - Rdh::Xcb(_) => Some(find_x_library().unwrap()), - Rdh::Wayland(_) => Some(find_wayland_library().unwrap()), + let window_handle = window.window_handle().unwrap().as_raw(); + let library = match window_handle { + Rwh::Xlib(_) => Some(find_x_library().unwrap()), + Rwh::Xcb(_) => Some(find_x_library().unwrap()), + Rwh::Wayland(_) => Some(find_wayland_library().unwrap()), _ => None, }; - let mut surface = unsafe { + Ok(unsafe { let guard = self.lock(); super::Surface { platform: PlatformSurface { library, - window_handle: window.window_handle().unwrap().as_raw(), + window_handle, swapchain: Mutex::new(None), }, renderbuf: guard.create_renderbuffer().unwrap(), framebuf: guard.create_framebuffer().unwrap(), } - }; - self.reconfigure_surface(&mut surface, config); - Ok(surface) + }) + } + + pub fn destroy_surface(&self, surface: &mut super::Surface) { + use raw_window_handle::RawWindowHandle as Rwh; + + let inner = self.platform.inner.lock().unwrap(); + let mut swapchain = surface.platform.swapchain.lock().unwrap(); + if let Some(s) = swapchain.take() { + inner + .egl + .instance + .destroy_surface(inner.egl.display, s.surface) + .unwrap(); + } + if let Rwh::Wayland(handle) = surface.platform.window_handle { + unsafe { + let wl_egl_window_destroy: libloading::Symbol = surface + .platform + .library + .as_ref() + .unwrap() + .get(b"wl_egl_window_destroy") + .unwrap(); + wl_egl_window_destroy(handle.surface.as_ptr()); + } + } + inner.egl.make_current(); + unsafe { + inner.glow.delete_renderbuffer(surface.renderbuf); + inner.glow.delete_framebuffer(surface.framebuf); + } + inner.egl.unmake_current(); } pub fn reconfigure_surface(&self, surface: &mut super::Surface, config: crate::SurfaceConfig) { @@ -449,38 +477,6 @@ impl super::Context { inner.egl.unmake_current(); } - pub fn destroy_surface(&self, surface: &mut super::Surface) { - use raw_window_handle::RawWindowHandle as Rwh; - - let inner = self.platform.inner.lock().unwrap(); - let mut swapchain = surface.platform.swapchain.lock().unwrap(); - if let Some(s) = swapchain.take() { - inner - .egl - .instance - .destroy_surface(inner.egl.display, s.surface) - .unwrap(); - } - if let Rwh::Wayland(handle) = surface.platform.window_handle { - unsafe { - let wl_egl_window_destroy: libloading::Symbol = surface - .platform - .library - .as_ref() - .unwrap() - .get(b"wl_egl_window_destroy") - .unwrap(); - wl_egl_window_destroy(handle.surface.as_ptr()); - } - } - inner.egl.make_current(); - unsafe { - inner.glow.delete_renderbuffer(surface.renderbuf); - inner.glow.delete_framebuffer(surface.framebuf); - } - inner.egl.unmake_current(); - } - pub(super) fn lock(&self) -> ContextLock { let inner = self.platform.inner.lock().unwrap(); inner.egl.make_current(); diff --git a/blade-graphics/src/gles/web.rs b/blade-graphics/src/gles/web.rs index f9a542a..19134db 100644 --- a/blade-graphics/src/gles/web.rs +++ b/blade-graphics/src/gles/web.rs @@ -101,7 +101,6 @@ impl super::Context { pub fn create_surface( &self, _window: &I, - config: crate::SurfaceConfig, ) -> Result { let platform = PlatformSurface { info: crate::SurfaceInfo { @@ -110,17 +109,17 @@ impl super::Context { }, extent: crate::Extent::default(), }; - let mut surface = unsafe { + Ok(unsafe { super::Surface { platform, renderbuf: self.platform.glow.create_renderbuffer().unwrap(), framebuf: self.platform.glow.create_framebuffer().unwrap(), } - }; - self.reconfigure_surface(&mut surface, config); - Ok(surface) + }) } + pub fn destroy_surface(&self, _surface: &mut super::Surface) {} + pub fn reconfigure_surface(&self, surface: &mut super::Surface, config: crate::SurfaceConfig) { //TODO: create WebGL context here let format_desc = super::describe_texture_format(surface.platform.info.format); @@ -146,8 +145,6 @@ impl super::Context { surface.platform.extent = config.size; } - pub fn destroy_surface(&self, _surface: &mut super::Surface) {} - /// Obtain a lock to the EGL context and get handle to the [`glow::Context`] that can be used to /// do rendering. pub(super) fn lock(&self) -> &glow::Context { diff --git a/blade-graphics/src/lib.rs b/blade-graphics/src/lib.rs index d7bc0e3..d8470a1 100644 --- a/blade-graphics/src/lib.rs +++ b/blade-graphics/src/lib.rs @@ -137,6 +137,20 @@ pub struct DeviceInformation { pub driver_info: String, } +impl Context { + pub fn create_surface_configured< + I: raw_window_handle::HasWindowHandle + raw_window_handle::HasDisplayHandle, + >( + &self, + window: &I, + config: SurfaceConfig, + ) -> Result { + let mut surface = self.create_surface(window)?; + self.reconfigure_surface(&mut surface, config); + Ok(surface) + } +} + #[derive(Clone, Copy, Debug, PartialEq)] pub enum Memory { /// Device-local memory. Fast for GPU operations. diff --git a/blade-graphics/src/metal/surface.rs b/blade-graphics/src/metal/surface.rs index 38dbc6c..90e75e3 100644 --- a/blade-graphics/src/metal/surface.rs +++ b/blade-graphics/src/metal/surface.rs @@ -82,14 +82,11 @@ impl super::Surface { } impl super::Context { - pub fn create_surface< - I: raw_window_handle::HasWindowHandle + raw_window_handle::HasDisplayHandle, - >( + pub fn create_surface( &self, window: &I, - config: crate::SurfaceConfig, ) -> Result { - let mut surface = match window.window_handle().unwrap().as_raw() { + Ok(match window.window_handle().unwrap().as_raw() { #[cfg(target_os = "ios")] raw_window_handle::RawWindowHandle::UiKit(handle) => unsafe { super::Surface::from_view(handle.ui_view.as_ptr() as *mut _) @@ -99,9 +96,14 @@ impl super::Context { super::Surface::from_view(handle.ns_view.as_ptr() as *mut _) }, _ => return Err(crate::NotSupportedError::PlatformNotSupported), - }; - self.reconfigure_surface(&mut surface, config); - Ok(surface) + }) + } + + pub fn destroy_surface(&self, surface: &mut super::Surface) { + unsafe { + let () = msg_send![surface.view, release]; + } + surface.view = ptr::null_mut(); } pub fn reconfigure_surface(&self, surface: &mut super::Surface, config: crate::SurfaceConfig) { @@ -141,11 +143,4 @@ impl super::Context { let () = msg_send![surface.render_layer, setDisplaySyncEnabled: vsync]; } } - - pub fn destroy_surface(&self, surface: &mut super::Surface) { - unsafe { - let () = msg_send![surface.view, release]; - } - surface.view = ptr::null_mut(); - } } diff --git a/blade-graphics/src/vulkan/surface.rs b/blade-graphics/src/vulkan/surface.rs index 384950a..c94f03c 100644 --- a/blade-graphics/src/vulkan/surface.rs +++ b/blade-graphics/src/vulkan/surface.rs @@ -58,7 +58,6 @@ impl super::Context { >( &self, window: &I, - config: crate::SurfaceConfig, ) -> Result { let khr_swapchain = self .device @@ -119,7 +118,7 @@ impl super::Context { .unwrap() }; - let mut this = super::Surface { + Ok(super::Surface { device: khr_swapchain, raw, frames: Vec::new(), @@ -131,9 +130,7 @@ impl super::Context { target_size: [0; 2], }, _full_screen_exclusive: fullscreen_exclusive_ext.full_screen_exclusive_supported != 0, - }; - self.reconfigure_surface(&mut this, config); - Ok(this) + }) } pub fn destroy_surface(&self, surface: &mut super::Surface) { diff --git a/examples/bunnymark/main.rs b/examples/bunnymark/main.rs index 0191014..b14c2fe 100644 --- a/examples/bunnymark/main.rs +++ b/examples/bunnymark/main.rs @@ -90,7 +90,7 @@ impl Example { let window_size = window.inner_size(); let surface = context - .create_surface(window, Self::make_surface_config(window_size)) + .create_surface_configured(window, Self::make_surface_config(window_size)) .unwrap(); let global_layout = ::layout(); diff --git a/examples/particle/main.rs b/examples/particle/main.rs index 936c377..e836f82 100644 --- a/examples/particle/main.rs +++ b/examples/particle/main.rs @@ -36,7 +36,9 @@ impl Example { display_sync: gpu::DisplaySync::Block, ..Default::default() }; - let surface = context.create_surface(window, surface_config).unwrap(); + let surface = context + .create_surface_configured(window, surface_config) + .unwrap(); let surface_info = surface.info(); let gui_painter = blade_egui::GuiPainter::new(surface_info, &context); diff --git a/examples/ray-query/main.rs b/examples/ray-query/main.rs index b6eb83e..3fab8f2 100644 --- a/examples/ray-query/main.rs +++ b/examples/ray-query/main.rs @@ -71,7 +71,9 @@ impl Example { transparent: true, ..Default::default() }; - let surface = context.create_surface(window, surface_config).unwrap(); + let surface = context + .create_surface_configured(window, surface_config) + .unwrap(); let target = context.create_texture(gpu::TextureDesc { name: "main", diff --git a/examples/scene/main.rs b/examples/scene/main.rs index 16440b3..ddae495 100644 --- a/examples/scene/main.rs +++ b/examples/scene/main.rs @@ -195,7 +195,9 @@ impl Example { let surface_config = Self::make_surface_config(window.inner_size()); let surface_size = surface_config.size; - let surface = context.create_surface(window, surface_config).unwrap(); + let surface = context + .create_surface_configured(window, surface_config) + .unwrap(); let surface_info = surface.info(); let num_workers = num_cpus::get_physical().max((num_cpus::get() * 3 + 2) / 4); diff --git a/src/lib.rs b/src/lib.rs index c42ffc2..3ae92c3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -424,7 +424,9 @@ impl Engine { let surface_config = Self::make_surface_config(window.inner_size()); let surface_size = surface_config.size; - let gpu_surface = gpu_context.create_surface(window, surface_config).unwrap(); + let gpu_surface = gpu_context + .create_surface_configured(window, surface_config) + .unwrap(); let surface_info = gpu_surface.info(); let num_workers = num_cpus::get_physical().max((num_cpus::get() * 3 + 2) / 4);