diff --git a/editor/src/node_graph_executor/runtime.rs b/editor/src/node_graph_executor/runtime.rs index 26102cda07..59c970d866 100644 --- a/editor/src/node_graph_executor/runtime.rs +++ b/editor/src/node_graph_executor/runtime.rs @@ -352,7 +352,7 @@ impl NodeRuntime { &executor.context.device, &vello::wgpu::SurfaceConfiguration { usage: vello::wgpu::TextureUsages::RENDER_ATTACHMENT | vello::wgpu::TextureUsages::COPY_DST, - format: vello::wgpu::TextureFormat::Rgba8Unorm, + format: surface.surface.format, width: physical_resolution.x, height: physical_resolution.y, present_mode: surface_caps.present_modes[0], @@ -365,21 +365,11 @@ impl NodeRuntime { let surface_texture = surface_inner.get_current_texture().expect("Failed to get surface texture"); self.current_viewport_texture = Some(image_texture.clone()); - encoder.copy_texture_to_texture( - vello::wgpu::TexelCopyTextureInfoBase { - texture: image_texture.texture.as_ref(), - mip_level: 0, - origin: Default::default(), - aspect: Default::default(), - }, - vello::wgpu::TexelCopyTextureInfoBase { - texture: &surface_texture.texture, - mip_level: 0, - origin: Default::default(), - aspect: Default::default(), - }, - image_texture.texture.size(), - ); + // Use the blitter to copy the texture to the surface, handling format conversion + // (e.g., Rgba8Unorm source to Bgra8Unorm surface on Firefox) + let source_view = image_texture.texture.create_view(&vello::wgpu::TextureViewDescriptor::default()); + let target_view = surface_texture.texture.create_view(&vello::wgpu::TextureViewDescriptor::default()); + surface.surface.blitter.copy(&executor.context.device, &mut encoder, &source_view, &target_view); executor.context.queue.submit([encoder.finish()]); surface_texture.present(); diff --git a/node-graph/libraries/wgpu-executor/src/lib.rs b/node-graph/libraries/wgpu-executor/src/lib.rs index e98869238d..8319daea8e 100644 --- a/node-graph/libraries/wgpu-executor/src/lib.rs +++ b/node-graph/libraries/wgpu-executor/src/lib.rs @@ -49,6 +49,7 @@ pub struct Surface { pub inner: wgpu::Surface<'static>, pub target_texture: Mutex>, pub blitter: TextureBlitter, + pub format: wgpu::TextureFormat, } #[derive(Clone, Debug)] @@ -173,13 +174,17 @@ impl WgpuExecutor { } pub fn create_surface_inner(&self, surface: wgpu::Surface<'static>, window_id: SurfaceId) -> Result> { - let blitter = TextureBlitter::new(&self.context.device, VELLO_SURFACE_FORMAT); + // Get the surface's preferred format (Firefox WebGL may prefer Bgra8Unorm, Chrome prefers Rgba8Unorm) + let surface_caps = surface.get_capabilities(&self.context.adapter); + let surface_format = surface_caps.formats.iter().copied().find(|f| f.is_srgb()).unwrap_or(surface_caps.formats[0]); + let blitter = TextureBlitter::new(&self.context.device, surface_format); Ok(SurfaceHandle { window_id, surface: Surface { inner: surface, target_texture: Mutex::new(None), blitter, + format: surface_format, }, }) }