Avoid panics on more wrong VBlank events

This commit is contained in:
Ivan Molodetskikh
2024-09-10 10:48:45 +03:00
parent 7d5785e96f
commit 6b6a84e55b
2 changed files with 19 additions and 18 deletions
+18 -17
View File
@@ -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()
+1 -1
View File
@@ -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]