| Age | Commit message (Collapse) | Author | Files | Lines |
|
|
|
The GPU (SRDWM_GPU=1/general.gpu) path had real window content but
square corners and no border/titlebar. A prior pass investigated a full
port of the Pixman path's decoration rendering and deliberately did not
attempt it blind, given no working GPU-capable hardware on this machine
to verify a single pixel of it against. Asked directly, twice, to build
it anyway rather than leave it.
Scoped smaller than a full port: border top/bottom strips and the
titlebar bitmap now render, reusing the exact cached MemoryRenderBuffers
the Pixman path already builds (renderer-agnostic pixel buffers,
imported for GlesRenderer the same generic way cursor::render_elements
already does for either renderer). Left out on purpose: occlusion-
fragment clipping against overlapping windows, and the left/right border
side strips plus the drop shadow.
Full workspace build/test/clippy clean. Explicitly not visually
verified - same reason as before, no GPU-capable hardware on this
machine.
|
|
Past clear-color + cursor: a GPU-driven head now renders every
visible window's real content too, via surface_content_elements (the
same generic-over-renderer helper the Pixman path uses, unmodified
against gpu.renderer instead of udev.renderer). Content pushed after
the cursor (so the cursor stays on top), in the same front-to-back
`ids` order the Pixman path's own custom_elements already relies on
for correct occlusion between windows - plain painter's-algorithm
draw order, no separate clip needed since content is window-shaped.
Deliberately the *unrounded* path: no corner masking (that's built
against PixmanRenderer specifically on this backend) and no
decorations (border, titlebar) - a GPU-driven head now shows real
window content, square corners, no chrome. Decorations are the
remaining real gap before this path has parity with the software one.
Per-window geometry/position math (geom from window_anims or
w.geometry, band for a decorated window's titlebar reservation,
content_offset clamped non-negative) mirrors the Pixman path's own
content push exactly, including an earlier double-
subtraction and negative-margin fixes - so a CSD client with a real
shadow margin positions the same way on either render path.
Untested on real GPU-enabled hardware as of this writing: builds,
passes clippy, full test suite green, and matches the existing Pixman
path's geometry logic by inspection, but SRDWM_GPU/general.gpu were
both unset on the machine this was built on - noted honestly in
gpu.rs's own module doc comment, DEFAULTS.md, and
IMPLEMENTATION_STATUS.md.
|
|
SRDWM_GPU=1 was the only way to opt into the udev backend's GBM+EGL
GPU render path - an env var, not a real config option, with no way
to enable it from init.lua the way every other general.* flag works.
WindowManager::gpu_enabled (plain bool, false by default - unlike
rounded_corners_enabled's Option<bool>, GPU rendering has one
unambiguous default regardless of which backend ends up connecting,
so there's no "let the backend decide" case to preserve) is read from
general.gpu in apply_general_settings, same as every other general.*
key. gpu::probe now takes an explicit enabled: bool instead of
checking the env var itself; udev/platform.rs's call site computes it
as wm.gpu_enabled OR SRDWM_GPU=1, so the env var still works as a
quick manual override for testing without touching config, on top of
the new persistent option.
Falls back to the existing software (Pixman) path exactly as before
on any failure at any step (no GBM device, no atomic-modesetting
support, a software-only EGL renderer, ...) - gpu::probe's own
fallback behavior is unchanged, only how the initial enabled/disabled
decision gets made.
|
|
Past clear-color-only (Phase 2): the GPU-driven head now shows the
same moving cursor the Pixman path renders, via cursor::render_elements
- already generic over the renderer (R: Renderer + ImportAll +
ImportMem), so it works unmodified against gpu.renderer (GlesRenderer)
instead of udev.renderer (PixmanRenderer).
GpuElement (gpu.rs) widened from a bare MemoryRenderBufferRenderElement
to crate::elements::OverlayElement<GlesRenderer> - the same
Surface/Memory/Solid enum the Pixman path's own custom_elements already
uses, needed once the element list stopped always being empty.
Window content and decorations remain a real gap - a GPU-driven head
still shows no windows, just its own clear color and cursor. Untested
on real GPU-enabled hardware this work (SRDWM_GPU unset on this
machine's live session); builds, passes clippy, full test suite green.
|
|
Phase 2 of the GPU-rendering plan deliberately targeted a single head
(GpuContext::output: Option<(crtc::Handle, GpuOutput)>) as a narrow
proof that GBM+EGL+DrmCompositor rendering works at all on this
hardware. DrmOutputManager already supports driving several crtcs at
once - initialize_output is a per-crtc call on one shared manager,
the same way anvil drives multiple outputs - so this was purely an
unexercised restriction, not an architectural limit.
GpuContext::output is now GpuContext::outputs: Vec<(crtc::Handle,
GpuOutput)>, and udev/platform.rs calls initialize_output for every
connected head in its own bring-up loop instead of only the first
after that loop finishes. A head this fails for individually (already
logged, not fatal) still just has no entry and falls back to the
existing legacy Pixman path, unchanged from before.
session.rs's VBlank handler and its VT-switch resume path (which
excludes GPU-driven crtcs from the legacy set_crtc reassert loop, a
different device fd that must never issue mode-set commands against a
crtc DrmOutputManager already owns) both now look a crtc up in the
Vec instead of comparing against a single stored one.
render.rs's own render-loop lookup uses direct field access
(gpu.outputs.iter_mut().find(...)) rather than an equivalent
&mut self method: the borrow checker treats a method call as
borrowing all of GpuContext, including gpu.renderer needed a few
lines later for the same head, where direct field access lets it see
the two borrows are disjoint.
Still gated behind SRDWM_GPU=1 (unset by default) and untested on
real multi-monitor hardware with the flag on - this machine has one
display, so the actual multi-head path itself only gets exercised
whenever it's set on hardware that has more than one.
|
|
Extends the SRDWM_GPU=1 opt-in path (Phase 1, fa0c7f1) from a
capability probe into an actual, working GPU render pipeline for
exactly one head, per the plan this was built from
the plan file.
gpu.rs: probe now goes all the way through EGLContext, GlesRenderer,
DrmDevice (real DRM device, separate duped fd from the existing legacy
Card), and DrmOutputManager construction, returning both a GpuContext
and its DrmDeviceNotifier on success. GpuContext::initialize_output
drives one crtc/mode/connector through DrmOutputManager, storing the
resulting GpuOutput for the render loop to find.
Confirmed while reading smithay's own source directly (not assumed):
DrmDevice::new's disable_connectors parameter is not an atomic-vs-
legacy switch - DrmDevice::create_internal tries atomic capability
first and falls back to a Legacy internal variant automatically,
exposed via DrmDevice::is_atomic(), logged here rather than assumed.
platform.rs: probes at startup, calls initialize_output for the first
head only (Phase 2's deliberate scope - see the plan), registers the
DrmDeviceNotifier as its own calloop event source alongside (not
replacing) the existing legacy DRM-fd registration.
render.rs: render_udev_frame's per-head loop checks, before any of the
existing Pixman-specific element-building logic runs, whether this
head's crtc matches the GPU context's initialized output; if so,
renders a plain clear color through render_frame/queue_frame and
continues to the next head, completely bypassing the Pixman path for
that head. Every other head, and this same head whenever the GPU
context or its output is absent, is entirely unaffected.
session.rs: register_gpu_drm_notifier handles DrmEvent::VBlank by
calling frame_submitted() on the matching GpuOutput (required per
queue_frame's own doc comment, or the swapchain runs out of buffers)
and logs DrmEvent::Error without treating it as fatal.
Deliberately out of scope for this phase (documented in the plan):
window content/decorations/cursor on the GPU head (clear color only),
multi-monitor GPU rendering (one head only), and VT-switch pause/
resume for the GPU head specifically (DrmOutputManager's own pause()/
activate() calls are a different API surface from the
existing manual set_crtc+DPMS reassertion, and porting that pairing
correctly needs its own isolated verification pass).
SRDWM_GPU unset (the default) is unaffected: every step above only
runs when it's set to "1", and every failure at any step falls back
to the existing, untouched Pixman path with a logged reason, same
fallback contract Phase 1 already established.
|
|
The udev backend is, by explicit design, 100% software: PixmanRenderer
compositing into legacy KMS dumb buffers. That was a deliberate choice
for portability (dumb buffers work on essentially any DRM driver,
including a VM with no GBM/3D support), not an oversight - but this
machine's real hardware (Intel UHD 620, i915) should support real
GBM+EGL rendering, and the user has asked for a genuine GPU-accelerated
path, GPU preferred with CPU fallback, built as a separate track that
doesn't risk the working software path.
Adds `udev/gpu.rs::probe`: gated behind `SRDWM_GPU=1` (unset by
default - a no-op, zero behavior change for every session that
doesn't set it), attempts GBM device creation on a duped DRM fd, EGL
display/device creation, and a software-rasterizer check, logging
exactly which step failed if any and falling back silently. Wired in
at udev backend startup, right after the DRM fd is opened.
Deliberately does not yet create an EGLContext, a GlesRenderer, or
touch scanout at all. Reading smithay's own reference compositor
(anvil/src/udev.rs) confirmed it wires GBM+EGL rendering together with
atomic-KMS scanout as one unit via DrmCompositor, not as a renderer
swapped into the existing legacy set_crtc/page_flip flip loop this
backend uses today. Adopting DrmCompositor is separate, larger-scoped
work than "swap the renderer" - it replaces the same UdevHead
mode-set/flip machinery the VT-switch fixes
(register_session_notifier's ActivateSession arm, copy_and_flip's
retry backoff) live in, and needs its own plan. This probe answers the
first question - does the hardware even support it at all - safely,
before that larger integration is scoped and attempted.
Cargo.toml: added backend_egl/backend_gbm smithay features, additive
to the existing renderer_pixman path (unchanged, still the default).
|