diff --git a/Cargo.lock b/Cargo.lock index f76d4d520d..8a7d512b83 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12344,18 +12344,18 @@ dependencies = [ [[package]] name = "profiling" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d" +checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773" dependencies = [ "profiling-procmacros", ] [[package]] name = "profiling-procmacros" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30" +checksum = "52717f9a02b6965224f95ca2a81e2e0c5c43baacd28ca057577988930b6c3d5b" dependencies = [ "quote", "syn 2.0.101", diff --git a/Cargo.toml b/Cargo.toml index 9a05d89e53..0ad7a8e5ed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -537,7 +537,7 @@ portable-pty = "0.9.0" postage = { version = "0.5", features = ["futures-traits"] } pretty_assertions = { version = "1.3.0", features = ["unstable"] } proc-macro2 = "1.0.93" -profiling = "1" +profiling = "1.0.17" prost = "0.9" prost-build = "0.9" prost-types = "0.9" diff --git a/crates/gpui/src/platform/windows/directx_renderer.rs b/crates/gpui/src/platform/windows/directx_renderer.rs index 768ca7fc22..0823bf17e0 100644 --- a/crates/gpui/src/platform/windows/directx_renderer.rs +++ b/crates/gpui/src/platform/windows/directx_renderer.rs @@ -286,6 +286,7 @@ impl DirectXRenderer { Ok(()) } + #[profiling::function] pub(crate) fn draw(&mut self, scene: &Scene) -> Result<()> { self.pre_draw()?; for batch in scene.batches() { diff --git a/crates/gpui/src/platform/windows/events.rs b/crates/gpui/src/platform/windows/events.rs index fcdc16b93f..ad211b827f 100644 --- a/crates/gpui/src/platform/windows/events.rs +++ b/crates/gpui/src/platform/windows/events.rs @@ -238,6 +238,7 @@ fn handle_timer_msg( } } +#[profiling::function] fn handle_paint_msg(handle: HWND, state_ptr: Rc) -> Option { draw_window(handle, false, state_ptr) } @@ -373,6 +374,7 @@ fn handle_syskeyup_msg( // It's a known bug that you can't trigger `ctrl-shift-0`. See: // https://superuser.com/questions/1455762/ctrl-shift-number-key-combination-has-stopped-working-for-a-few-numbers +#[profiling::function] fn handle_keydown_msg( handle: HWND, wparam: WPARAM, @@ -1302,6 +1304,7 @@ fn translate_message(handle: HWND, wparam: WPARAM, lparam: LPARAM) { unsafe { TranslateMessage(&msg).ok().log_err() }; } +#[profiling::function] fn handle_key_event( handle: HWND, wparam: WPARAM, diff --git a/crates/gpui/src/platform/windows/platform.rs b/crates/gpui/src/platform/windows/platform.rs index a1d052496a..5dfa631189 100644 --- a/crates/gpui/src/platform/windows/platform.rs +++ b/crates/gpui/src/platform/windows/platform.rs @@ -14,19 +14,20 @@ use itertools::Itertools; use parking_lot::RwLock; use smallvec::SmallVec; use windows::{ - UI::ViewManagement::UISettings, - Win32::{ + core::*, Win32::{ Foundation::*, Graphics::{ DirectComposition::DCompositionWaitForCompositorClock, + Dxgi::{ + CreateDXGIFactory2, IDXGIAdapter1, IDXGIFactory6, IDXGIOutput, DXGI_CREATE_FACTORY_FLAGS, DXGI_GPU_PREFERENCE_MINIMUM_POWER + }, Gdi::*, Imaging::{CLSID_WICImagingFactory, IWICImagingFactory}, }, Security::Credentials::*, System::{Com::*, LibraryLoader::*, Ole::*, SystemInformation::*, Threading::*}, UI::{Input::KeyboardAndMouse::*, Shell::*, WindowsAndMessaging::*}, - }, - core::*, + }, UI::ViewManagement::UISettings }; use crate::*; @@ -132,9 +133,11 @@ impl WindowsPlatform { fn begin_vsync_thread(&self) { let raw_window_handles = self.raw_window_handles.clone(); std::thread::spawn(move || { + let vsync_provider = VSyncProvider::new(); loop { unsafe { - DCompositionWaitForCompositorClock(None, INFINITE); + // DCompositionWaitForCompositorClock(None, INFINITE); + vsync_provider.wait_for_vsync(); for handle in raw_window_handles.read().iter() { RedrawWindow(Some(**handle), None, None, RDW_INVALIDATE) .ok() @@ -743,6 +746,46 @@ pub(crate) struct WindowCreationInfo { pub(crate) main_thread_id_win32: u32, } +struct VSyncProvider { + dxgi_output: IDXGIOutput, +} + +impl VSyncProvider { + fn new() -> Self { + let dxgi_factory: IDXGIFactory6 = + unsafe { CreateDXGIFactory2(DXGI_CREATE_FACTORY_FLAGS::default()) }.unwrap(); + let adapter: IDXGIAdapter1 = get_adapter(&dxgi_factory); + unsafe { + let dxgi_output = adapter.EnumOutputs(0).unwrap(); + Self { dxgi_output } + } + } + + fn wait_for_vsync(&self) { + unsafe { + self.dxgi_output.WaitForVBlank().unwrap(); + } + } +} + +fn get_adapter(dxgi_factory: &IDXGIFactory6) -> IDXGIAdapter1 { + unsafe { + for index in 0.. { + let adapter = dxgi_factory + .EnumAdapterByGpuPreference(index, DXGI_GPU_PREFERENCE_MINIMUM_POWER) + .unwrap(); + return adapter; + } + } + unreachable!("No DXGI adapter found") +} + +impl Default for VSyncProvider { + fn default() -> Self { + Self::new() + } +} + fn open_target(target: &str) { unsafe { let ret = ShellExecuteW(