diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-09-10 10:48:45 +0300 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-09-10 10:48:45 +0300 |
| commit | 6b6a84e55be388589e49fc9ddd8502dd2da7aca9 (patch) | |
| tree | df5b3ab59e57cc6bf819d816c5d4f76276910a41 | |
| parent | 7d5785e96f3deaee1bb279ee16b3b12f05344951 (diff) | |
| download | niri-6b6a84e55be388589e49fc9ddd8502dd2da7aca9.tar.gz niri-6b6a84e55be388589e49fc9ddd8502dd2da7aca9.tar.bz2 niri-6b6a84e55be388589e49fc9ddd8502dd2da7aca9.zip | |
Avoid panics on more wrong VBlank events
| -rw-r--r-- | src/backend/tty.rs | 35 | ||||
| -rw-r--r-- | src/niri.rs | 2 |
2 files changed, 19 insertions, 18 deletions
diff --git a/src/backend/tty.rs b/src/backend/tty.rs index 41e067a9..4b012177 100644 --- a/src/backend/tty.rs +++ b/src/backend/tty.rs @@ -1153,15 +1153,24 @@ impl Tty { return; }; - // This happened for someone reconnecting 2 monitors with a KVM switch: - // https://github.com/YaLTeR/niri/issues/556 - // - // Maybe the vblank didn't get cancelled or got reordered weirdly? Either way, we can avoid - // crashing here. - if matches!(output_state.redraw_state, RedrawState::Idle) { - error!("got vblank for an idle output {name}"); - return; - } + let redraw_needed = match mem::replace(&mut output_state.redraw_state, RedrawState::Idle) { + RedrawState::WaitingForVBlank { redraw_needed } => redraw_needed, + state @ (RedrawState::Idle + | RedrawState::Queued + | RedrawState::WaitingForEstimatedVBlank(_) + | RedrawState::WaitingForEstimatedVBlankAndQueued(_)) => { + // This is an error!() because it shouldn't happen, but on some systems it somehow + // does. Kernel sending rogue vblank events? + // + // https://github.com/YaLTeR/niri/issues/556 + // https://github.com/YaLTeR/niri/issues/615 + error!( + "unexpected redraw state for output {name} (should be WaitingForVBlank); \ + can happen when resuming from sleep or powering on monitors: {state:?}" + ); + true + } + }; // Mark the last frame as submitted. match surface.compositor.frame_submitted() { @@ -1209,14 +1218,6 @@ impl Tty { output_state.frame_clock.presented(presentation_time); - let redraw_needed = match mem::replace(&mut output_state.redraw_state, RedrawState::Idle) { - RedrawState::Idle => unreachable!(), - RedrawState::Queued => unreachable!(), - RedrawState::WaitingForVBlank { redraw_needed } => redraw_needed, - RedrawState::WaitingForEstimatedVBlank(_) => unreachable!(), - RedrawState::WaitingForEstimatedVBlankAndQueued(_) => unreachable!(), - }; - if redraw_needed || output_state.unfinished_animations_remain { let vblank_frame = tracy_client::Client::running() .unwrap() diff --git a/src/niri.rs b/src/niri.rs index 0f43333b..7c87ecc5 100644 --- a/src/niri.rs +++ b/src/niri.rs @@ -344,7 +344,7 @@ pub struct OutputState { pub debug_damage_tracker: OutputDamageTracker, } -#[derive(Default)] +#[derive(Debug, Default)] pub enum RedrawState { /// The compositor is idle. #[default] |
