kms: Fix damage issues due to timing
This commit is contained in:
parent
fcf39337a7
commit
48c071466f
2 changed files with 55 additions and 12 deletions
|
|
@ -10,7 +10,7 @@ use crate::{
|
||||||
state::{BackendData, ClientState, Common, Data},
|
state::{BackendData, ClientState, Common, Data},
|
||||||
utils::prelude::*,
|
utils::prelude::*,
|
||||||
wayland::{
|
wayland::{
|
||||||
handlers::screencopy::UserdataExt,
|
handlers::screencopy::{PendingScreencopyBuffers, UserdataExt},
|
||||||
protocols::screencopy::{BufferParams, Session as ScreencopySession},
|
protocols::screencopy::{BufferParams, Session as ScreencopySession},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -97,6 +97,7 @@ pub struct Surface {
|
||||||
refresh_rate: u32,
|
refresh_rate: u32,
|
||||||
vrr: bool,
|
vrr: bool,
|
||||||
pending: bool,
|
pending: bool,
|
||||||
|
dirty: bool,
|
||||||
render_timer_token: Option<RegistrationToken>,
|
render_timer_token: Option<RegistrationToken>,
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
fps: Fps,
|
fps: Fps,
|
||||||
|
|
@ -375,18 +376,44 @@ impl State {
|
||||||
let dispatcher =
|
let dispatcher =
|
||||||
Dispatcher::new(drm, move |event, metadata, data: &mut Data| match event {
|
Dispatcher::new(drm, move |event, metadata, data: &mut Data| match event {
|
||||||
DrmEvent::VBlank(crtc) => {
|
DrmEvent::VBlank(crtc) => {
|
||||||
if let Some(device) = data.state.backend.kms().devices.get_mut(&drm_node) {
|
let rescheduled_output =
|
||||||
if let Some(surface) = device.surfaces.get_mut(&crtc) {
|
if let Some(device) = data.state.backend.kms().devices.get_mut(&drm_node) {
|
||||||
match surface.surface.as_mut().map(|x| x.frame_submitted()) {
|
if let Some(surface) = device.surfaces.get_mut(&crtc) {
|
||||||
Some(Ok(_)) => {
|
match surface.surface.as_mut().map(|x| x.frame_submitted()) {
|
||||||
let _submit_time = metadata.take().map(|data| data.time);
|
Some(Ok(_)) => {
|
||||||
surface.pending = false;
|
let _submit_time = metadata.take().map(|data| data.time);
|
||||||
|
surface.pending = false;
|
||||||
|
surface.dirty.then(|| surface.output.clone())
|
||||||
|
}
|
||||||
|
Some(Err(err)) => {
|
||||||
|
slog_scope::warn!("Failed to submit frame: {}", err);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
_ => None, // got disabled
|
||||||
}
|
}
|
||||||
Some(Err(err)) => {
|
} else {
|
||||||
slog_scope::warn!("Failed to submit frame: {}", err)
|
None
|
||||||
}
|
}
|
||||||
None => {} // got disabled
|
} else {
|
||||||
};
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(output) = rescheduled_output {
|
||||||
|
let mut scheduled_sessions =
|
||||||
|
data.state.workspace_session_for_output(&output);
|
||||||
|
if let Some(sessions) = output.user_data().get::<PendingScreencopyBuffers>()
|
||||||
|
{
|
||||||
|
scheduled_sessions
|
||||||
|
.get_or_insert_with(Vec::new)
|
||||||
|
.extend(sessions.borrow_mut().drain(..));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Err(err) = data.state.backend.kms().schedule_render(
|
||||||
|
&data.state.common.event_loop_handle,
|
||||||
|
&output,
|
||||||
|
scheduled_sessions,
|
||||||
|
) {
|
||||||
|
slog_scope::warn!("Failed to schedule render: {}", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -697,6 +724,7 @@ impl Device {
|
||||||
vrr,
|
vrr,
|
||||||
refresh_rate,
|
refresh_rate,
|
||||||
pending: false,
|
pending: false,
|
||||||
|
dirty: false,
|
||||||
render_timer_token: None,
|
render_timer_token: None,
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
fps: Fps::default(),
|
fps: Fps::default(),
|
||||||
|
|
@ -986,6 +1014,7 @@ impl KmsState {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
if !surface.pending {
|
if !surface.pending {
|
||||||
|
surface.dirty = false;
|
||||||
surface.pending = true;
|
surface.pending = true;
|
||||||
/*
|
/*
|
||||||
let instant = surface
|
let instant = surface
|
||||||
|
|
@ -1039,6 +1068,8 @@ impl KmsState {
|
||||||
TimeoutAction::Drop
|
TimeoutAction::Drop
|
||||||
},
|
},
|
||||||
)?);
|
)?);
|
||||||
|
} else {
|
||||||
|
surface.dirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -901,6 +901,18 @@ impl State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn workspace_session_for_output(
|
||||||
|
&mut self,
|
||||||
|
output: &Output,
|
||||||
|
) -> Option<Vec<(Session, BufferParams)>> {
|
||||||
|
let workspace = self.common.shell.active_space_mut(output);
|
||||||
|
if !workspace.pending_buffers.is_empty() {
|
||||||
|
Some(std::mem::take(&mut workspace.pending_buffers))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn schedule_workspace_sessions(
|
pub fn schedule_workspace_sessions(
|
||||||
&mut self,
|
&mut self,
|
||||||
surface: &WlSurface,
|
surface: &WlSurface,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue