diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 0acb6e3..dfbc27d 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -542,6 +542,17 @@ pub fn run(cli_args: CliArgs) { initialize_core_logic(&app_handle); + // Pre-warm GPU/accelerator enumeration on a background thread. + // The first call into transcribe_rs::whisper_cpp::gpu::list_gpu_devices + // loads the Metal/Vulkan backend and probes devices, which can take + // several seconds. Without this, that cost is paid synchronously the + // first time the user opens the Advanced settings page (which calls + // the get_available_accelerators command), causing a UI freeze. + // Result is cached in a OnceLock inside the transcription manager. + std::thread::spawn(|| { + let _ = crate::managers::transcription::get_available_accelerators(); + }); + // Hide tray icon if --no-tray was passed if cli_args.no_tray { tray::set_tray_visibility(&app_handle, false); diff --git a/src-tauri/src/shortcut/mod.rs b/src-tauri/src/shortcut/mod.rs index 6d179f1..79e0766 100644 --- a/src-tauri/src/shortcut/mod.rs +++ b/src-tauri/src/shortcut/mod.rs @@ -1143,8 +1143,15 @@ pub fn change_whisper_gpu_device(app: AppHandle, device: i32) -> Result<(), Stri } /// Return which accelerators and GPU devices are available for this build. +/// +/// First-call cost is dominated by enumerating GPU devices through the +/// whisper.cpp Metal/Vulkan backend, which loads dynamic libraries and +/// probes hardware. Run it on the blocking pool so the webview thread +/// stays responsive — see also the startup pre-warm in `lib.rs`. #[tauri::command] #[specta::specta] -pub fn get_available_accelerators() -> crate::managers::transcription::AvailableAccelerators { - crate::managers::transcription::get_available_accelerators() +pub async fn get_available_accelerators() -> crate::managers::transcription::AvailableAccelerators { + tauri::async_runtime::spawn_blocking(crate::managers::transcription::get_available_accelerators) + .await + .expect("get_available_accelerators panicked") } diff --git a/src/bindings.ts b/src/bindings.ts index 378d630..476c411 100644 --- a/src/bindings.ts +++ b/src/bindings.ts @@ -389,6 +389,11 @@ async changeWhisperGpuDevice(device: number) : Promise> { }, /** * Return which accelerators and GPU devices are available for this build. + * + * First-call cost is dominated by enumerating GPU devices through the + * whisper.cpp Metal/Vulkan backend, which loads dynamic libraries and + * probes hardware. Run it on the blocking pool so the webview thread + * stays responsive — see also the startup pre-warm in `lib.rs`. */ async getAvailableAccelerators() : Promise { return await TAURI_INVOKE("get_available_accelerators");