srdusr
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crates/config/src/engine/support.rs10
-rw-r--r--crates/core/src/manager/mod.rs18
-rw-r--r--crates/srdwm/src/main.rs2
-rw-r--r--crates/wayland/src/udev/gpu.rs34
-rw-r--r--crates/wayland/src/udev/platform.rs24
5 files changed, 65 insertions, 23 deletions
diff --git a/crates/config/src/engine/support.rs b/crates/config/src/engine/support.rs
index b67a688..9f7e537 100644
--- a/crates/config/src/engine/support.rs
+++ b/crates/config/src/engine/support.rs
@@ -144,6 +144,16 @@ pub(super) fn default_config() -> HashMap<String, ConfigValue> {
set("general.animation_duration", Number(200.0));
set("general.shadows", Bool(true));
set("general.resize_margin", Number(6.0));
+ // `false`: real GBM+EGL+`DrmCompositor` GPU rendering on the udev
+ // backend is opt-in and still missing real window content/decoration
+ // support (see `crates/wayland/src/udev/gpu.rs`'s own module doc
+ // comment for exactly what it does render) - unlike `general.
+ // rounded_corners` just above, this has one unambiguous default
+ // regardless of which backend ends up connecting (GPU rendering is
+ // udev-only and experimental everywhere), so it's seeded here like
+ // every other ordinary flag rather than left absent for a backend to
+ // decide.
+ set("general.gpu", Bool(false));
// Deliberately *not* seeded here, unlike every other `general.*` key --
// its actual default differs by backend (GLES/winit: on; udev/Pixman:
// off, an untested-on-real-hardware CPU cost too real to default to on
diff --git a/crates/core/src/manager/mod.rs b/crates/core/src/manager/mod.rs
index 74be06b..9593dd3 100644
--- a/crates/core/src/manager/mod.rs
+++ b/crates/core/src/manager/mod.rs
@@ -189,6 +189,23 @@ pub struct WindowManager {
/// redraws constantly - see `crates/wayland/src/rounded_corners.rs`).
/// `Some(_)` only when the user explicitly set it, and wins either way.
pub rounded_corners_enabled: Option<bool>,
+ /// Whether the udev backend attempts real GBM+EGL+`DrmCompositor` GPU
+ /// rendering instead of the default, always-available software
+ /// (Pixman/dumb-buffer) path - read from `general.gpu`, `false` by
+ /// default (unlike `rounded_corners_enabled`'s `Option`, this has one
+ /// unambiguous default regardless of backend: GPU rendering is udev-
+ /// only and experimental everywhere, so "off" is correct whether or
+ /// not the eventual backend even has a GPU path at all). `true` here
+ /// only ever *attempts* it - `udev::gpu::probe` still falls back to
+ /// the untouched software path on any failure at any step (no GBM
+ /// device, no atomic-modesetting support, a software-only EGL
+ /// renderer, ...), logged but never fatal, so setting this on a
+ /// machine or VM without real GPU/KMS support costs nothing beyond
+ /// the one failed probe at startup. `SRDWM_GPU=1` (an env var, unset
+ /// by default) remains a separate, lower-level override for testing
+ /// without touching config - `udev::platform::connect` attempts the
+ /// probe if *either* this or the env var says to.
+ pub gpu_enabled: bool,
/// The whole-screen colour treatment currently active (night light's
/// warm tint or reading mode's desaturation), live-settable via `srd
/// set night_light`/`srd set reading_mode` - see [`ColorFilter`]. Off
@@ -349,6 +366,7 @@ impl WindowManager {
shadows_enabled: true,
resize_margin: RESIZE_MARGIN,
rounded_corners_enabled: None,
+ gpu_enabled: false,
color_filter: ColorFilter::None,
focus_follows_mouse: false,
auto_raise: false,
diff --git a/crates/srdwm/src/main.rs b/crates/srdwm/src/main.rs
index 1f33a74..a229d34 100644
--- a/crates/srdwm/src/main.rs
+++ b/crates/srdwm/src/main.rs
@@ -171,6 +171,7 @@ fn apply_general_settings(engine: &Engine, wm: &Rc<RefCell<WindowManager>>) {
// - see `WindowManager::rounded_corners_enabled`'s doc comment for why
// this can't just be `get_bool(..., true)` like every other flag here.
let rounded_corners = engine.get("general.rounded_corners").and_then(|v| v.as_bool());
+ let gpu = engine.get_bool("general.gpu", false);
let focus_follows_mouse = engine.get_bool("general.focus_follows_mouse", false);
let auto_raise = engine.get_bool("general.auto_raise", false);
@@ -295,6 +296,7 @@ fn apply_general_settings(engine: &Engine, wm: &Rc<RefCell<WindowManager>>) {
wm.shadows_enabled = shadows;
wm.resize_margin = resize_margin;
wm.rounded_corners_enabled = rounded_corners;
+ wm.gpu_enabled = gpu;
wm.focus_follows_mouse = focus_follows_mouse;
wm.auto_raise = auto_raise;
wm.theme = theme;
diff --git a/crates/wayland/src/udev/gpu.rs b/crates/wayland/src/udev/gpu.rs
index 904a420..8617af1 100644
--- a/crates/wayland/src/udev/gpu.rs
+++ b/crates/wayland/src/udev/gpu.rs
@@ -1,6 +1,7 @@
-//! 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. Past the original Phase 2 (one output,
+//! Opt-in (`general.gpu` in config, or the lower-level `SRDWM_GPU=1` env
+//! var) 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. 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
@@ -106,15 +107,20 @@ impl GpuContext {
const COLOR_FORMATS: [DrmFourcc; 2] = [DrmFourcc::Argb8888, DrmFourcc::Xrgb8888];
/// Attempts the full GBM+EGL+GLES+`DrmDevice`+`DrmOutputManager` chain
-/// against `card`'s DRM fd, gated behind `SRDWM_GPU=1` (unset - the
-/// default - skips this entirely: zero cost, zero risk, identical to
-/// every session before this one). Returns `None` on *any* failure at any
-/// step, each logged with which step failed and why, so a machine without
-/// working KMS+3D driver support (or a VM with only dumb-buffer scanout --
-/// this backend's own long-standing default target, see `udev/mod.rs`'s
-/// module doc comment) gets one clear, harmless log line instead of
-/// anything touching the actual rendering/modesetting this backend already
-/// does.
+/// against `card`'s DRM fd, gated behind `enabled` (the caller's own
+/// combined decision - `udev/platform.rs`'s call site attempts this
+/// whenever *either* `general.gpu` in config or the lower-level
+/// `SRDWM_GPU=1` env-var override says to; both unset/`false` is the
+/// default, and skips this entirely: zero cost, zero risk, identical to
+/// every session before this option existed). Returns `None` on *any*
+/// failure at any step, each logged with which step failed and why, so a
+/// machine without working KMS+3D driver support (or a VM with only
+/// dumb-buffer scanout - this backend's own long-standing default
+/// target, see `udev/mod.rs`'s module doc comment) gets one clear,
+/// harmless log line instead of anything touching the actual rendering/
+/// modesetting this backend already does, and falls straight back to
+/// that same always-available software path with no further action
+/// needed from whoever enabled this.
///
/// `DrmDevice::new`'s own `disable_connectors` parameter (passed `false`
/// here, matching the existing legacy path's own connector handling) is
@@ -132,8 +138,8 @@ const COLOR_FORMATS: [DrmFourcc; 2] = [DrmFourcc::Argb8888, DrmFourcc::Xrgb8888]
/// is building a ready-to-use `GpuContext`; which head (if any) actually
/// gets driven through it is a per-session, per-head decision the caller
/// (`udev/platform.rs`'s startup path) makes once this succeeds.
-pub(crate) fn probe(card: &Card) -> Option<(GpuContext, DrmDeviceNotifier)> {
- if std::env::var("SRDWM_GPU").as_deref() != Ok("1") {
+pub(crate) fn probe(card: &Card, enabled: bool) -> Option<(GpuContext, DrmDeviceNotifier)> {
+ if !enabled {
return None;
}
// One `DrmDeviceFd` used for everything below - GBM, EGL, and the
diff --git a/crates/wayland/src/udev/platform.rs b/crates/wayland/src/udev/platform.rs
index 19991e8..691c8de 100644
--- a/crates/wayland/src/udev/platform.rs
+++ b/crates/wayland/src/udev/platform.rs
@@ -36,15 +36,21 @@ impl UdevPlatform {
.open(&gpu_path, rustix::fs::OFlags::RDWR | rustix::fs::OFlags::CLOEXEC)
.map_err(err)?;
let card = Rc::new(Card(fd));
- // Opt-in only (`SRDWM_GPU=1`, unset by default) - see `gpu::probe`'s
- // own doc comment for exactly what this does and does not do yet.
- // A no-op unless that variable is set, so this line changes nothing
- // about any session that doesn't set it. `gpu_notifier` is
- // registered as its own calloop event source further down
- // (alongside `register_drm_fd`'s own registration for the
- // existing legacy heads); `gpu_context` is stored on `UdevState`
- // below and consulted by `render_udev_frame`.
- let (mut gpu_context, gpu_notifier) = match super::gpu::probe(&card) {
+ // Opt-in only - `general.gpu` in config (`wm.gpu_enabled`,
+ // `false` by default) or the lower-level `SRDWM_GPU=1` env var,
+ // whichever says yes - see `gpu::probe`'s own doc comment for
+ // exactly what this does and does not do yet. A no-op unless
+ // either says to, so this line changes nothing about any session
+ // that leaves both alone. The env var stays as a quick manual
+ // override for testing without touching config (still works even
+ // if `general.gpu` is explicitly `false`) - it does not gate
+ // config *off*, only ever adds an extra way to opt *in*.
+ // `gpu_notifier` is registered as its own calloop event source
+ // further down (alongside `register_drm_fd`'s own registration
+ // for the existing legacy heads); `gpu_context` is stored on
+ // `UdevState` below and consulted by `render_udev_frame`.
+ let gpu_enabled = wm.borrow().gpu_enabled || std::env::var("SRDWM_GPU").as_deref() == Ok("1");
+ let (mut gpu_context, gpu_notifier) = match super::gpu::probe(&card, gpu_enabled) {
Some((ctx, notifier)) => (Some(ctx), Some(notifier)),
None => (None, None),
};