From 64fe580e9a6cd32848d67d096ecf1041edb282ca Mon Sep 17 00:00:00 2001 From: Raph Levien Date: Thu, 20 Aug 2020 13:28:40 -0700 Subject: [PATCH] Use a simpler approach to creating D2D contexts Always use a DXGI swapchain. This iS WIP, pushing for experimentation. --- druid-shell/src/platform/windows/util.rs | 9 ++++++ druid-shell/src/platform/windows/window.rs | 34 ++++++++++------------ 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/druid-shell/src/platform/windows/util.rs b/druid-shell/src/platform/windows/util.rs index 9b0237755e..e91d12d42b 100644 --- a/druid-shell/src/platform/windows/util.rs +++ b/druid-shell/src/platform/windows/util.rs @@ -138,6 +138,8 @@ type DCompositionCreateDevice2 = unsafe extern "system" fn( iid: REFIID, dcompositionDevice: *mut *mut c_void, ) -> HRESULT; +type CreateDXGIFactory1 = + unsafe extern "system" fn(riid: REFIID, ppFactory: *mut *mut c_void) -> HRESULT; type CreateDXGIFactory2 = unsafe extern "system" fn(Flags: UINT, riid: REFIID, ppFactory: *mut *mut c_void) -> HRESULT; @@ -147,6 +149,7 @@ pub struct OptionalFunctions { pub GetDpiForMonitor: Option, pub SetProcessDpiAwareness: Option, pub DCompositionCreateDevice2: Option, + pub CreateDXGIFactory1: Option, pub CreateDXGIFactory2: Option, } @@ -200,6 +203,7 @@ fn load_optional_functions() -> OptionalFunctions { let mut GetDpiForMonitor = None; let mut SetProcessDpiAwareness = None; let mut DCompositionCreateDevice2 = None; + let mut CreateDXGIFactory1 = None; let mut CreateDXGIFactory2 = None; if shcore.is_null() { @@ -219,6 +223,10 @@ fn load_optional_functions() -> OptionalFunctions { load_function!(dcomp, DCompositionCreateDevice2, "8.1"); } + if !dxgi.is_null() { + load_function!(dxgi, CreateDXGIFactory1, "7.0"); + } + if !dxgi.is_null() { load_function!(dxgi, CreateDXGIFactory2, "8.1"); } @@ -228,6 +236,7 @@ fn load_optional_functions() -> OptionalFunctions { GetDpiForMonitor, SetProcessDpiAwareness, DCompositionCreateDevice2, + CreateDXGIFactory1, CreateDXGIFactory2, } } diff --git a/druid-shell/src/platform/windows/window.rs b/druid-shell/src/platform/windows/window.rs index 82e6c4df66..f31e9f38a3 100644 --- a/druid-shell/src/platform/windows/window.rs +++ b/druid-shell/src/platform/windows/window.rs @@ -190,9 +190,6 @@ struct WndState { /// on 8.1 and up. struct DCompState { swap_chain: *mut IDXGISwapChain1, - dcomp_device: DCompositionDevice, - dcomp_target: DCompositionTarget, - swapchain_visual: DCompositionVisual, // True if in a drag-resizing gesture (at which point the swapchain is disabled) sizing: bool, } @@ -216,7 +213,7 @@ impl Default for PresentStrategy { fn default() -> PresentStrategy { // We probably want to change this, but we need GDI to work. Too bad about // the artifacty resizing. - PresentStrategy::FlipRedirect + PresentStrategy::Sequential } } @@ -445,7 +442,7 @@ impl WndProc for MyWndProc { }; if !ds.sizing { (*ds.swap_chain).Present1(1, 0, ¶ms); - let _ = ds.dcomp_device.commit(); + //let _ = ds.dcomp_device.commit(); } } ValidateRect(hwnd, null_mut()); @@ -454,6 +451,7 @@ impl WndProc for MyWndProc { } Some(0) }, + /* WM_ENTERSIZEMOVE => unsafe { if let Ok(mut s) = self.state.try_borrow_mut() { let s = s.as_mut().unwrap(); @@ -471,11 +469,13 @@ impl WndProc for MyWndProc { ); } + /* if let Some(ref mut ds) = s.dcomp_state { let _ = ds.dcomp_target.clear_root(); let _ = ds.dcomp_device.commit(); ds.sizing = true; } + */ } } else { self.log_dropped_msg(hwnd, msg, wparam, lparam); @@ -513,17 +513,20 @@ impl WndProc for MyWndProc { // It might actually be better to create a new swapchain here. DwmFlush(); + /* if let Some(ref mut ds) = s.dcomp_state { let _ = ds.dcomp_target.set_root(&mut ds.swapchain_visual); let _ = ds.dcomp_device.commit(); ds.sizing = false; } + */ } } else { self.log_dropped_msg(hwnd, msg, wparam, lparam); } None }, + */ WM_SIZE => unsafe { if let Ok(mut s) = self.state.try_borrow_mut() { let s = s.as_mut().unwrap(); @@ -574,7 +577,7 @@ impl WndProc for MyWndProc { ); if let Some(ref mut dcomp_state) = s.dcomp_state { (*dcomp_state.swap_chain).Present(0, 0); - let _ = dcomp_state.dcomp_device.commit(); + //let _ = dcomp_state.dcomp_device.commit(); } ValidateRect(hwnd, null_mut()); } else { @@ -1064,10 +1067,9 @@ unsafe fn create_dcomp_state( if present_strategy == PresentStrategy::Hwnd { return Ok(None); } - if let Some(create_dxgi_factory2) = OPTIONAL_FUNCTIONS.CreateDXGIFactory2 { + if let Some(create_dxgi_factory1) = OPTIONAL_FUNCTIONS.CreateDXGIFactory1 { let mut factory: *mut IDXGIFactory2 = null_mut(); - as_result(create_dxgi_factory2( - 0, + as_result(create_dxgi_factory1( &IID_IDXGIFactory2, &mut factory as *mut *mut IDXGIFactory2 as *mut *mut c_void, ))?; @@ -1076,9 +1078,7 @@ unsafe fn create_dcomp_state( debug!("adapter = {:?}", adapter); let mut d3d11_device = D3D11Device::new_simple()?; - let mut d2d1_device = d3d11_device.create_d2d1_device()?; - let mut dcomp_device = d2d1_device.create_composition_device()?; - let mut dcomp_target = dcomp_device.create_target_for_hwnd(hwnd, true)?; + //let mut d2d1_device = d3d11_device.create_d2d1_device()?; let (swap_effect, bufs) = match present_strategy { PresentStrategy::Hwnd => unreachable!(), @@ -1104,22 +1104,18 @@ unsafe fn create_dcomp_state( Flags: 0, }; let mut swap_chain: *mut IDXGISwapChain1 = null_mut(); - let res = (*factory).CreateSwapChainForComposition( + let res = (*factory).CreateSwapChainForHwnd( d3d11_device.raw_ptr() as *mut IUnknown, + hwnd, &desc, null_mut(), + null_mut(), &mut swap_chain, ); debug!("swap chain res = 0x{:x}, pointer = {:?}", res, swap_chain); - let mut swapchain_visual = dcomp_device.create_visual()?; - swapchain_visual.set_content_raw(swap_chain as *mut IUnknown)?; - dcomp_target.set_root(&mut swapchain_visual)?; Ok(Some(DCompState { swap_chain, - dcomp_device, - dcomp_target, - swapchain_visual, sizing: false, })) } else {