2026-03-10 22:43:43 +00:00
|
|
|
// Non-Linux: DRM/KMS backend is unavailable; callers must use --winit.
|
feat(compositor): add weft-compositor crate
- Implement WeftCompositorState with all Wayland protocol globals:
compositor, xdg-shell, layer-shell, shm, dmabuf, output, presentation,
text-input, input-method, pointer-constraints, cursor-shape, seat.
- Implement process_input_event covering keyboard, pointer (relative +
absolute), axis, touch, and all gesture types (swipe, pinch, hold).
- Implement Winit backend with damage-tracked rendering loop and frame
callbacks.
- Add DRM/KMS backend skeleton: libseat session, udev device discovery,
calloop integration (rendering path deferred).
- Add infra/systemd/weft-compositor.service (Type=notify).
- Split CI into cross-platform and linux-only jobs.
- Exclude weft-compositor from Windows check scripts.
2026-03-10 19:56:35 +00:00
|
|
|
#[cfg(not(target_os = "linux"))]
|
|
|
|
|
pub fn run() -> anyhow::Result<()> {
|
|
|
|
|
anyhow::bail!("DRM/KMS backend requires Linux; pass --winit for development on other platforms")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(target_os = "linux")]
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
use std::{collections::HashMap, path::Path, sync::Arc, time::Duration};
|
|
|
|
|
|
|
|
|
|
#[cfg(target_os = "linux")]
|
|
|
|
|
use anyhow::Context;
|
feat(compositor): add weft-compositor crate
- Implement WeftCompositorState with all Wayland protocol globals:
compositor, xdg-shell, layer-shell, shm, dmabuf, output, presentation,
text-input, input-method, pointer-constraints, cursor-shape, seat.
- Implement process_input_event covering keyboard, pointer (relative +
absolute), axis, touch, and all gesture types (swipe, pinch, hold).
- Implement Winit backend with damage-tracked rendering loop and frame
callbacks.
- Add DRM/KMS backend skeleton: libseat session, udev device discovery,
calloop integration (rendering path deferred).
- Add infra/systemd/weft-compositor.service (Type=notify).
- Split CI into cross-platform and linux-only jobs.
- Exclude weft-compositor from Windows check scripts.
2026-03-10 19:56:35 +00:00
|
|
|
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
#[cfg(target_os = "linux")]
|
|
|
|
|
use smithay::{
|
|
|
|
|
backend::{
|
|
|
|
|
allocator::{
|
2026-03-10 22:43:43 +00:00
|
|
|
Fourcc, Modifier,
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
format::FormatSet,
|
|
|
|
|
gbm::{GbmAllocator, GbmBufferFlags, GbmDevice},
|
feat(compositor): add weft-compositor crate
- Implement WeftCompositorState with all Wayland protocol globals:
compositor, xdg-shell, layer-shell, shm, dmabuf, output, presentation,
text-input, input-method, pointer-constraints, cursor-shape, seat.
- Implement process_input_event covering keyboard, pointer (relative +
absolute), axis, touch, and all gesture types (swipe, pinch, hold).
- Implement Winit backend with damage-tracked rendering loop and frame
callbacks.
- Add DRM/KMS backend skeleton: libseat session, udev device discovery,
calloop integration (rendering path deferred).
- Add infra/systemd/weft-compositor.service (Type=notify).
- Split CI into cross-platform and linux-only jobs.
- Exclude weft-compositor from Windows check scripts.
2026-03-10 19:56:35 +00:00
|
|
|
},
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
drm::{
|
2026-03-10 22:43:43 +00:00
|
|
|
DrmDevice, DrmDeviceFd, DrmEvent, DrmNode, NodeType,
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
compositor::FrameFlags,
|
|
|
|
|
exporter::gbm::GbmFramebufferExporter,
|
|
|
|
|
output::{DrmOutputManager, DrmOutputRenderElements},
|
|
|
|
|
},
|
|
|
|
|
egl::{EGLDevice, EGLDisplay},
|
|
|
|
|
input::InputEvent,
|
|
|
|
|
libinput::{LibinputInputBackend, LibinputSessionInterface},
|
|
|
|
|
renderer::{
|
|
|
|
|
element::surface::WaylandSurfaceRenderElement,
|
|
|
|
|
gles::GlesRenderer,
|
2026-03-10 22:43:43 +00:00
|
|
|
multigpu::{GpuManager, MultiRenderer, gbm::GbmGlesBackend},
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
},
|
2026-03-10 22:43:43 +00:00
|
|
|
session::{Event as SessionEvent, Session, libseat::LibSeatSession},
|
|
|
|
|
udev::{UdevBackend, UdevEvent, all_gpus, primary_gpu},
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
},
|
|
|
|
|
output::{Mode as WlMode, Output, PhysicalProperties, Subpixel},
|
|
|
|
|
reexports::{
|
|
|
|
|
calloop::{EventLoop, Interest, Mode, PostAction, generic::Generic},
|
2026-03-10 22:43:43 +00:00
|
|
|
drm::control::{ModeTypeFlags, connector, crtc},
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
input::{DeviceCapability, Libinput},
|
|
|
|
|
rustix::fs::OFlags,
|
|
|
|
|
wayland_server::Display,
|
|
|
|
|
},
|
|
|
|
|
utils::{DeviceFd, Transform},
|
|
|
|
|
wayland::socket::ListeningSocketSource,
|
|
|
|
|
};
|
feat(compositor): add weft-compositor crate
- Implement WeftCompositorState with all Wayland protocol globals:
compositor, xdg-shell, layer-shell, shm, dmabuf, output, presentation,
text-input, input-method, pointer-constraints, cursor-shape, seat.
- Implement process_input_event covering keyboard, pointer (relative +
absolute), axis, touch, and all gesture types (swipe, pinch, hold).
- Implement Winit backend with damage-tracked rendering loop and frame
callbacks.
- Add DRM/KMS backend skeleton: libseat session, udev device discovery,
calloop integration (rendering path deferred).
- Add infra/systemd/weft-compositor.service (Type=notify).
- Split CI into cross-platform and linux-only jobs.
- Exclude weft-compositor from Windows check scripts.
2026-03-10 19:56:35 +00:00
|
|
|
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
#[cfg(target_os = "linux")]
|
|
|
|
|
use smithay_drm_extras::drm_scanner::{DrmScanEvent, DrmScanner};
|
feat(compositor): add weft-compositor crate
- Implement WeftCompositorState with all Wayland protocol globals:
compositor, xdg-shell, layer-shell, shm, dmabuf, output, presentation,
text-input, input-method, pointer-constraints, cursor-shape, seat.
- Implement process_input_event covering keyboard, pointer (relative +
absolute), axis, touch, and all gesture types (swipe, pinch, hold).
- Implement Winit backend with damage-tracked rendering loop and frame
callbacks.
- Add DRM/KMS backend skeleton: libseat session, udev device discovery,
calloop integration (rendering path deferred).
- Add infra/systemd/weft-compositor.service (Type=notify).
- Split CI into cross-platform and linux-only jobs.
- Exclude weft-compositor from Windows check scripts.
2026-03-10 19:56:35 +00:00
|
|
|
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
#[cfg(target_os = "linux")]
|
|
|
|
|
use crate::{
|
|
|
|
|
input,
|
|
|
|
|
state::{WeftClientState, WeftCompositorState},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#[cfg(target_os = "linux")]
|
|
|
|
|
use super::drm_device::{WeftDrmData, WeftDrmDevice, WeftOutputSurface};
|
|
|
|
|
|
|
|
|
|
#[cfg(target_os = "linux")]
|
|
|
|
|
const SUPPORTED_FORMATS: &[Fourcc] = &[
|
|
|
|
|
Fourcc::Abgr2101010,
|
|
|
|
|
Fourcc::Argb2101010,
|
|
|
|
|
Fourcc::Abgr8888,
|
|
|
|
|
Fourcc::Argb8888,
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
#[cfg(target_os = "linux")]
|
|
|
|
|
const SUPPORTED_FORMATS_8BIT_ONLY: &[Fourcc] = &[Fourcc::Abgr8888, Fourcc::Argb8888];
|
|
|
|
|
|
|
|
|
|
#[cfg(target_os = "linux")]
|
|
|
|
|
type WeftMultiRenderer<'a> = MultiRenderer<
|
|
|
|
|
'a,
|
|
|
|
|
'a,
|
|
|
|
|
GbmGlesBackend<GlesRenderer, DrmDeviceFd>,
|
|
|
|
|
GbmGlesBackend<GlesRenderer, DrmDeviceFd>,
|
|
|
|
|
>;
|
feat(compositor): add weft-compositor crate
- Implement WeftCompositorState with all Wayland protocol globals:
compositor, xdg-shell, layer-shell, shm, dmabuf, output, presentation,
text-input, input-method, pointer-constraints, cursor-shape, seat.
- Implement process_input_event covering keyboard, pointer (relative +
absolute), axis, touch, and all gesture types (swipe, pinch, hold).
- Implement Winit backend with damage-tracked rendering loop and frame
callbacks.
- Add DRM/KMS backend skeleton: libseat session, udev device discovery,
calloop integration (rendering path deferred).
- Add infra/systemd/weft-compositor.service (Type=notify).
- Split CI into cross-platform and linux-only jobs.
- Exclude weft-compositor from Windows check scripts.
2026-03-10 19:56:35 +00:00
|
|
|
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
#[cfg(target_os = "linux")]
|
|
|
|
|
pub fn run() -> anyhow::Result<()> {
|
feat(compositor): add weft-compositor crate
- Implement WeftCompositorState with all Wayland protocol globals:
compositor, xdg-shell, layer-shell, shm, dmabuf, output, presentation,
text-input, input-method, pointer-constraints, cursor-shape, seat.
- Implement process_input_event covering keyboard, pointer (relative +
absolute), axis, touch, and all gesture types (swipe, pinch, hold).
- Implement Winit backend with damage-tracked rendering loop and frame
callbacks.
- Add DRM/KMS backend skeleton: libseat session, udev device discovery,
calloop integration (rendering path deferred).
- Add infra/systemd/weft-compositor.service (Type=notify).
- Split CI into cross-platform and linux-only jobs.
- Exclude weft-compositor from Windows check scripts.
2026-03-10 19:56:35 +00:00
|
|
|
let mut event_loop: EventLoop<'static, WeftCompositorState> = EventLoop::try_new()?;
|
|
|
|
|
let loop_handle = event_loop.handle();
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
|
2026-03-10 22:43:43 +00:00
|
|
|
let display = Display::<WeftCompositorState>::new()?;
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
let display_handle = display.handle();
|
|
|
|
|
|
|
|
|
|
let (session, session_notifier) =
|
|
|
|
|
LibSeatSession::new().context("failed to create libseat session")?;
|
|
|
|
|
|
|
|
|
|
let seat_name = session.seat().to_owned();
|
feat(compositor): add weft-compositor crate
- Implement WeftCompositorState with all Wayland protocol globals:
compositor, xdg-shell, layer-shell, shm, dmabuf, output, presentation,
text-input, input-method, pointer-constraints, cursor-shape, seat.
- Implement process_input_event covering keyboard, pointer (relative +
absolute), axis, touch, and all gesture types (swipe, pinch, hold).
- Implement Winit backend with damage-tracked rendering loop and frame
callbacks.
- Add DRM/KMS backend skeleton: libseat session, udev device discovery,
calloop integration (rendering path deferred).
- Add infra/systemd/weft-compositor.service (Type=notify).
- Split CI into cross-platform and linux-only jobs.
- Exclude weft-compositor from Windows check scripts.
2026-03-10 19:56:35 +00:00
|
|
|
let loop_signal = event_loop.get_signal();
|
|
|
|
|
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
let primary_gpu_node = if let Ok(var) = std::env::var("WEFT_DRM_DEVICE") {
|
|
|
|
|
DrmNode::from_path(var).context("invalid WEFT_DRM_DEVICE path")?
|
|
|
|
|
} else {
|
|
|
|
|
primary_gpu(&seat_name)
|
|
|
|
|
.ok()
|
|
|
|
|
.flatten()
|
2026-03-10 22:43:43 +00:00
|
|
|
.and_then(|p| {
|
|
|
|
|
DrmNode::from_path(p)
|
|
|
|
|
.ok()?
|
|
|
|
|
.node_with_type(NodeType::Render)?
|
|
|
|
|
.ok()
|
|
|
|
|
})
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
.or_else(|| {
|
|
|
|
|
all_gpus(&seat_name)
|
|
|
|
|
.unwrap_or_default()
|
|
|
|
|
.into_iter()
|
|
|
|
|
.find_map(|p| DrmNode::from_path(p).ok())
|
|
|
|
|
})
|
|
|
|
|
.context("no GPU found")?
|
|
|
|
|
};
|
|
|
|
|
tracing::info!(?primary_gpu_node, "primary GPU");
|
|
|
|
|
|
|
|
|
|
let gpu_manager: super::drm_device::WeftGpuManager =
|
|
|
|
|
GpuManager::new(Default::default()).context("failed to create GPU manager")?;
|
feat(compositor): add weft-compositor crate
- Implement WeftCompositorState with all Wayland protocol globals:
compositor, xdg-shell, layer-shell, shm, dmabuf, output, presentation,
text-input, input-method, pointer-constraints, cursor-shape, seat.
- Implement process_input_event covering keyboard, pointer (relative +
absolute), axis, touch, and all gesture types (swipe, pinch, hold).
- Implement Winit backend with damage-tracked rendering loop and frame
callbacks.
- Add DRM/KMS backend skeleton: libseat session, udev device discovery,
calloop integration (rendering path deferred).
- Add infra/systemd/weft-compositor.service (Type=notify).
- Split CI into cross-platform and linux-only jobs.
- Exclude weft-compositor from Windows check scripts.
2026-03-10 19:56:35 +00:00
|
|
|
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
let listening_socket =
|
|
|
|
|
ListeningSocketSource::new_auto().context("failed to create Wayland socket")?;
|
2026-03-10 20:20:28 +00:00
|
|
|
let socket_name = listening_socket.socket_name().to_os_string();
|
2026-03-10 22:43:43 +00:00
|
|
|
unsafe { std::env::set_var("WAYLAND_DISPLAY", &socket_name) };
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
tracing::info!(?socket_name, "Wayland socket open");
|
feat(compositor): add weft-compositor crate
- Implement WeftCompositorState with all Wayland protocol globals:
compositor, xdg-shell, layer-shell, shm, dmabuf, output, presentation,
text-input, input-method, pointer-constraints, cursor-shape, seat.
- Implement process_input_event covering keyboard, pointer (relative +
absolute), axis, touch, and all gesture types (swipe, pinch, hold).
- Implement Winit backend with damage-tracked rendering loop and frame
callbacks.
- Add DRM/KMS backend skeleton: libseat session, udev device discovery,
calloop integration (rendering path deferred).
- Add infra/systemd/weft-compositor.service (Type=notify).
- Split CI into cross-platform and linux-only jobs.
- Exclude weft-compositor from Windows check scripts.
2026-03-10 19:56:35 +00:00
|
|
|
|
2026-03-10 20:20:28 +00:00
|
|
|
loop_handle
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
.insert_source(listening_socket, |stream, _, state| {
|
2026-03-10 20:20:28 +00:00
|
|
|
state
|
|
|
|
|
.display_handle
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
.insert_client(stream, Arc::new(WeftClientState::default()))
|
2026-03-10 20:20:28 +00:00
|
|
|
.unwrap();
|
|
|
|
|
})
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
.map_err(|e| anyhow::anyhow!("socket source: {e}"))?;
|
feat(compositor): add weft-compositor crate
- Implement WeftCompositorState with all Wayland protocol globals:
compositor, xdg-shell, layer-shell, shm, dmabuf, output, presentation,
text-input, input-method, pointer-constraints, cursor-shape, seat.
- Implement process_input_event covering keyboard, pointer (relative +
absolute), axis, touch, and all gesture types (swipe, pinch, hold).
- Implement Winit backend with damage-tracked rendering loop and frame
callbacks.
- Add DRM/KMS backend skeleton: libseat session, udev device discovery,
calloop integration (rendering path deferred).
- Add infra/systemd/weft-compositor.service (Type=notify).
- Split CI into cross-platform and linux-only jobs.
- Exclude weft-compositor from Windows check scripts.
2026-03-10 19:56:35 +00:00
|
|
|
|
2026-03-10 20:20:28 +00:00
|
|
|
loop_handle
|
|
|
|
|
.insert_source(
|
|
|
|
|
Generic::new(display, Interest::READ, Mode::Level),
|
|
|
|
|
|_, display, state| {
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
// Safety: Display is owned by this Generic source and outlives the event loop.
|
2026-03-10 20:20:28 +00:00
|
|
|
unsafe {
|
|
|
|
|
display.get_mut().dispatch_clients(state).unwrap();
|
|
|
|
|
}
|
|
|
|
|
Ok(PostAction::Continue)
|
|
|
|
|
},
|
|
|
|
|
)
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
.map_err(|e| anyhow::anyhow!("display source: {e}"))?;
|
|
|
|
|
|
2026-03-10 22:43:43 +00:00
|
|
|
let udev_backend = UdevBackend::new(&seat_name).context("failed to create udev backend")?;
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
|
|
|
|
|
let mut libinput_ctx =
|
2026-03-10 22:43:43 +00:00
|
|
|
Libinput::new_with_udev::<LibinputSessionInterface<LibSeatSession>>(session.clone().into());
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
libinput_ctx
|
|
|
|
|
.udev_assign_seat(&seat_name)
|
|
|
|
|
.map_err(|_| anyhow::anyhow!("libinput seat assignment failed"))?;
|
|
|
|
|
let libinput_backend = LibinputInputBackend::new(libinput_ctx);
|
2026-03-10 20:20:28 +00:00
|
|
|
|
|
|
|
|
loop_handle
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
.insert_source(
|
|
|
|
|
libinput_backend,
|
|
|
|
|
move |mut event, _, state: &mut WeftCompositorState| {
|
2026-03-10 22:43:43 +00:00
|
|
|
if let InputEvent::DeviceAdded { device } = &mut event
|
|
|
|
|
&& device.has_capability(DeviceCapability::Keyboard)
|
|
|
|
|
{
|
|
|
|
|
if let Some(led) = state.seat.get_keyboard().map(|k| k.led_state()) {
|
|
|
|
|
device.led_update(led.into());
|
|
|
|
|
}
|
|
|
|
|
if let Some(drm) = state.drm.as_mut() {
|
|
|
|
|
drm.keyboards.push(device.clone());
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
input::process_input_event(state, event);
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
.map_err(|e| anyhow::anyhow!("libinput source: {e}"))?;
|
|
|
|
|
|
|
|
|
|
loop_handle
|
|
|
|
|
.insert_source(
|
|
|
|
|
session_notifier,
|
|
|
|
|
move |event, &mut (), state: &mut WeftCompositorState| match event {
|
|
|
|
|
SessionEvent::PauseSession => {
|
|
|
|
|
if let Some(drm) = state.drm.as_mut() {
|
|
|
|
|
for dev in drm.devices.values_mut() {
|
|
|
|
|
dev.drm_output_manager.pause();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
SessionEvent::ActivateSession => {
|
|
|
|
|
tracing::info!("session activated");
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
.map_err(|e| anyhow::anyhow!("session notifier: {e}"))?;
|
|
|
|
|
|
|
|
|
|
loop_handle
|
|
|
|
|
.insert_source(
|
|
|
|
|
udev_backend,
|
|
|
|
|
move |event, _, state: &mut WeftCompositorState| match event {
|
|
|
|
|
UdevEvent::Added { device_id: _, path } => {
|
|
|
|
|
let node = match DrmNode::from_path(&path) {
|
|
|
|
|
Ok(n) => n,
|
|
|
|
|
Err(e) => {
|
|
|
|
|
tracing::warn!(?e, "failed to build DRM node");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
if let Err(e) = device_added(state, node, &path) {
|
|
|
|
|
tracing::warn!(?e, "failed to add DRM device");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
UdevEvent::Changed { device_id } => {
|
|
|
|
|
let node = state
|
|
|
|
|
.drm
|
|
|
|
|
.as_ref()
|
|
|
|
|
.and_then(|d| d.devices.keys().find(|n| n.dev_id() == device_id).copied());
|
|
|
|
|
if let Some(node) = node {
|
|
|
|
|
device_changed(state, node);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
UdevEvent::Removed { device_id } => {
|
|
|
|
|
let node = state
|
|
|
|
|
.drm
|
|
|
|
|
.as_ref()
|
|
|
|
|
.and_then(|d| d.devices.keys().find(|n| n.dev_id() == device_id).copied());
|
|
|
|
|
if let Some(node) = node {
|
|
|
|
|
device_removed(state, node);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
.map_err(|e| anyhow::anyhow!("udev source: {e}"))?;
|
|
|
|
|
|
2026-03-10 22:43:43 +00:00
|
|
|
let mut state =
|
|
|
|
|
WeftCompositorState::new(display_handle.clone(), loop_signal, loop_handle, seat_name);
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
|
|
|
|
|
state.drm = Some(WeftDrmData {
|
|
|
|
|
session,
|
|
|
|
|
primary_gpu: primary_gpu_node,
|
|
|
|
|
gpu_manager,
|
|
|
|
|
devices: HashMap::new(),
|
|
|
|
|
keyboards: Vec::new(),
|
|
|
|
|
display_handle,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let existing: Vec<(DrmNode, std::path::PathBuf)> = state
|
|
|
|
|
.drm
|
|
|
|
|
.as_ref()
|
|
|
|
|
.map(|d| {
|
|
|
|
|
all_gpus(d.session.seat())
|
|
|
|
|
.unwrap_or_default()
|
|
|
|
|
.into_iter()
|
|
|
|
|
.filter_map(|p| DrmNode::from_path(&p).ok().map(|n| (n, p)))
|
|
|
|
|
.collect()
|
2026-03-10 20:20:28 +00:00
|
|
|
})
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
.unwrap_or_default();
|
feat(compositor): add weft-compositor crate
- Implement WeftCompositorState with all Wayland protocol globals:
compositor, xdg-shell, layer-shell, shm, dmabuf, output, presentation,
text-input, input-method, pointer-constraints, cursor-shape, seat.
- Implement process_input_event covering keyboard, pointer (relative +
absolute), axis, touch, and all gesture types (swipe, pinch, hold).
- Implement Winit backend with damage-tracked rendering loop and frame
callbacks.
- Add DRM/KMS backend skeleton: libseat session, udev device discovery,
calloop integration (rendering path deferred).
- Add infra/systemd/weft-compositor.service (Type=notify).
- Split CI into cross-platform and linux-only jobs.
- Exclude weft-compositor from Windows check scripts.
2026-03-10 19:56:35 +00:00
|
|
|
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
for (node, path) in existing {
|
|
|
|
|
if let Err(e) = device_added(&mut state, node, &path) {
|
|
|
|
|
tracing::warn!(?e, ?node, "startup device_added failed");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let _ = sd_notify::notify(false, &[sd_notify::NotifyState::Ready]);
|
feat(compositor): add weft-compositor crate
- Implement WeftCompositorState with all Wayland protocol globals:
compositor, xdg-shell, layer-shell, shm, dmabuf, output, presentation,
text-input, input-method, pointer-constraints, cursor-shape, seat.
- Implement process_input_event covering keyboard, pointer (relative +
absolute), axis, touch, and all gesture types (swipe, pinch, hold).
- Implement Winit backend with damage-tracked rendering loop and frame
callbacks.
- Add DRM/KMS backend skeleton: libseat session, udev device discovery,
calloop integration (rendering path deferred).
- Add infra/systemd/weft-compositor.service (Type=notify).
- Split CI into cross-platform and linux-only jobs.
- Exclude weft-compositor from Windows check scripts.
2026-03-10 19:56:35 +00:00
|
|
|
|
2026-03-10 20:20:28 +00:00
|
|
|
event_loop.run(None, &mut state, |_| {})?;
|
feat(compositor): add weft-compositor crate
- Implement WeftCompositorState with all Wayland protocol globals:
compositor, xdg-shell, layer-shell, shm, dmabuf, output, presentation,
text-input, input-method, pointer-constraints, cursor-shape, seat.
- Implement process_input_event covering keyboard, pointer (relative +
absolute), axis, touch, and all gesture types (swipe, pinch, hold).
- Implement Winit backend with damage-tracked rendering loop and frame
callbacks.
- Add DRM/KMS backend skeleton: libseat session, udev device discovery,
calloop integration (rendering path deferred).
- Add infra/systemd/weft-compositor.service (Type=notify).
- Split CI into cross-platform and linux-only jobs.
- Exclude weft-compositor from Windows check scripts.
2026-03-10 19:56:35 +00:00
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
|
|
|
|
|
#[cfg(target_os = "linux")]
|
2026-03-10 22:43:43 +00:00
|
|
|
fn device_added(state: &mut WeftCompositorState, node: DrmNode, path: &Path) -> anyhow::Result<()> {
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
let drm_data = state.drm.as_mut().context("DRM data not initialised")?;
|
|
|
|
|
|
|
|
|
|
let fd = drm_data
|
|
|
|
|
.session
|
|
|
|
|
.open(
|
|
|
|
|
path,
|
|
|
|
|
OFlags::RDWR | OFlags::CLOEXEC | OFlags::NOCTTY | OFlags::NONBLOCK,
|
|
|
|
|
)
|
|
|
|
|
.context("failed to open DRM device")?;
|
|
|
|
|
|
|
|
|
|
let fd = DrmDeviceFd::new(DeviceFd::from(fd));
|
2026-03-10 22:43:43 +00:00
|
|
|
let (drm, notifier) = DrmDevice::new(fd.clone(), true).context("DrmDevice::new failed")?;
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
let gbm = GbmDevice::new(fd).context("GbmDevice::new failed")?;
|
|
|
|
|
|
|
|
|
|
let render_node = (|| -> anyhow::Result<DrmNode> {
|
|
|
|
|
// Safety: EGLDisplay requires the GBM device to outlive it; gbm lives in WeftDrmDevice.
|
|
|
|
|
let egl_display =
|
|
|
|
|
unsafe { EGLDisplay::new(gbm.clone()).context("EGLDisplay::new failed")? };
|
2026-03-10 22:43:43 +00:00
|
|
|
let egl_device = EGLDevice::device_for_display(&egl_display).context("no EGL device")?;
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
if egl_device.is_software() {
|
|
|
|
|
anyhow::bail!("software renderer");
|
|
|
|
|
}
|
|
|
|
|
let rn = egl_device
|
|
|
|
|
.try_get_render_node()
|
|
|
|
|
.ok()
|
|
|
|
|
.flatten()
|
|
|
|
|
.unwrap_or(node);
|
|
|
|
|
drm_data
|
|
|
|
|
.gpu_manager
|
|
|
|
|
.as_mut()
|
|
|
|
|
.add_node(rn, gbm.clone())
|
|
|
|
|
.map_err(|e| anyhow::anyhow!("add_node: {e:?}"))?;
|
|
|
|
|
Ok(rn)
|
|
|
|
|
})()
|
|
|
|
|
.map_err(|e| {
|
|
|
|
|
tracing::warn!(?e, "EGL init failed; output may render black");
|
|
|
|
|
e
|
|
|
|
|
})
|
|
|
|
|
.ok();
|
|
|
|
|
|
|
|
|
|
let effective_gpu = render_node.unwrap_or(drm_data.primary_gpu);
|
|
|
|
|
|
|
|
|
|
let allocator = GbmAllocator::new(
|
|
|
|
|
gbm.clone(),
|
|
|
|
|
GbmBufferFlags::RENDERING | GbmBufferFlags::SCANOUT,
|
|
|
|
|
);
|
|
|
|
|
|
2026-03-10 22:43:43 +00:00
|
|
|
let exporter = GbmFramebufferExporter::new(gbm.clone(), render_node);
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
|
|
|
|
|
let color_formats = if std::env::var("WEFT_DISABLE_10BIT").is_ok() {
|
|
|
|
|
SUPPORTED_FORMATS_8BIT_ONLY
|
|
|
|
|
} else {
|
|
|
|
|
SUPPORTED_FORMATS
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let render_formats: FormatSet = drm_data
|
|
|
|
|
.gpu_manager
|
|
|
|
|
.single_renderer(&effective_gpu)
|
|
|
|
|
.map(|r| {
|
|
|
|
|
r.as_ref()
|
|
|
|
|
.egl_context()
|
|
|
|
|
.dmabuf_render_formats()
|
|
|
|
|
.iter()
|
|
|
|
|
.filter(|f| render_node.is_some() || f.modifier == Modifier::Linear)
|
|
|
|
|
.copied()
|
|
|
|
|
.collect::<FormatSet>()
|
|
|
|
|
})
|
|
|
|
|
.unwrap_or_default();
|
|
|
|
|
|
|
|
|
|
let drm_output_manager = DrmOutputManager::new(
|
|
|
|
|
drm,
|
|
|
|
|
allocator,
|
|
|
|
|
exporter,
|
|
|
|
|
Some(gbm),
|
|
|
|
|
color_formats.iter().copied(),
|
|
|
|
|
render_formats,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
let registration_token = state
|
|
|
|
|
.loop_handle
|
|
|
|
|
.insert_source(
|
|
|
|
|
notifier,
|
|
|
|
|
move |event, _metadata, data: &mut WeftCompositorState| match event {
|
|
|
|
|
DrmEvent::VBlank(crtc) => render_output(data, node, crtc),
|
|
|
|
|
DrmEvent::Error(e) => tracing::error!(?e, "DRM error"),
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
.map_err(|e| anyhow::anyhow!("DRM notifier: {e}"))?;
|
|
|
|
|
|
|
|
|
|
state.drm.as_mut().unwrap().devices.insert(
|
|
|
|
|
node,
|
|
|
|
|
WeftDrmDevice {
|
|
|
|
|
drm_output_manager,
|
|
|
|
|
drm_scanner: DrmScanner::new(),
|
|
|
|
|
surfaces: HashMap::new(),
|
|
|
|
|
render_node,
|
|
|
|
|
registration_token,
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
device_changed(state, node);
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(target_os = "linux")]
|
|
|
|
|
fn device_changed(state: &mut WeftCompositorState, node: DrmNode) {
|
|
|
|
|
let drm_data = match state.drm.as_mut() {
|
|
|
|
|
Some(d) => d,
|
|
|
|
|
None => return,
|
|
|
|
|
};
|
|
|
|
|
let device = match drm_data.devices.get_mut(&node) {
|
|
|
|
|
Some(d) => d,
|
|
|
|
|
None => return,
|
|
|
|
|
};
|
|
|
|
|
|
2026-03-10 22:43:43 +00:00
|
|
|
let events: Vec<DrmScanEvent> = match device
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
.drm_scanner
|
2026-03-10 22:43:43 +00:00
|
|
|
.scan_connectors(device.drm_output_manager.device())
|
|
|
|
|
{
|
|
|
|
|
Ok(r) => r.into_iter().collect(),
|
|
|
|
|
Err(e) => {
|
|
|
|
|
tracing::warn!(?e, "connector scan failed");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
};
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
|
|
|
|
|
for event in events {
|
|
|
|
|
match event {
|
|
|
|
|
DrmScanEvent::Connected {
|
|
|
|
|
connector,
|
|
|
|
|
crtc: Some(crtc),
|
|
|
|
|
} => connector_connected(state, node, connector, crtc),
|
|
|
|
|
DrmScanEvent::Disconnected {
|
|
|
|
|
connector,
|
|
|
|
|
crtc: Some(crtc),
|
|
|
|
|
} => connector_disconnected(state, node, connector, crtc),
|
|
|
|
|
_ => {}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(target_os = "linux")]
|
|
|
|
|
fn connector_connected(
|
|
|
|
|
state: &mut WeftCompositorState,
|
|
|
|
|
node: DrmNode,
|
|
|
|
|
connector: connector::Info,
|
|
|
|
|
crtc: crtc::Handle,
|
|
|
|
|
) {
|
|
|
|
|
let name = format!("{:?}-{}", connector.interface(), connector.interface_id());
|
|
|
|
|
|
|
|
|
|
let mode = match connector
|
|
|
|
|
.modes()
|
|
|
|
|
.iter()
|
|
|
|
|
.find(|m| m.mode_type().contains(ModeTypeFlags::PREFERRED))
|
|
|
|
|
.copied()
|
|
|
|
|
.or_else(|| connector.modes().first().copied())
|
|
|
|
|
{
|
|
|
|
|
Some(m) => m,
|
|
|
|
|
None => {
|
|
|
|
|
tracing::warn!(?name, "connector has no modes");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let wl_mode = WlMode {
|
|
|
|
|
size: (mode.size().0 as i32, mode.size().1 as i32).into(),
|
|
|
|
|
refresh: mode.vrefresh() as i32 * 1000,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let output = Output::new(
|
|
|
|
|
name.clone(),
|
|
|
|
|
PhysicalProperties {
|
|
|
|
|
size: (0, 0).into(),
|
|
|
|
|
subpixel: Subpixel::Unknown,
|
|
|
|
|
make: "Unknown".to_string(),
|
|
|
|
|
model: name.clone(),
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
let drm_data = match state.drm.as_mut() {
|
|
|
|
|
Some(d) => d,
|
|
|
|
|
None => return,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let global = output.create_global::<WeftCompositorState>(&drm_data.display_handle);
|
|
|
|
|
output.change_current_state(
|
|
|
|
|
Some(wl_mode),
|
|
|
|
|
Some(Transform::Normal),
|
|
|
|
|
None,
|
|
|
|
|
Some((0, 0).into()),
|
|
|
|
|
);
|
|
|
|
|
output.set_preferred(wl_mode);
|
|
|
|
|
|
|
|
|
|
let render_node = drm_data
|
|
|
|
|
.devices
|
|
|
|
|
.get(&node)
|
|
|
|
|
.and_then(|d| d.render_node)
|
|
|
|
|
.unwrap_or(drm_data.primary_gpu);
|
|
|
|
|
|
|
|
|
|
let planes = drm_data
|
|
|
|
|
.devices
|
|
|
|
|
.get_mut(&node)
|
|
|
|
|
.and_then(|d| d.drm_output_manager.device().planes(&crtc).ok());
|
|
|
|
|
|
|
|
|
|
let WeftDrmData {
|
|
|
|
|
ref mut gpu_manager,
|
|
|
|
|
ref mut devices,
|
|
|
|
|
..
|
|
|
|
|
} = *drm_data;
|
|
|
|
|
|
|
|
|
|
let device = match devices.get_mut(&node) {
|
|
|
|
|
Some(d) => d,
|
|
|
|
|
None => return,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let mut renderer = match gpu_manager.single_renderer(&render_node) {
|
|
|
|
|
Ok(r) => r,
|
|
|
|
|
Err(e) => {
|
|
|
|
|
tracing::warn!(?e, "no renderer for output init");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2026-03-10 22:43:43 +00:00
|
|
|
let drm_output = match device
|
|
|
|
|
.drm_output_manager
|
|
|
|
|
.initialize_output::<_, WaylandSurfaceRenderElement<_>>(
|
|
|
|
|
crtc,
|
|
|
|
|
mode,
|
|
|
|
|
&[connector.handle()],
|
|
|
|
|
&output,
|
|
|
|
|
planes,
|
|
|
|
|
&mut renderer,
|
|
|
|
|
&DrmOutputRenderElements::default(),
|
|
|
|
|
) {
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
Ok(o) => o,
|
|
|
|
|
Err(e) => {
|
|
|
|
|
tracing::warn!(?e, ?name, "initialize_output failed");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
device.surfaces.insert(
|
|
|
|
|
crtc,
|
|
|
|
|
WeftOutputSurface {
|
|
|
|
|
output: output.clone(),
|
|
|
|
|
drm_output,
|
|
|
|
|
device_id: node,
|
|
|
|
|
global,
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
state.space.map_output(&output, (0, 0));
|
|
|
|
|
tracing::info!(?name, "output connected");
|
|
|
|
|
render_output(state, node, crtc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(target_os = "linux")]
|
|
|
|
|
fn connector_disconnected(
|
|
|
|
|
state: &mut WeftCompositorState,
|
|
|
|
|
node: DrmNode,
|
|
|
|
|
_connector: connector::Info,
|
|
|
|
|
crtc: crtc::Handle,
|
|
|
|
|
) {
|
|
|
|
|
let drm_data = match state.drm.as_mut() {
|
|
|
|
|
Some(d) => d,
|
|
|
|
|
None => return,
|
|
|
|
|
};
|
2026-03-10 22:43:43 +00:00
|
|
|
if let Some(device) = drm_data.devices.get_mut(&node)
|
|
|
|
|
&& let Some(surface) = device.surfaces.remove(&crtc)
|
|
|
|
|
{
|
|
|
|
|
state.space.unmap_output(&surface.output);
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(target_os = "linux")]
|
|
|
|
|
fn device_removed(state: &mut WeftCompositorState, node: DrmNode) {
|
|
|
|
|
let drm_data = match state.drm.as_mut() {
|
|
|
|
|
Some(d) => d,
|
|
|
|
|
None => return,
|
|
|
|
|
};
|
|
|
|
|
if let Some(device) = drm_data.devices.remove(&node) {
|
|
|
|
|
state.loop_handle.remove(device.registration_token);
|
|
|
|
|
for surface in device.surfaces.into_values() {
|
|
|
|
|
state.space.unmap_output(&surface.output);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(target_os = "linux")]
|
|
|
|
|
fn render_output(state: &mut WeftCompositorState, node: DrmNode, crtc: crtc::Handle) {
|
|
|
|
|
let output = {
|
|
|
|
|
let drm_data = match state.drm.as_ref() {
|
|
|
|
|
Some(d) => d,
|
|
|
|
|
None => return,
|
|
|
|
|
};
|
|
|
|
|
match drm_data
|
|
|
|
|
.devices
|
|
|
|
|
.get(&node)
|
|
|
|
|
.and_then(|d| d.surfaces.get(&crtc))
|
|
|
|
|
{
|
|
|
|
|
Some(s) => s.output.clone(),
|
|
|
|
|
None => return,
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let render_node = {
|
|
|
|
|
let d = state.drm.as_ref().unwrap();
|
|
|
|
|
d.devices
|
|
|
|
|
.get(&node)
|
|
|
|
|
.and_then(|d| d.render_node)
|
|
|
|
|
.unwrap_or(d.primary_gpu)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let WeftCompositorState {
|
|
|
|
|
ref mut drm,
|
|
|
|
|
ref space,
|
|
|
|
|
..
|
|
|
|
|
} = *state;
|
|
|
|
|
|
|
|
|
|
let drm_data = match drm.as_mut() {
|
|
|
|
|
Some(d) => d,
|
|
|
|
|
None => return,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let WeftDrmData {
|
|
|
|
|
ref mut gpu_manager,
|
|
|
|
|
ref mut devices,
|
|
|
|
|
..
|
|
|
|
|
} = *drm_data;
|
|
|
|
|
|
|
|
|
|
let device = match devices.get_mut(&node) {
|
|
|
|
|
Some(d) => d,
|
|
|
|
|
None => return,
|
|
|
|
|
};
|
|
|
|
|
let surface = match device.surfaces.get_mut(&crtc) {
|
|
|
|
|
Some(s) => s,
|
|
|
|
|
None => return,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let mut renderer = match gpu_manager.single_renderer(&render_node) {
|
|
|
|
|
Ok(r) => r,
|
|
|
|
|
Err(e) => {
|
|
|
|
|
tracing::warn!(?e, "renderer unavailable");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Wave 2: clear-colour-only frame to establish the VBlank pipeline.
|
|
|
|
|
// Surface compositing is added in Wave 3.
|
|
|
|
|
let elements: &[WaylandSurfaceRenderElement<WeftMultiRenderer<'_>>] = &[];
|
|
|
|
|
match surface.drm_output.render_frame(
|
|
|
|
|
&mut renderer,
|
|
|
|
|
elements,
|
|
|
|
|
[0.08_f32, 0.08, 0.08, 1.0],
|
|
|
|
|
FrameFlags::DEFAULT,
|
|
|
|
|
) {
|
|
|
|
|
Ok(result) if !result.is_empty => {
|
|
|
|
|
if let Err(e) = surface.drm_output.queue_frame(None) {
|
|
|
|
|
tracing::warn!(?e, "queue_frame failed");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Ok(_) => {}
|
|
|
|
|
Err(e) => tracing::warn!(?e, "render_frame failed"),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
space.elements().for_each(|window| {
|
2026-03-10 22:43:43 +00:00
|
|
|
window.send_frame(&output, Duration::ZERO, Some(Duration::ZERO), |_, _| {
|
|
|
|
|
Some(output.clone())
|
|
|
|
|
});
|
feat(compositor): implement DRM/KMS rendering path
Add full DRM/KMS backend with libseat session, GBM allocation, EGL
display initialisation, and a GpuManager-driven rendering loop.
- drm_device.rs: type aliases and per-device/per-output state structs
(WeftDrmDevice, WeftOutputSurface, WeftDrmData)
- drm.rs: replace skeleton with complete backend libseat session,
udev device enumeration, libinput event source, connector scanning
via smithay-drm-extras DrmScanner, DrmOutputManager initialisation
per CRTC, VBlank-driven render_output, sd_notify(READY=1)
- state.rs: add drm: Option<WeftDrmData> field; route dmabuf import
through GPU manager when the DRM path is active
- Cargo.toml: add renderer_multi, use_system_lib Smithay features;
add smithay-drm-extras and sd-notify Linux dependencies
render_output submits a clear-colour-only frame to establish
the VBlank pipeline. Surface compositing is wired up in a subsequent commit.
2026-03-10 21:32:21 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let _ = state.display_handle.flush_clients();
|
2026-03-10 22:43:43 +00:00
|
|
|
}
|