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

  1. Ensure configure_surface runs for every physical-size or scale change before the next present (keep surface_version in sync like iced_winit does)
  2. In a custom runtime, compare viewport.physical_size() with the size passed to the last resize() and reconfigure on mismatch before presenting
  3. 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

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


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)