chore: Update to newest smithay/calloop
This commit is contained in:
parent
8ac85c4112
commit
b07ac107b1
8 changed files with 218 additions and 107 deletions
|
|
@ -27,8 +27,8 @@ use smithay::{
|
|||
},
|
||||
reexports::{
|
||||
calloop::{
|
||||
timer::{Timer, TimerHandle},
|
||||
Dispatcher, EventLoop, LoopHandle, RegistrationToken,
|
||||
timer::{TimeoutAction, Timer},
|
||||
Dispatcher, EventLoop, InsertError, LoopHandle, RegistrationToken,
|
||||
},
|
||||
drm::control::{connector, crtc, Device as ControlDevice, ModeTypeFlags},
|
||||
input::Libinput,
|
||||
|
|
@ -44,7 +44,7 @@ use std::{
|
|||
collections::{HashMap, HashSet},
|
||||
path::PathBuf,
|
||||
rc::Rc,
|
||||
time::{Duration, Instant, SystemTime},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
mod drm_helpers;
|
||||
|
|
@ -82,7 +82,6 @@ pub struct Surface {
|
|||
refresh_rate: u32,
|
||||
vrr: bool,
|
||||
pending: bool,
|
||||
render_timer: TimerHandle<(DrmNode, crtc::Handle)>,
|
||||
render_timer_token: Option<RegistrationToken>,
|
||||
#[cfg(feature = "debug")]
|
||||
fps: Fps,
|
||||
|
|
@ -109,7 +108,13 @@ pub fn init_backend(event_loop: &mut EventLoop<'static, State>, state: &mut Stat
|
|||
}
|
||||
state.process_input_event(event);
|
||||
for output in state.common.shell.outputs() {
|
||||
state.backend.kms().schedule_render(output);
|
||||
if let Err(err) = state
|
||||
.backend
|
||||
.kms()
|
||||
.schedule_render(&state.common.event_loop_handle, output)
|
||||
{
|
||||
slog_scope::crit!("Error scheduling event loop for output {}: {:?}", output.name(), err);
|
||||
}
|
||||
}
|
||||
})
|
||||
.map_err(|err| err.error)
|
||||
|
|
@ -219,6 +224,7 @@ pub fn init_backend(event_loop: &mut EventLoop<'static, State>, state: &mut Stat
|
|||
state.common.output_conf.outputs(),
|
||||
&mut state.backend,
|
||||
&mut state.common.shell,
|
||||
&state.common.event_loop_handle,
|
||||
);
|
||||
state.common.shell.refresh_outputs();
|
||||
state
|
||||
|
|
@ -236,7 +242,13 @@ pub fn init_backend(event_loop: &mut EventLoop<'static, State>, state: &mut Stat
|
|||
surface.pending = false;
|
||||
}
|
||||
for output in state.common.shell.outputs() {
|
||||
state.backend.kms().schedule_render(output);
|
||||
if let Err(err) = state
|
||||
.backend
|
||||
.kms()
|
||||
.schedule_render(&state.common.event_loop_handle, output)
|
||||
{
|
||||
slog_scope::crit!("Error scheduling event loop for output {}: {:?}", output.name(), err);
|
||||
}
|
||||
}
|
||||
});
|
||||
loop_signal.wakeup();
|
||||
|
|
@ -382,7 +394,7 @@ impl State {
|
|||
let mut wl_outputs = Vec::new();
|
||||
let mut w = self.common.shell.global_space().size.w;
|
||||
for (crtc, conn) in outputs {
|
||||
match device.setup_surface(crtc, conn, &mut self.common.event_loop_handle, (0, w)) {
|
||||
match device.setup_surface(crtc, conn, (0, w)) {
|
||||
Ok(output) => {
|
||||
w += output
|
||||
.user_data()
|
||||
|
|
@ -403,11 +415,12 @@ impl State {
|
|||
.output_conf
|
||||
.update(&mut *self.common.display.borrow_mut());
|
||||
for output in wl_outputs {
|
||||
if let Err(err) =
|
||||
self.backend
|
||||
.kms()
|
||||
.apply_config_for_output(&output, &mut self.common.shell, false)
|
||||
{
|
||||
if let Err(err) = self.backend.kms().apply_config_for_output(
|
||||
&output,
|
||||
&mut self.common.shell,
|
||||
false,
|
||||
&self.common.event_loop_handle,
|
||||
) {
|
||||
slog_scope::warn!("Failed to initialize output: {}", err);
|
||||
}
|
||||
}
|
||||
|
|
@ -415,6 +428,7 @@ impl State {
|
|||
self.common.output_conf.outputs(),
|
||||
&mut self.backend,
|
||||
&mut self.common.shell,
|
||||
&self.common.event_loop_handle,
|
||||
);
|
||||
self.common.shell.refresh_outputs();
|
||||
self.common
|
||||
|
|
@ -445,7 +459,7 @@ impl State {
|
|||
}
|
||||
}
|
||||
for (crtc, conn) in changes.added {
|
||||
match device.setup_surface(crtc, conn, &mut self.common.event_loop_handle, (0, w)) {
|
||||
match device.setup_surface(crtc, conn, (0, w)) {
|
||||
Ok(output) => {
|
||||
w += output
|
||||
.user_data()
|
||||
|
|
@ -464,11 +478,12 @@ impl State {
|
|||
self.common.output_conf.remove_heads(outputs_removed.iter());
|
||||
self.common.output_conf.add_heads(outputs_added.iter());
|
||||
for output in outputs_added {
|
||||
if let Err(err) =
|
||||
self.backend
|
||||
.kms()
|
||||
.apply_config_for_output(&output, &mut self.common.shell, false)
|
||||
{
|
||||
if let Err(err) = self.backend.kms().apply_config_for_output(
|
||||
&output,
|
||||
&mut self.common.shell,
|
||||
false,
|
||||
&self.common.event_loop_handle,
|
||||
) {
|
||||
slog_scope::warn!("Failed to initialize output: {}", err);
|
||||
}
|
||||
}
|
||||
|
|
@ -479,6 +494,7 @@ impl State {
|
|||
self.common.output_conf.outputs(),
|
||||
&mut self.backend,
|
||||
&mut self.common.shell,
|
||||
&self.common.event_loop_handle,
|
||||
);
|
||||
self.common.shell.refresh_outputs();
|
||||
self.common
|
||||
|
|
@ -515,6 +531,7 @@ impl State {
|
|||
self.common.output_conf.outputs(),
|
||||
&mut self.backend,
|
||||
&mut self.common.shell,
|
||||
&self.common.event_loop_handle,
|
||||
);
|
||||
self.common.shell.refresh_outputs();
|
||||
self.common
|
||||
|
|
@ -563,7 +580,6 @@ impl Device {
|
|||
&mut self,
|
||||
crtc: crtc::Handle,
|
||||
conn: connector::Handle,
|
||||
loop_handle: &mut LoopHandle<'static, State>,
|
||||
position: (i32, i32),
|
||||
) -> Result<Output> {
|
||||
let drm = &mut *self.drm.as_source_mut();
|
||||
|
|
@ -622,27 +638,6 @@ impl Device {
|
|||
})
|
||||
});
|
||||
|
||||
let timer = Timer::new()?;
|
||||
let timer_handle = timer.handle();
|
||||
// render timer
|
||||
let timer_token = loop_handle
|
||||
.insert_source(timer, |(dev_id, crtc), _, state| {
|
||||
let backend = state.backend.kms();
|
||||
if let Some(device) = backend.devices.get_mut(&dev_id) {
|
||||
if let Some(surface) = device.surfaces.get_mut(&crtc) {
|
||||
if let Err(err) = surface.render_output(
|
||||
&mut backend.api,
|
||||
&device.render_node,
|
||||
&mut state.common,
|
||||
) {
|
||||
slog_scope::error!("Error rendering: {}", err);
|
||||
// TODO re-schedule?
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let data = Surface {
|
||||
output: output.clone(),
|
||||
surface: None,
|
||||
|
|
@ -651,8 +646,7 @@ impl Device {
|
|||
refresh_rate,
|
||||
last_submit: None,
|
||||
pending: false,
|
||||
render_timer: timer_handle,
|
||||
render_timer_token: Some(timer_token),
|
||||
render_timer_token: None,
|
||||
#[cfg(feature = "debug")]
|
||||
fps: Fps::default(),
|
||||
};
|
||||
|
|
@ -756,6 +750,7 @@ impl KmsState {
|
|||
output: &Output,
|
||||
shell: &mut Shell,
|
||||
test_only: bool,
|
||||
loop_handle: &LoopHandle<'_, State>,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
let recreated = if let Some(device) = self
|
||||
.devices
|
||||
|
|
@ -840,12 +835,18 @@ impl KmsState {
|
|||
|
||||
shell.refresh_outputs();
|
||||
if recreated {
|
||||
self.schedule_render(output);
|
||||
if let Err(err) = self.schedule_render(loop_handle, output) {
|
||||
slog_scope::crit!("Error scheduling event loop for output {}: {:?}", output.name(), err);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn schedule_render(&mut self, output: &Output) {
|
||||
pub fn schedule_render(
|
||||
&mut self,
|
||||
loop_handle: &LoopHandle<'_, State>,
|
||||
output: &Output,
|
||||
) -> Result<(), InsertError<Timer>> {
|
||||
if let Some((device, crtc, surface)) = self
|
||||
.devices
|
||||
.iter_mut()
|
||||
|
|
@ -853,29 +854,53 @@ impl KmsState {
|
|||
.find(|(_, _, s)| s.output == *output)
|
||||
{
|
||||
if surface.surface.is_none() {
|
||||
return;
|
||||
return Ok(());
|
||||
}
|
||||
if !surface.pending {
|
||||
surface.pending = true;
|
||||
/*
|
||||
let duration = surface
|
||||
let instant = surface
|
||||
.last_submit
|
||||
.as_ref()
|
||||
.and_then(|x| match x {
|
||||
DrmEventTime::Monotonic(instant) => {
|
||||
instant.checked_duration_since(Instant::now())
|
||||
}
|
||||
DrmEventTime::Realtime(time) => time.duration_since(SystemTime::now()).ok(),
|
||||
DrmEventTime::Monotonic(instant) => Some(instant),
|
||||
DrmEventTime::Realtime(_) => None,
|
||||
})
|
||||
.unwrap_or(Duration::ZERO); // + Duration::from_secs_f64((1.0 / surface.refresh_rate as f64) - 20.0);
|
||||
.map(|i| {
|
||||
*i + Duration::from_secs_f64(1.0 / surface.refresh_rate as f64)
|
||||
- Duration::from_millis(20) // render budget
|
||||
});
|
||||
*/
|
||||
let data = (*device, *crtc);
|
||||
//if surface.vrr {
|
||||
surface.render_timer.add_timeout(Duration::ZERO, data);
|
||||
//} else {
|
||||
// surface.render_timer.add_timeout(duration, data);
|
||||
//}
|
||||
|
||||
let device = *device;
|
||||
let crtc = *crtc;
|
||||
surface.render_timer_token = Some(loop_handle.insert_source(
|
||||
//if surface.vrr || instant.is_none() {
|
||||
Timer::immediate()
|
||||
/*} else {
|
||||
Timer::from_deadline(instant.unwrap())
|
||||
}*/,
|
||||
move |_time, _, state| {
|
||||
let backend = state.backend.kms();
|
||||
if let Some(device) = backend.devices.get_mut(&device) {
|
||||
if let Some(surface) = device.surfaces.get_mut(&crtc) {
|
||||
if let Err(err) = surface.render_output(
|
||||
&mut backend.api,
|
||||
&device.render_node,
|
||||
&mut state.common,
|
||||
) {
|
||||
slog_scope::error!("Error rendering: {}", err);
|
||||
return TimeoutAction::ToDuration(Duration::from_secs_f64(
|
||||
1.0 / surface.refresh_rate as f64,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
TimeoutAction::Drop
|
||||
},
|
||||
)?);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -210,6 +210,7 @@ pub fn init_backend(event_loop: &mut EventLoop<State>, state: &mut State) -> Res
|
|||
std::iter::once(&output),
|
||||
&mut state.backend,
|
||||
&mut state.common.shell,
|
||||
&state.common.event_loop_handle,
|
||||
);
|
||||
state.common.shell.refresh_outputs();
|
||||
state.common.config.write_outputs(std::iter::once(&output));
|
||||
|
|
|
|||
|
|
@ -268,6 +268,7 @@ pub fn init_backend(event_loop: &mut EventLoop<State>, state: &mut State) -> Res
|
|||
std::iter::once(&output),
|
||||
&mut state.backend,
|
||||
&mut state.common.shell,
|
||||
&state.common.event_loop_handle,
|
||||
);
|
||||
state.common.shell.refresh_outputs();
|
||||
state.common.config.write_outputs(std::iter::once(&output));
|
||||
|
|
@ -414,7 +415,8 @@ impl State {
|
|||
self.process_input_event(event);
|
||||
// TODO actually figure out the output
|
||||
for output in self.common.shell.outputs() {
|
||||
self.backend.schedule_render(output);
|
||||
self.backend
|
||||
.schedule_render(&self.common.event_loop_handle, output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,14 +2,17 @@
|
|||
|
||||
use crate::{
|
||||
shell::{layout::FocusDirection, Shell},
|
||||
state::BackendData,
|
||||
state::{BackendData, State},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
pub use smithay::{
|
||||
backend::input::KeyState,
|
||||
reexports::input::{
|
||||
AccelProfile, ClickMethod, Device as InputDevice, ScrollMethod, SendEventsMode,
|
||||
TapButtonMap,
|
||||
reexports::{
|
||||
calloop::LoopHandle,
|
||||
input::{
|
||||
AccelProfile, ClickMethod, Device as InputDevice, ScrollMethod, SendEventsMode,
|
||||
TapButtonMap,
|
||||
},
|
||||
},
|
||||
utils::{Logical, Physical, Point, Size, Transform},
|
||||
wayland::{
|
||||
|
|
@ -270,6 +273,7 @@ impl Config {
|
|||
outputs: impl Iterator<Item = impl std::borrow::Borrow<Output>>,
|
||||
backend: &mut BackendData,
|
||||
shell: &mut Shell,
|
||||
loop_handle: &LoopHandle<'_, State>,
|
||||
) {
|
||||
let outputs = outputs.map(|x| x.borrow().clone()).collect::<Vec<_>>();
|
||||
let mut infos = outputs
|
||||
|
|
@ -300,7 +304,9 @@ impl Config {
|
|||
.get::<RefCell<OutputConfig>>()
|
||||
.unwrap()
|
||||
.borrow_mut() = output_config;
|
||||
if let Err(err) = backend.apply_config_for_output(&output, false, shell) {
|
||||
if let Err(err) =
|
||||
backend.apply_config_for_output(&output, false, shell, loop_handle)
|
||||
{
|
||||
slog_scope::warn!(
|
||||
"Failed to set new config for output {}: {}",
|
||||
output.name(),
|
||||
|
|
@ -322,7 +328,9 @@ impl Config {
|
|||
.get::<RefCell<OutputConfig>>()
|
||||
.unwrap()
|
||||
.borrow_mut() = output_config;
|
||||
if let Err(err) = backend.apply_config_for_output(&output, false, shell) {
|
||||
if let Err(err) =
|
||||
backend.apply_config_for_output(&output, false, shell, loop_handle)
|
||||
{
|
||||
slog_scope::error!(
|
||||
"Failed to reset config for output {}: {}",
|
||||
output.name(),
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ fn main() -> Result<()> {
|
|||
slog_scope::info!("Cosmic starting up!");
|
||||
|
||||
// init event loop
|
||||
let mut event_loop = EventLoop::try_new().with_context(|| "Failed to initialize event loop")?;
|
||||
let mut event_loop =
|
||||
EventLoop::try_new_high_precision().with_context(|| "Failed to initialize event loop")?;
|
||||
// init wayland
|
||||
let (display, socket) = init_wayland_display(&mut event_loop)?;
|
||||
// init state
|
||||
|
|
@ -56,7 +57,9 @@ fn main() -> Result<()> {
|
|||
// do we need to trigger another render
|
||||
if state.common.dirty_flag.swap(false, Ordering::SeqCst) {
|
||||
for output in state.common.shell.outputs() {
|
||||
state.backend.schedule_render(output)
|
||||
state
|
||||
.backend
|
||||
.schedule_render(&state.common.event_loop_handle, output)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -83,7 +86,7 @@ fn init_wayland_display(event_loop: &mut EventLoop<state::State>) -> Result<(Dis
|
|||
event_loop
|
||||
.handle()
|
||||
.insert_source(
|
||||
Generic::from_fd(display.get_poll_fd(), Interest::READ, Mode::Level),
|
||||
Generic::new(display.get_poll_fd(), Interest::READ, Mode::Level),
|
||||
move |_, _, state: &mut state::State| {
|
||||
let display = state.common.display.clone();
|
||||
let mut display = display.borrow_mut();
|
||||
|
|
|
|||
|
|
@ -312,7 +312,9 @@ fn commit(surface: &WlSurface, state: &mut State) {
|
|||
// TODO figure out which output the surface is on.
|
||||
for output in state.common.shell.outputs() {
|
||||
//.cloned().collect::<Vec<_>>().into_iter() {
|
||||
state.backend.schedule_render(output);
|
||||
state
|
||||
.backend
|
||||
.schedule_render(&state.common.event_loop_handle, output);
|
||||
// let space = state.common.spaces.active_space(output);
|
||||
// get output for surface
|
||||
}
|
||||
|
|
|
|||
13
src/state.rs
13
src/state.rs
|
|
@ -118,10 +118,11 @@ impl BackendData {
|
|||
output: &Output,
|
||||
test_only: bool,
|
||||
shell: &mut Shell,
|
||||
loop_handle: &LoopHandle<'_, State>,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
let result = match self {
|
||||
BackendData::Kms(ref mut state) => {
|
||||
state.apply_config_for_output(output, shell, test_only)
|
||||
state.apply_config_for_output(output, shell, test_only, loop_handle)
|
||||
}
|
||||
BackendData::Winit(ref mut state) => state.apply_config_for_output(output, test_only),
|
||||
BackendData::X11(ref mut state) => state.apply_config_for_output(output, test_only),
|
||||
|
|
@ -155,13 +156,17 @@ impl BackendData {
|
|||
result
|
||||
}
|
||||
|
||||
pub fn schedule_render(&mut self, output: &Output) {
|
||||
pub fn schedule_render(&mut self, loop_handle: &LoopHandle<'_, State>, output: &Output) {
|
||||
match self {
|
||||
BackendData::Winit(_) => {} // We cannot do this on the winit backend.
|
||||
// Winit has a very strict render-loop and skipping frames breaks atleast the wayland winit-backend.
|
||||
// Swapping with damage (which should be empty on these frames) is likely good enough anyway.
|
||||
BackendData::X11(ref mut state) => state.schedule_render(output),
|
||||
BackendData::Kms(ref mut state) => state.schedule_render(output),
|
||||
BackendData::Kms(ref mut state) => {
|
||||
if let Err(err) = state.schedule_render(loop_handle, output) {
|
||||
slog_scope::crit!("Failed to schedule event, are we shutting down? {:?}", err);
|
||||
}
|
||||
}
|
||||
_ => unreachable!("No backend was initialized"),
|
||||
}
|
||||
}
|
||||
|
|
@ -264,6 +269,7 @@ impl State {
|
|||
output,
|
||||
test_only,
|
||||
&mut state.common.shell,
|
||||
&state.common.event_loop_handle,
|
||||
) {
|
||||
slog_scope::warn!(
|
||||
"Failed to apply config to {}: {}. Resetting",
|
||||
|
|
@ -284,6 +290,7 @@ impl State {
|
|||
output,
|
||||
false,
|
||||
&mut state.common.shell,
|
||||
&state.common.event_loop_handle,
|
||||
) {
|
||||
slog_scope::error!(
|
||||
"Failed to reset output config for {}: {}",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue