anvil: send millisecond time in frame callback

This is what the protocol requires, and apps rely on it to figure
out how long time elapsed between draws.
This commit is contained in:
Victor Berger 2020-10-10 20:01:18 +02:00 committed by Victor Berger
parent 04625405a0
commit 5421b9675c
4 changed files with 18 additions and 11 deletions

View File

@ -755,9 +755,9 @@ impl SurfaceData {
}
/// Send the frame callback if it had been requested
pub fn send_frame(&mut self, serial: Serial) {
pub fn send_frame(&mut self, time: u32) {
if let Some(callback) = self.current_state.frame_callback.take() {
callback.done(serial.into());
callback.done(time);
}
}
}

View File

@ -59,7 +59,6 @@ use smithay::{
compositor::CompositorToken,
output::{Mode, Output, PhysicalProperties},
seat::CursorImageStatus,
SERIAL_COUNTER as SCOUNTER,
},
};
@ -450,6 +449,7 @@ impl<Data: 'static> UdevHandlerImpl<Data> {
cursor_status: self.cursor_status.clone(),
dnd_icon: self.dnd_icon.clone(),
logger: self.logger.clone(),
start_time: std::time::Instant::now(),
});
let mut listener = DrmRendererSessionListener {
renderer: renderer.clone(),
@ -582,6 +582,7 @@ pub struct DrmRenderer {
cursor_status: Arc<Mutex<CursorImageStatus>>,
dnd_icon: Arc<Mutex<Option<wl_surface::WlSurface>>>,
logger: ::slog::Logger,
start_time: std::time::Instant,
}
impl DrmRenderer {
@ -727,7 +728,9 @@ impl DrmRenderer {
} else {
// TODO: only send drawn windows the frames callback
// Send frame events so that client start drawing their next frame
self.window_map.borrow().send_frames(SCOUNTER.next_serial());
self.window_map
.borrow()
.send_frames(self.start_time.elapsed().as_millis() as u32);
}
}
}

View File

@ -9,7 +9,6 @@ use smithay::{
legacy::{ShellSurface, ShellSurfaceRole},
xdg::{ToplevelSurface, XdgSurfaceRole},
},
Serial,
},
};
@ -173,7 +172,7 @@ where
/// Sends the frame callback to all the subsurfaces in this
/// window that requested it
pub fn send_frame(&self, serial: Serial, ctoken: CompositorToken<R>) {
pub fn send_frame(&self, time: u32, ctoken: CompositorToken<R>) {
if let Some(wl_surface) = self.toplevel.get_surface() {
ctoken.with_surface_tree_downward(
wl_surface,
@ -183,7 +182,7 @@ where
// the surface may not have any user_data if it is a subsurface and has not
// yet been commited
if let Some(data) = attributes.user_data.get::<RefCell<SurfaceData>>() {
data.borrow_mut().send_frame(serial)
data.borrow_mut().send_frame(time)
}
},
|_, _, _, &()| true,
@ -313,9 +312,9 @@ where
.map(|w| w.geometry(self.ctoken))
}
pub fn send_frames(&self, serial: Serial) {
pub fn send_frames(&self, time: u32) {
for window in &self.windows {
window.send_frame(serial, self.ctoken);
window.send_frame(time, self.ctoken);
}
}
}

View File

@ -12,7 +12,6 @@ use smithay::{
wayland::{
output::{Mode, Output, PhysicalProperties},
seat::CursorImageStatus,
SERIAL_COUNTER as SCOUNTER,
},
};
@ -90,6 +89,8 @@ pub fn run_winit(
refresh: 60_000,
});
let start_time = std::time::Instant::now();
info!(log, "Initialization completed, starting the main loop.");
while state.running.load(Ordering::SeqCst) {
@ -140,7 +141,11 @@ pub fn run_winit(
}
}
// Send frame events so that client start drawing their next frame
state.window_map.borrow().send_frames(SCOUNTER.next_serial());
state
.window_map
.borrow()
.send_frames(start_time.elapsed().as_millis() as u32);
display.borrow_mut().flush_clients(&mut state);
if event_loop
.dispatch(Some(Duration::from_millis(16)), &mut state)