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 /// 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() { 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, compositor::CompositorToken,
output::{Mode, Output, PhysicalProperties}, output::{Mode, Output, PhysicalProperties},
seat::CursorImageStatus, seat::CursorImageStatus,
SERIAL_COUNTER as SCOUNTER,
}, },
}; };
@ -450,6 +449,7 @@ impl<Data: 'static> UdevHandlerImpl<Data> {
cursor_status: self.cursor_status.clone(), cursor_status: self.cursor_status.clone(),
dnd_icon: self.dnd_icon.clone(), dnd_icon: self.dnd_icon.clone(),
logger: self.logger.clone(), logger: self.logger.clone(),
start_time: std::time::Instant::now(),
}); });
let mut listener = DrmRendererSessionListener { let mut listener = DrmRendererSessionListener {
renderer: renderer.clone(), renderer: renderer.clone(),
@ -582,6 +582,7 @@ pub struct DrmRenderer {
cursor_status: Arc<Mutex<CursorImageStatus>>, cursor_status: Arc<Mutex<CursorImageStatus>>,
dnd_icon: Arc<Mutex<Option<wl_surface::WlSurface>>>, dnd_icon: Arc<Mutex<Option<wl_surface::WlSurface>>>,
logger: ::slog::Logger, logger: ::slog::Logger,
start_time: std::time::Instant,
} }
impl DrmRenderer { impl DrmRenderer {
@ -727,7 +728,9 @@ impl DrmRenderer {
} else { } else {
// TODO: only send drawn windows the frames callback // TODO: only send drawn windows the frames callback
// Send frame events so that client start drawing their next frame // 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}, legacy::{ShellSurface, ShellSurfaceRole},
xdg::{ToplevelSurface, XdgSurfaceRole}, xdg::{ToplevelSurface, XdgSurfaceRole},
}, },
Serial,
}, },
}; };
@ -173,7 +172,7 @@ where
/// Sends the frame callback to all the subsurfaces in this /// Sends the frame callback to all the subsurfaces in this
/// window that requested it /// 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() { if let Some(wl_surface) = self.toplevel.get_surface() {
ctoken.with_surface_tree_downward( ctoken.with_surface_tree_downward(
wl_surface, wl_surface,
@ -183,7 +182,7 @@ where
// the surface may not have any user_data if it is a subsurface and has not // the surface may not have any user_data if it is a subsurface and has not
// yet been commited // yet been commited
if let Some(data) = attributes.user_data.get::<RefCell<SurfaceData>>() { if let Some(data) = attributes.user_data.get::<RefCell<SurfaceData>>() {
data.borrow_mut().send_frame(serial) data.borrow_mut().send_frame(time)
} }
}, },
|_, _, _, &()| true, |_, _, _, &()| true,
@ -313,9 +312,9 @@ where
.map(|w| w.geometry(self.ctoken)) .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 { 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::{ wayland::{
output::{Mode, Output, PhysicalProperties}, output::{Mode, Output, PhysicalProperties},
seat::CursorImageStatus, seat::CursorImageStatus,
SERIAL_COUNTER as SCOUNTER,
}, },
}; };
@ -90,6 +89,8 @@ pub fn run_winit(
refresh: 60_000, refresh: 60_000,
}); });
let start_time = std::time::Instant::now();
info!(log, "Initialization completed, starting the main loop."); info!(log, "Initialization completed, starting the main loop.");
while state.running.load(Ordering::SeqCst) { 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 // 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 if event_loop
.dispatch(Some(Duration::from_millis(16)), &mut state) .dispatch(Some(Duration::from_millis(16)), &mut state)