iced-rs/iced · error
Create pixel map
Error message
Create pixel map
What it means
Every frame, present() views the softbuffer backbuffer as a tiny_skia::PixmapMut via PixmapMut::from_bytes(buffer, width, height), which returns None when the byte length does not equal width*height*4. The buffer length is fixed by the last successful resize(), while physical_size comes from the current Viewport; any drift between the configured surface size and the viewport at present time breaks the invariant and this expect panics.
Solutions
- Ensure configure_surface runs for every physical-size or scale change before the next present (keep surface_version in sync like iced_winit does)
- In a custom runtime, compare viewport.physical_size() with the size passed to the last resize() and reconfigure on mismatch before presenting
- Patch iced to propagate the failure as compositor::SurfaceError::Lost instead of panicking so the runtime recreates the surface
Example fix
// before (iced internals)
let mut pixels = tiny_skia::PixmapMut::from_bytes(
bytemuck::cast_slice_mut(&mut buffer), physical_size.width, physical_size.height,
).expect("Create pixel map");
// after
let mut pixels = tiny_skia::PixmapMut::from_bytes(
bytemuck::cast_slice_mut(&mut buffer), physical_size.width, physical_size.height,
).ok_or(compositor::SurfaceError::Lost)?; Defensive patterns
Strategy: validation
Validate before calling
// In a custom runtime: reconfigure whenever the viewport drifts from the
// size the softbuffer surface was last resized to.
let physical = viewport.physical_size();
if physical != last_configured_size {
compositor.configure_surface(&mut surface, physical.width, physical.height);
last_configured_size = physical;
}
compositor.present(&mut renderer, &mut surface, &viewport, background, || {})?; Prevention
- Handle every Resized and ScaleFactorChanged event by reconfiguring before the next redraw, like iced_winit's surface_version tracking does
- Treat scale-factor changes as resizes: the physical buffer length changes even when the logical size does not
When it happens
Trigger: A window resize or scale-factor change that lands between the runtime's configure_surface and the next present (surface_version bookkeeping missed an update); calling present() with a Viewport newer than the surface configuration; multi-window code presenting to a surface resized by another event path.
Common situations: Rapid interactive resizing; dragging a window between monitors with different scale factors; tiling window managers emitting resize bursts; custom runtimes that update the viewport but forget to reconfigure the surface.
Related errors
- Non-zero height
- Non-zero width
- Create softbuffer context
- Create softbuffer surface for window
- Create clip mask
AI-assisted analysis of iced-rs/iced@3de451447b (2026-08-17).
Data as JSON: /api/errors/e4b4ed57ec894560.
Report an issue: GitHub.
Appendix: source
Thrown at tiny_skia/src/window/compositor.rs:190
if damage.is_empty() {
if let Some(last_frame) = last_frame {
surface.frames.push_front(last_frame.clone());
}
} else {
surface.frames.push_front(Frame {
background,
layers: renderer.layers().to_vec(),
});
let damage = damage::group(damage, Rectangle::with_size(viewport.logical_size()));
let mut pixels = tiny_skia::PixmapMut::from_bytes(
bytemuck::cast_slice_mut(&mut buffer),
physical_size.width,
physical_size.height,
)
.expect("Create pixel map");
renderer.draw(
&mut pixels,
&mut surface.clip_mask,
viewport,
&damage,
background,
);
}
on_pre_present();
buffer.present().map_err(|_| compositor::SurfaceError::Lost)
}
pub fn screenshot(
renderer: &mut Renderer,
viewport: &Viewport,
background_color: Color,View on GitHub (pinned to 3de451447b)