srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/crates/wayland
diff options
context:
space:
mode:
authorsrdusr <[email protected]>2025-05-26 21:09:00 +0200
committersrdusr <[email protected]>2025-05-26 21:09:00 +0200
commit65e1e7476101c56f44f843c9b9160730331dfbd1 (patch)
treebeaa330d2176dba39d66b6ae73e43f9f7570f96b /crates/wayland
parent9fb4f996fe76dc5eeee861e463e62fdb6f7de816 (diff)
downloadsrdwm-65e1e7476101c56f44f843c9b9160730331dfbd1.tar.gz
srdwm-65e1e7476101c56f44f843c9b9160730331dfbd1.zip
Render the real cursor on the GPU render path, not just a clear color
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.
Diffstat (limited to 'crates/wayland')
-rw-r--r--crates/wayland/src/udev/gpu.rs28
-rw-r--r--crates/wayland/src/udev/render.rs35
2 files changed, 43 insertions, 20 deletions
diff --git a/crates/wayland/src/udev/gpu.rs b/crates/wayland/src/udev/gpu.rs
index 50c42c1..904a420 100644
--- a/crates/wayland/src/udev/gpu.rs
+++ b/crates/wayland/src/udev/gpu.rs
@@ -1,8 +1,14 @@
//! Opt-in (`SRDWM_GPU=1`) GBM+EGL+`DrmCompositor` GPU render path for the
//! udev backend - see [`probe`]'s own doc comment for exactly what this
-//! does and does not do yet (Phase 2: one output, clear-color only, no
-//! window content/decorations, no VT-switch support - see the plan this
-//! was built from, `snappy-percolating-boole.md`, for the full scoping).
+//! does and does not do yet. Past the original Phase 2 (one output,
+//! clear-color only - see the plan this was built from, `snappy-
+//! percolating-boole.md`, for that phase's own scoping): every head
+//! `initialize_output` succeeds for gets driven, not just the first
+//! (`GpuContext::outputs`), VT-switch pause/activate is wired
+//! (`udev/session.rs`'s `SessionEvent` handlers), and the real cursor
+//! renders on top of the clear color (`udev/render.rs`'s own GPU branch).
+//! Window content and decorations are the remaining gap - a GPU-driven
+//! head still shows no windows, just its own clear color and cursor.
use std::os::fd::{AsFd, OwnedFd};
@@ -11,7 +17,6 @@ use smithay::backend::drm::exporter::gbm::GbmFramebufferExporter;
use smithay::backend::drm::output::{DrmOutput, DrmOutputManager, DrmOutputRenderElements};
use smithay::backend::drm::{DrmDevice, DrmDeviceFd, DrmDeviceNotifier};
use smithay::backend::egl::{EGLContext, EGLDevice, EGLDisplay};
-use smithay::backend::renderer::element::memory::MemoryRenderBufferRenderElement;
use smithay::backend::renderer::gles::GlesRenderer;
use smithay::output::Output;
use smithay::reexports::drm::buffer::DrmFourcc;
@@ -21,11 +26,16 @@ use smithay::utils::DeviceFd;
use super::Card;
-/// The concrete render-element type this phase's (empty) element list uses
-/// - see [`GpuContext::initialize_output`]'s own doc comment for why the
-/// actual choice of `E` doesn't matter yet, since no real elements are
-/// passed through it.
-type GpuElement = MemoryRenderBufferRenderElement<GlesRenderer>;
+/// The render-element type real frames on the GPU path push through --
+/// `crate::elements::OverlayElement`, the same enum (Surface/Memory/Solid)
+/// the Pixman path's own `custom_elements` already uses, just instantiated
+/// for `GlesRenderer` instead of `PixmanRenderer`. Started out as a bare
+/// `MemoryRenderBufferRenderElement<GlesRenderer>` back when this phase's
+/// element list was always empty and the concrete choice genuinely didn't
+/// matter - widened once `render_udev_frame`'s GPU branch started pushing
+/// a real cursor (`cursor::render_elements`' own return type) through
+/// `render_frame`.
+type GpuElement = crate::elements::OverlayElement<GlesRenderer>;
/// One head successfully driven through `DrmOutputManager::initialize_output`
/// - see [`GpuContext::initialize_output`]'s own doc comment.
diff --git a/crates/wayland/src/udev/render.rs b/crates/wayland/src/udev/render.rs
index cfc9efd..4d51fab 100644
--- a/crates/wayland/src/udev/render.rs
+++ b/crates/wayland/src/udev/render.rs
@@ -214,16 +214,15 @@ impl CompState {
let Some(udev) = self.udev.as_mut() else { return };
let head_crtc = udev.heads[index].crtc;
// Phase 2 of the GPU-rendering plan (`gpu.rs`'s own module doc
- // comment), now extended to every head `initialize_output`
- // succeeded for (`GpuContext::outputs`' own doc comment), not
- // just the first: each renders a plain clear color through the
- // real GBM+EGL+DrmCompositor pipeline instead of anything
- // below - no window content, decorations, or cursor yet,
- // deliberately (see that module's own doc comment for why).
- // Any head `output_for_mut` finds nothing for - either
- // `SRDWM_GPU` was never set, or `initialize_output` failed for
- // this specific crtc - falls straight through to the
- // existing, untouched Pixman path unchanged.
+ // comment), extended to every head `initialize_output`
+ // succeeded for (`GpuContext::outputs`' own doc comment) and
+ // now, past clear-color-only, to the real cursor too - see
+ // this block's own `elements` for the still-missing pieces
+ // (window content, decorations). Any head `output_for_mut`
+ // finds nothing for - either `SRDWM_GPU` was never set, or
+ // `initialize_output` failed for this specific crtc - falls
+ // straight through to the existing, untouched Pixman path
+ // unchanged.
if let Some(gpu) = udev.gpu.as_mut() {
// Direct field access (`gpu.outputs`), not `GpuContext::
// output_for_mut` - that method takes `&mut self`, which
@@ -233,7 +232,21 @@ impl CompState {
// field access, not a method call, even one that (like
// this one) only actually touches `self.outputs`.
if let Some(gpu_output) = gpu.outputs.iter_mut().find(|(c, _)| *c == head_crtc).map(|(_, o)| o) {
- let elements: [smithay::backend::renderer::element::memory::MemoryRenderBufferRenderElement<smithay::backend::renderer::gles::GlesRenderer>; 0] = [];
+ // The one real element this phase pushes: the same
+ // `cursor::render_elements` the Pixman path already
+ // uses, generic over the renderer (`R: Renderer +
+ // ImportAll + ImportMem`), so it works unmodified
+ // against `gpu.renderer` (`GlesRenderer`) instead of
+ // `udev.renderer` (`PixmanRenderer`). Window content
+ // and decorations are real, separate scope past this
+ // (they need either a GLES-side version of the
+ // border/titlebar bitmap upload path, or the rounded-
+ // corner GLES shader `winit/render.rs` already has
+ // wired for its own single-output case) - not
+ // attempted here, so a GPU-driven head still shows a
+ // plain clear color under its own real, moving cursor,
+ // not yet any windows.
+ let elements = crate::cursor::render_elements(&cursor_status, &cursor_buffers, &mut gpu.renderer, udev.pointer_pos, origin, udev.heads[index].size);
let clear_color = [0.05, 0.05, 0.08, 1.0];
match gpu_output.render_frame(&mut gpu.renderer, &elements, clear_color, smithay::backend::drm::compositor::FrameFlags::DEFAULT) {
Ok(res) if !res.is_empty => match gpu_output.queue_frame(None) {