srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/crates/wayland/src/udev/mod.rs
diff options
context:
space:
mode:
authorsrdusr <[email protected]>2025-02-17 21:12:00 +0200
committersrdusr <[email protected]>2025-02-17 21:12:00 +0200
commitf7c6e9c607742ed373752aadf5761e99ec3eb64a (patch)
tree433e666d8082821ce70fd97a2851f261fed864b8 /crates/wayland/src/udev/mod.rs
parent413daa7ba2ea0ebd1424c024fd0566423aaea3f8 (diff)
downloadsrdwm-f7c6e9c607742ed373752aadf5761e99ec3eb64a.tar.gz
srdwm-f7c6e9c607742ed373752aadf5761e99ec3eb64a.zip
Checkpoint: today's fixes before reconciling with the rust-rewrite worktree
Fixes a live-reproduced VT-switch busy loop (failed page_flip retried with no backoff), shadow rendering bleeding onto occluding windows unclipped, and a winit-backend buffer-age correctness bug that left stale cross-window pixels on screen. Committing before merging in the much larger uncommitted rust-rewrite worktree, which independently touches several of the same files - this is the pre-merge baseline to diff against, not a claim that these are the final versions of these fixes.
Diffstat (limited to 'crates/wayland/src/udev/mod.rs')
-rw-r--r--crates/wayland/src/udev/mod.rs24
1 files changed, 24 insertions, 0 deletions
diff --git a/crates/wayland/src/udev/mod.rs b/crates/wayland/src/udev/mod.rs
index 501e3fc..9a6bf49 100644
--- a/crates/wayland/src/udev/mod.rs
+++ b/crates/wayland/src/udev/mod.rs
@@ -149,6 +149,30 @@ pub(crate) struct UdevHead {
/// Origin of this head in the global coordinate space.
pub(crate) location: Point<i32, Logical>,
pub(crate) size: (i32, i32),
+ /// Set when [`UdevHead::copy_and_flip`] fails; no new flip is attempted
+ /// for this head again until this deadline passes.
+ ///
+ /// Without this, a failed `page_flip` (real and reproduced live: the
+ /// kernel returns `EBUSY`/"device or resource busy" for a brief window
+ /// right after a VT-switch resume's `set_crtc` reasserts the mode,
+ /// before that commit has actually settled) left `flip_pending` still
+ /// `false` - `copy_and_flip`'s early-return `?` on the failing
+ /// `page_flip` call skips the line just after it that would have set
+ /// `flip_pending = true`, so nothing ever marked this head "busy". The
+ /// next call to `render_udev_frame` (every ~16ms, or sooner --
+ /// `event_loop.dispatch`'s timeout is only an upper bound) saw the
+ /// exact same head still "ready" and every prior damage still pending,
+ /// tried the exact same flip again, failed the exact same way, forever
+ /// - a true busy loop with no backoff at all, not merely a missed
+ /// optimization. Confirmed live from a real session log: tens of
+ /// thousands of consecutive `page flip failed: Device or resource
+ /// busy` lines a few *microseconds* apart, the compositor's one thread
+ /// spinning flat out on nothing else, which is what actually explains
+ /// the user's report of losing pointer input and the ability to
+ /// switch VTs at all after switching away and back once - not a
+ /// separate input bug, this loop simply never yielded the CPU back to
+ /// anything else, libinput's own event processing included.
+ pub(crate) flip_retry_after: Option<Instant>,
}
/// Everything the DRM/udev backend needs that the nested winit backend