diff --git a/crates/gpui/src/platform/windows/directx_renderer.rs b/crates/gpui/src/platform/windows/directx_renderer.rs index c9f2add7a2..72c2cb5d42 100644 --- a/crates/gpui/src/platform/windows/directx_renderer.rs +++ b/crates/gpui/src/platform/windows/directx_renderer.rs @@ -27,8 +27,8 @@ const MULTISAMPLE_COUNT: u32 = 4; pub(crate) struct DirectXRenderer { hwnd: HWND, atlas: Arc, - devices: DirectXDevices, - resources: DirectXResources, + devices: ManuallyDrop, + resources: ManuallyDrop, globals: DirectXGlobalElements, pipelines: DirectXRenderPipelines, #[cfg(not(feature = "enable-renderdoc"))] @@ -115,16 +115,14 @@ impl DirectXDevices { } impl DirectXRenderer { - pub(crate) fn new(devices: &DirectXDevices, hwnd: HWND) -> Result { - let atlas = Arc::new(DirectXAtlas::new( - devices.device.clone(), - devices.device_context.clone(), - )); + pub(crate) fn new(hwnd: HWND) -> Result { + let devices = ManuallyDrop::new(DirectXDevices::new().context("Creating DirectX devices")?); + let atlas = Arc::new(DirectXAtlas::new(&devices.device, &devices.device_context)); #[cfg(not(feature = "enable-renderdoc"))] - let resources = DirectXResources::new(devices).unwrap(); + let resources = DirectXResources::new(&devices, 1, 1).unwrap(); #[cfg(feature = "enable-renderdoc")] - let resources = DirectXResources::new(devices, hwnd)?; + let resources = DirectXResources::new(&devices, hwnd)?; let globals = DirectXGlobalElements::new(&devices.device).unwrap(); let pipelines = DirectXRenderPipelines::new(&devices.device).unwrap(); @@ -139,7 +137,7 @@ impl DirectXRenderer { Ok(DirectXRenderer { hwnd, atlas, - devices: devices.clone(), + devices, resources, globals, pipelines, @@ -212,17 +210,29 @@ impl DirectXRenderer { } fn handle_device_lost(&mut self) -> Result<()> { - let devices = DirectXDevices::new().context("Recreating DirectX devices")?; - #[cfg(not(feature = "enable-renderdoc"))] unsafe { + ManuallyDrop::drop(&mut self.devices); + ManuallyDrop::drop(&mut self.resources); + #[cfg(not(feature = "enable-renderdoc"))] ManuallyDrop::drop(&mut self._direct_composition); } - self.atlas - .handle_device_lost(devices.device.clone(), devices.device_context.clone()); + let devices = + ManuallyDrop::new(DirectXDevices::new().context("Recreating DirectX devices")?); + unsafe { + devices.device_context.OMSetRenderTargets(None, None); + devices.device_context.ClearState(); + devices.device_context.Flush(); + } #[cfg(not(feature = "enable-renderdoc"))] - let resources = DirectXResources::new(&devices).unwrap(); + let resources = + DirectXResources::new(&devices, self.resources.width, self.resources.height).unwrap(); #[cfg(feature = "enable-renderdoc")] - let resources = DirectXResources::new(&devices, self.hwnd)?; + let resources = DirectXResources::new( + &devices, + self.resources.width, + self.resources.height, + self.hwnd, + )?; let globals = DirectXGlobalElements::new(&devices.device).unwrap(); let pipelines = DirectXRenderPipelines::new(&devices.device).unwrap(); @@ -233,6 +243,8 @@ impl DirectXRenderer { .set_swap_chain(&resources.swap_chain) .unwrap(); + self.atlas + .handle_device_lost(&devices.device, &devices.device_context); self.devices = devices; self.resources = resources; self.globals = globals; @@ -505,11 +517,10 @@ impl DirectXRenderer { impl DirectXResources { pub fn new( devices: &DirectXDevices, + width: u32, + height: u32, #[cfg(feature = "enable-renderdoc")] hwnd: HWND, - ) -> Result { - let width = 1; - let height = 1; - + ) -> Result> { #[cfg(not(feature = "enable-renderdoc"))] let swap_chain = create_swap_chain(&devices.dxgi_factory, &devices.device, width, height)?; #[cfg(feature = "enable-renderdoc")] @@ -520,7 +531,7 @@ impl DirectXResources { create_resources(devices, &swap_chain, width, height)?; set_rasterizer_state(&devices.device, &devices.device_context)?; - Ok(Self { + Ok(ManuallyDrop::new(Self { swap_chain, render_target, render_target_view, @@ -529,7 +540,7 @@ impl DirectXResources { width, height, viewport, - }) + })) } #[inline] @@ -978,10 +989,12 @@ struct PathSprite { color: Background, } -#[cfg(not(feature = "enable-renderdoc"))] impl Drop for DirectXRenderer { fn drop(&mut self) { unsafe { + ManuallyDrop::drop(&mut self.devices); + ManuallyDrop::drop(&mut self.resources); + #[cfg(not(feature = "enable-renderdoc"))] ManuallyDrop::drop(&mut self._direct_composition); } } diff --git a/crates/gpui/src/platform/windows/platform.rs b/crates/gpui/src/platform/windows/platform.rs index c7ba58b3af..d86305bd30 100644 --- a/crates/gpui/src/platform/windows/platform.rs +++ b/crates/gpui/src/platform/windows/platform.rs @@ -34,7 +34,6 @@ pub(crate) struct WindowsPlatform { state: RefCell, raw_window_handles: RwLock>, // The below members will never change throughout the entire lifecycle of the app. - directx_devices: DirectXDevices, icon: HICON, main_receiver: flume::Receiver, background_executor: BackgroundExecutor, @@ -111,13 +110,11 @@ impl WindowsPlatform { let icon = load_icon().unwrap_or_default(); let state = RefCell::new(WindowsPlatformState::new()); let raw_window_handles = RwLock::new(SmallVec::new()); - let directx_devices = DirectXDevices::new().context("Unable to init directx devices.")?; let windows_version = WindowsVersion::new().context("Error retrieve windows version")?; Ok(Self { state, raw_window_handles, - directx_devices, icon, main_receiver, background_executor, @@ -455,13 +452,8 @@ impl Platform for WindowsPlatform { handle: AnyWindowHandle, options: WindowParams, ) -> Result> { - let window = WindowsWindow::new( - handle, - options, - self.generate_creation_info(), - &self.directx_devices, - ) - .inspect_err(|err| show_error("Failed to open new window", err.to_string()))?; + let window = WindowsWindow::new(handle, options, self.generate_creation_info()) + .inspect_err(|err| show_error("Failed to open new window", err.to_string()))?; let handle = window.get_raw_handle(); self.raw_window_handles.write().push(handle); diff --git a/crates/gpui/src/platform/windows/window.rs b/crates/gpui/src/platform/windows/window.rs index eda75956b6..159cb6d95f 100644 --- a/crates/gpui/src/platform/windows/window.rs +++ b/crates/gpui/src/platform/windows/window.rs @@ -82,7 +82,6 @@ impl WindowsWindowState { cs: &CREATESTRUCTW, current_cursor: Option, display: WindowsDisplay, - gpu_context: &DirectXDevices, min_size: Option>, appearance: WindowAppearance, ) -> Result { @@ -101,7 +100,7 @@ impl WindowsWindowState { }; let border_offset = WindowBorderOffset::default(); let restore_from_minimized = None; - let renderer = DirectXRenderer::new(gpu_context, hwnd)?; + let renderer = DirectXRenderer::new(hwnd)?; let callbacks = Callbacks::default(); let input_handler = None; let pending_surrogate = None; @@ -207,7 +206,6 @@ impl WindowsWindowStatePtr { cs, context.current_cursor, context.display, - context.gpu_context, context.min_size, context.appearance, )?); @@ -326,7 +324,7 @@ pub(crate) struct Callbacks { pub(crate) appearance_changed: Option>, } -struct WindowCreateContext<'a> { +struct WindowCreateContext { inner: Option>>, handle: AnyWindowHandle, hide_title_bar: bool, @@ -339,7 +337,6 @@ struct WindowCreateContext<'a> { drop_target_helper: IDropTargetHelper, validation_number: usize, main_receiver: flume::Receiver, - gpu_context: &'a DirectXDevices, main_thread_id_win32: u32, appearance: WindowAppearance, } @@ -349,7 +346,6 @@ impl WindowsWindow { handle: AnyWindowHandle, params: WindowParams, creation_info: WindowCreationInfo, - gpu_context: &DirectXDevices, ) -> Result { let WindowCreationInfo { icon, @@ -408,7 +404,6 @@ impl WindowsWindow { drop_target_helper, validation_number, main_receiver, - gpu_context, main_thread_id_win32, appearance, };