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")]
|
2026-03-10 23:03:33 +00:00
|
|
|
use std::{
|
|
|
|
|
collections::HashMap,
|
|
|
|
|
path::Path,
|
|
|
|
|
sync::Arc,
|
|
|
|
|
time::{Duration, Instant},
|
|
|
|
|
};
|
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 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::{
|
feat(compositor): render pointer cursor from CursorImageStatus::Surface
When a Wayland client calls wl_pointer.set_cursor, render the cursor
surface at pointer_location using render_elements_from_surface_tree.
Changes in render_output:
- Collect output_geo, pointer_location, cursor_status before the inner
rendering block (avoids borrow conflict with space+drm destructure)
- Build cursor elements as Vec<SpaceRenderElements<_, WaylandSurfaceRenderElement<_>>>
via render_elements_from_surface_tree with Kind::Cursor; hotspot is
read from CursorImageSurfaceData on the cursor wl_surface
- Cursor elements prepend space elements (highest z-index first, matching
render_elements_for_output sort order descending by z_index)
- CursorImageStatus::Hidden / Named: no cursor element emitted
New imports: SpaceRenderElements, CursorImageStatus, CursorImageSurfaceData,
render_elements_from_surface_tree, Kind, Scale, with_states
Hardware cursor plane deferred requires DRM cursor plane API audit.
2026-03-10 23:45:34 +00:00
|
|
|
element::{
|
|
|
|
|
Kind,
|
|
|
|
|
surface::{WaylandSurfaceRenderElement, render_elements_from_surface_tree},
|
|
|
|
|
},
|
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
|
|
|
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
|
|
|
},
|
feat(compositor): render pointer cursor from CursorImageStatus::Surface
When a Wayland client calls wl_pointer.set_cursor, render the cursor
surface at pointer_location using render_elements_from_surface_tree.
Changes in render_output:
- Collect output_geo, pointer_location, cursor_status before the inner
rendering block (avoids borrow conflict with space+drm destructure)
- Build cursor elements as Vec<SpaceRenderElements<_, WaylandSurfaceRenderElement<_>>>
via render_elements_from_surface_tree with Kind::Cursor; hotspot is
read from CursorImageSurfaceData on the cursor wl_surface
- Cursor elements prepend space elements (highest z-index first, matching
render_elements_for_output sort order descending by z_index)
- CursorImageStatus::Hidden / Named: no cursor element emitted
New imports: SpaceRenderElements, CursorImageStatus, CursorImageSurfaceData,
render_elements_from_surface_tree, Kind, Scale, with_states
Hardware cursor plane deferred requires DRM cursor plane API audit.
2026-03-10 23:45:34 +00:00
|
|
|
desktop::space::SpaceRenderElements,
|
|
|
|
|
input::pointer::{CursorImageStatus, CursorImageSurfaceData},
|
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,
|
|
|
|
|
},
|
feat(compositor): render pointer cursor from CursorImageStatus::Surface
When a Wayland client calls wl_pointer.set_cursor, render the cursor
surface at pointer_location using render_elements_from_surface_tree.
Changes in render_output:
- Collect output_geo, pointer_location, cursor_status before the inner
rendering block (avoids borrow conflict with space+drm destructure)
- Build cursor elements as Vec<SpaceRenderElements<_, WaylandSurfaceRenderElement<_>>>
via render_elements_from_surface_tree with Kind::Cursor; hotspot is
read from CursorImageSurfaceData on the cursor wl_surface
- Cursor elements prepend space elements (highest z-index first, matching
render_elements_for_output sort order descending by z_index)
- CursorImageStatus::Hidden / Named: no cursor element emitted
New imports: SpaceRenderElements, CursorImageStatus, CursorImageSurfaceData,
render_elements_from_surface_tree, Kind, Scale, with_states
Hardware cursor plane deferred requires DRM cursor plane API audit.
2026-03-10 23:45:34 +00:00
|
|
|
utils::{DeviceFd, Scale, Transform},
|
|
|
|
|
wayland::{compositor::with_states, socket::ListeningSocketSource},
|
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
|
|
|
};
|
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::{
|
2026-03-11 13:29:22 +00:00
|
|
|
appd_ipc::{self, WeftAppdIpc},
|
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,
|
|
|
|
|
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")]
|
2026-03-10 23:03:33 +00:00
|
|
|
#[allow(dead_code)]
|
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
|
|
|
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
|
|
|
|
2026-03-11 13:29:22 +00:00
|
|
|
state.appd_ipc = Some(WeftAppdIpc::new(appd_ipc::compositor_socket_path()));
|
|
|
|
|
if let Err(e) = appd_ipc::setup(&mut state) {
|
|
|
|
|
tracing::warn!(?e, "compositor IPC setup 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
|
|
|
state.drm = Some(WeftDrmData {
|
|
|
|
|
session,
|
|
|
|
|
primary_gpu: primary_gpu_node,
|
|
|
|
|
gpu_manager,
|
|
|
|
|
devices: HashMap::new(),
|
|
|
|
|
keyboards: Vec::new(),
|
|
|
|
|
display_handle,
|
2026-03-10 23:03:33 +00:00
|
|
|
start_time: Instant::now(),
|
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 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");
|
feat: appd IPC relay, WIT interfaces, UI kit, gesture routing, and CI hardening
- weft-appd: per-session IPC socket paths; bidirectional Wasm-HTML JSON relay
via spawn_ipc_relay; SO_PEERCRED UID check on Unix socket connections;
PanelGesture request and NavigationGesture broadcast for compositor gestures
- weft-runtime: weft:app/ipc, weft:app/fetch, weft:app/notifications WIT
interfaces; IpcState non-blocking Unix socket host functions; ureq-backed
net:fetch host function (net-fetch feature); notify-send notifications host
- weft-file-portal: spawn a thread per accepted connection for concurrent access
- weft-app-shell: weft-system:// URL translation; WEFT UI Kit UserScript
injection; resolve_weft_system_url helper
- weft-servo-shell: forward compositor navigation gestures to weft-appd
WebSocket as PanelGesture; WEFT UI Kit UserScript injection
- infra/shell: weft-ui-kit.js with 11 custom elements (weft-button, weft-card,
weft-dialog, weft-icon, weft-list, weft-list-item, weft-menu, weft-menu-item,
weft-progress, weft-input, weft-label); system-ui.html handles
NAVIGATION_GESTURE messages and dispatches weft:navigation-gesture CustomEvent
- infra/systemd: add missing env vars to weft-appd.service; correct
servo-shell.service binary path and system-ui.html argument
- .github/workflows/ci.yml: exclude weft-servo-shell and weft-app-shell from
cross-platform job; add them to linux-only job with libsystemd-dev dependency
2026-03-12 11:49:45 +00:00
|
|
|
let (pw, ph) = (wl_mode.size.w, wl_mode.size.h);
|
|
|
|
|
state.weft_shell_state.reconfigure_panels(0, 0, pw, ph);
|
|
|
|
|
state.weft_shell_state.retain_alive_panels();
|
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
|
|
|
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
|
|
|
}
|
feat: appd IPC relay, WIT interfaces, UI kit, gesture routing, and CI hardening
- weft-appd: per-session IPC socket paths; bidirectional Wasm-HTML JSON relay
via spawn_ipc_relay; SO_PEERCRED UID check on Unix socket connections;
PanelGesture request and NavigationGesture broadcast for compositor gestures
- weft-runtime: weft:app/ipc, weft:app/fetch, weft:app/notifications WIT
interfaces; IpcState non-blocking Unix socket host functions; ureq-backed
net:fetch host function (net-fetch feature); notify-send notifications host
- weft-file-portal: spawn a thread per accepted connection for concurrent access
- weft-app-shell: weft-system:// URL translation; WEFT UI Kit UserScript
injection; resolve_weft_system_url helper
- weft-servo-shell: forward compositor navigation gestures to weft-appd
WebSocket as PanelGesture; WEFT UI Kit UserScript injection
- infra/shell: weft-ui-kit.js with 11 custom elements (weft-button, weft-card,
weft-dialog, weft-icon, weft-list, weft-list-item, weft-menu, weft-menu-item,
weft-progress, weft-input, weft-label); system-ui.html handles
NAVIGATION_GESTURE messages and dispatches weft:navigation-gesture CustomEvent
- infra/systemd: add missing env vars to weft-appd.service; correct
servo-shell.service binary path and system-ui.html argument
- .github/workflows/ci.yml: exclude weft-servo-shell and weft-app-shell from
cross-platform job; add them to linux-only job with libsystemd-dev dependency
2026-03-12 11:49:45 +00:00
|
|
|
let (pw, ph) = state
|
|
|
|
|
.space
|
|
|
|
|
.outputs()
|
|
|
|
|
.next()
|
|
|
|
|
.and_then(|o| state.space.output_geometry(o))
|
|
|
|
|
.map(|g| (g.size.w, g.size.h))
|
|
|
|
|
.unwrap_or((0, 0));
|
|
|
|
|
state.weft_shell_state.reconfigure_panels(0, 0, pw, ph);
|
|
|
|
|
state.weft_shell_state.retain_alive_panels();
|
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)
|
|
|
|
|
};
|
|
|
|
|
|
2026-03-10 23:03:33 +00:00
|
|
|
let elapsed = state
|
|
|
|
|
.drm
|
|
|
|
|
.as_ref()
|
|
|
|
|
.map(|d| d.start_time.elapsed())
|
|
|
|
|
.unwrap_or_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
|
|
|
|
feat(compositor): render pointer cursor from CursorImageStatus::Surface
When a Wayland client calls wl_pointer.set_cursor, render the cursor
surface at pointer_location using render_elements_from_surface_tree.
Changes in render_output:
- Collect output_geo, pointer_location, cursor_status before the inner
rendering block (avoids borrow conflict with space+drm destructure)
- Build cursor elements as Vec<SpaceRenderElements<_, WaylandSurfaceRenderElement<_>>>
via render_elements_from_surface_tree with Kind::Cursor; hotspot is
read from CursorImageSurfaceData on the cursor wl_surface
- Cursor elements prepend space elements (highest z-index first, matching
render_elements_for_output sort order descending by z_index)
- CursorImageStatus::Hidden / Named: no cursor element emitted
New imports: SpaceRenderElements, CursorImageStatus, CursorImageSurfaceData,
render_elements_from_surface_tree, Kind, Scale, with_states
Hardware cursor plane deferred requires DRM cursor plane API audit.
2026-03-10 23:45:34 +00:00
|
|
|
let output_geo = state.space.output_geometry(&output).unwrap_or_default();
|
|
|
|
|
let pointer_location = state.pointer_location;
|
|
|
|
|
let cursor_status = state.cursor_image_status.clone();
|
|
|
|
|
|
2026-03-10 23:03:33 +00:00
|
|
|
{
|
|
|
|
|
let WeftCompositorState {
|
|
|
|
|
ref mut drm,
|
|
|
|
|
ref space,
|
|
|
|
|
..
|
|
|
|
|
} = *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
|
|
|
|
2026-03-10 23:03:33 +00:00
|
|
|
let drm_data = match drm.as_mut() {
|
|
|
|
|
Some(d) => d,
|
|
|
|
|
None => 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
|
|
|
|
2026-03-10 23:03:33 +00:00
|
|
|
let WeftDrmData {
|
|
|
|
|
ref mut gpu_manager,
|
|
|
|
|
ref mut devices,
|
|
|
|
|
..
|
|
|
|
|
} = *drm_data;
|
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 23:03:33 +00:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
};
|
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
|
|
|
|
feat(compositor): render pointer cursor from CursorImageStatus::Surface
When a Wayland client calls wl_pointer.set_cursor, render the cursor
surface at pointer_location using render_elements_from_surface_tree.
Changes in render_output:
- Collect output_geo, pointer_location, cursor_status before the inner
rendering block (avoids borrow conflict with space+drm destructure)
- Build cursor elements as Vec<SpaceRenderElements<_, WaylandSurfaceRenderElement<_>>>
via render_elements_from_surface_tree with Kind::Cursor; hotspot is
read from CursorImageSurfaceData on the cursor wl_surface
- Cursor elements prepend space elements (highest z-index first, matching
render_elements_for_output sort order descending by z_index)
- CursorImageStatus::Hidden / Named: no cursor element emitted
New imports: SpaceRenderElements, CursorImageStatus, CursorImageSurfaceData,
render_elements_from_surface_tree, Kind, Scale, with_states
Hardware cursor plane deferred requires DRM cursor plane API audit.
2026-03-10 23:45:34 +00:00
|
|
|
let output_scale = output.current_scale().fractional_scale();
|
|
|
|
|
|
|
|
|
|
let mut elements: Vec<SpaceRenderElements<_, WaylandSurfaceRenderElement<_>>> =
|
|
|
|
|
if let CursorImageStatus::Surface(ref cursor_surface) = cursor_status {
|
|
|
|
|
let hotspot = with_states(cursor_surface, |states| {
|
|
|
|
|
states
|
|
|
|
|
.data_map
|
|
|
|
|
.get::<CursorImageSurfaceData>()
|
|
|
|
|
.and_then(|d| d.lock().ok().map(|g| g.hotspot))
|
|
|
|
|
.unwrap_or_default()
|
|
|
|
|
});
|
|
|
|
|
let cursor_pos = (pointer_location - output_geo.loc.to_f64() - hotspot.to_f64())
|
|
|
|
|
.to_physical_precise_round(output_scale);
|
|
|
|
|
render_elements_from_surface_tree(
|
|
|
|
|
&mut renderer,
|
|
|
|
|
cursor_surface,
|
|
|
|
|
cursor_pos,
|
|
|
|
|
Scale::from(output_scale),
|
|
|
|
|
1.0,
|
|
|
|
|
Kind::Cursor,
|
|
|
|
|
)
|
|
|
|
|
} else {
|
|
|
|
|
Vec::new()
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
elements.extend(
|
|
|
|
|
space
|
|
|
|
|
.render_elements_for_output(&mut renderer, &output, 1.0)
|
|
|
|
|
.unwrap_or_default(),
|
|
|
|
|
);
|
2026-03-10 23:03:33 +00:00
|
|
|
|
|
|
|
|
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");
|
|
|
|
|
}
|
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 23:03:33 +00:00
|
|
|
Ok(_) => {}
|
|
|
|
|
Err(e) => tracing::warn!(?e, "render_frame 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
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-10 23:03:33 +00:00
|
|
|
state.space.elements().for_each(|window| {
|
|
|
|
|
window.send_frame(&output, elapsed, Some(Duration::from_millis(16)), |_, _| {
|
2026-03-10 22:43:43 +00:00
|
|
|
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
|
|
|
});
|
2026-03-10 23:03:33 +00:00
|
|
|
state.space.refresh();
|
|
|
|
|
state.popups.cleanup();
|
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
|
|
|
}
|