iced-rs/iced · critical

Create softbuffer context

Error message

Create softbuffer context

What it means

`tiny_skia::window::compositor::new` creates a `softbuffer::Context` for the given display and panics via `expect("Create softbuffer context")` if context creation fails. Softbuffer cannot initialize its drawing context on the provided raw display/window handle, so the library treats it as fatal.

Solutions

  1. Ensure a valid display environment: set `DISPLAY`/`WAYLAND_DISPLAY` or run under Xvfb in CI/headless setups.
  2. Install required system libraries (libxcb, libxkbcommon, Mesa/llvmpipe) for your platform.
  3. Verify the raw display/window handle passed to iced is correct and matches the windowing backend in use.
  4. Try a different renderer backend (wgpu) if softbuffer is unavailable on the target platform.

Example fix

// CI/headless Linux
// before
cargo run
// after
Xvfb :99 &
export DISPLAY=:99
cargo run
Defensive patterns

Strategy: fallback

Validate before calling

// Check for a usable display before launching
if std::env::var("DISPLAY").is_err()
    && std::env::var("WAYLAND_DISPLAY").is_err()
{
    eprintln!("no display server available");
    std::process::exit(1);
}

Type guard

fn display_available() -> bool {
    std::env::var_os("WAYLAND_DISPLAY").is_some()
        || std::env::var_os("DISPLAY").is_some()
}

Try / catch

// Context creation panics; check env and catch at process boundary
let ok = std::panic::catch_unwind(|| iced::application(...).run());
if ok.is_err() { eprintln!("softbuffer context init failed"); }

Prevention

When it happens

Trigger: `Compositor::new(display)` (used when building the tiny_skia shell) with a display handle the platform backend cannot use — invalid raw window/display handle, unsupported platform, or failed graphics initialization (e.g. no usable X11/Wayland connection).

Common situations: Headless environments without a display server; missing X11/Wayland libraries on Linux (missing libxkbcommon, XCB); running on an unsupported/odd platform (e.g. unusual wasm targets); incompatible raw-handle types from custom display integration.

Related errors


AI-assisted analysis of iced-rs/iced@d146509d89 (2026-09-11). Data as JSON: /api/errors/9f52bd6cf7ac369f. Report an issue: GitHub.

Appendix: source

Thrown at tiny_skia/src/window/compositor.rs:128

            background_color,
            on_pre_present,
        )
    }

    fn screenshot(
        &mut self,
        renderer: &mut Self::Renderer,
        viewport: &Viewport,
        background_color: Color,
    ) -> Vec<u8> {
        screenshot(renderer, viewport, background_color)
    }
}

pub fn new(display: impl compositor::Display) -> Compositor {
    #[allow(unsafe_code)]
    let context =
        softbuffer::Context::new(Box::new(display) as _).expect("Create softbuffer context");

    Compositor { context }
}

pub fn present(
    renderer: &mut Renderer,
    surface: &mut Surface,
    viewport: &Viewport,
    background: Color,
    on_pre_present: impl FnOnce(),
) -> Result<(), compositor::SurfaceError> {
    let physical_size = viewport.physical_size();

    let mut buffer = surface
        .window
        .buffer_mut()
        .map_err(|_| compositor::SurfaceError::Lost)?;

View on GitHub (pinned to d146509d89)