From 5216253998cadc29b0933ac4f30a8101b423941a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 24 Oct 2025 18:14:29 +0200 Subject: [PATCH] Fall back to synchronous rendering on Wasm --- src/application.rs | 11 +++++++++-- wgpu/src/image/cache.rs | 25 ++++++++++++++++--------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/application.rs b/src/application.rs index 143dfcc4..f007e9dc 100644 --- a/src/application.rs +++ b/src/application.rs @@ -198,10 +198,17 @@ impl Application

{ #[cfg(feature = "tester")] let program = iced_tester::attach(self); - #[cfg(all(feature = "debug", not(feature = "tester")))] + #[cfg(all( + feature = "debug", + not(feature = "tester"), + not(target_arch = "wasm32") + ))] let program = iced_devtools::attach(self); - #[cfg(not(any(feature = "tester", feature = "debug")))] + #[cfg(not(any( + feature = "tester", + all(feature = "debug", not(target_arch = "wasm32")) + )))] let program = self; Ok(shell::run(program)?) diff --git a/wgpu/src/image/cache.rs b/wgpu/src/image/cache.rs index 795800b8..858c6b4c 100644 --- a/wgpu/src/image/cache.rs +++ b/wgpu/src/image/cache.rs @@ -17,7 +17,7 @@ pub struct Cache { jobs: mpsc::SyncSender, #[cfg(feature = "image")] work: mpsc::Receiver, - #[cfg(feature = "image")] + #[cfg(all(feature = "image", not(target_arch = "wasm32")))] worker_: Option>, } @@ -29,11 +29,14 @@ impl Cache { layout: wgpu::BindGroupLayout, shell: &Shell, ) -> Self { - #[cfg(feature = "image")] + #[cfg(all(feature = "image", not(target_arch = "wasm32")))] let (worker, jobs, work) = Worker::new(device, queue, backend, layout.clone(), shell); - #[cfg(feature = "image")] + #[cfg(all(feature = "image", target_arch = "wasm32"))] + let (jobs, work) = (mpsc::sync_channel(0).0, mpsc::sync_channel(0).1); + + #[cfg(all(feature = "image", not(target_arch = "wasm32")))] let handle = thread::spawn(move || worker.run()); Self { @@ -50,7 +53,7 @@ impl Cache { jobs, #[cfg(feature = "image")] work, - #[cfg(feature = "image")] + #[cfg(all(feature = "image", not(target_arch = "wasm32")))] worker_: Some(handle), } } @@ -107,7 +110,8 @@ impl Cache { const MAX_SYNC_SIZE: usize = 2 * 1024 * 1024; - if image.len() < MAX_SYNC_SIZE { + // TODO: Concurrent Wasm support + if image.len() < MAX_SYNC_SIZE || cfg!(target_arch = "wasm32") { let entry = self.atlas.upload( device, encoder, @@ -205,7 +209,7 @@ impl Cache { } } -#[cfg(feature = "image")] +#[cfg(all(feature = "image", not(target_arch = "wasm32")))] impl Drop for Cache { fn drop(&mut self) { // Stop worker gracefully @@ -235,8 +239,11 @@ fn load_image<'a>( use crate::image::raster::Memory; if !cache.contains(handle) { - // Load RGBA handles synchronously, since it's very cheap - if let core::image::Handle::Rgba { .. } = handle { + if cfg!(target_arch = "wasm32") { + // TODO: Concurrent support for Wasm + cache.insert(handle, Memory::load(handle)); + } else if let core::image::Handle::Rgba { .. } = handle { + // Load RGBA handles synchronously, since it's very cheap cache.insert(handle, Memory::load(handle)); } else { let _ = jobs.send(Job::Load(handle.clone())); @@ -284,7 +291,7 @@ struct Worker { output: mpsc::SyncSender, } -#[cfg(feature = "image")] +#[cfg(all(feature = "image", not(target_arch = "wasm32")))] impl Worker { fn new( device: &wgpu::Device,