anvil: bulk-send frame events after each page flip
This commit is contained in:
parent
59f7167702
commit
315797ff43
|
@ -24,7 +24,6 @@ use smithay::{
|
|||
data_device::DnDIconRole,
|
||||
seat::CursorImageRole,
|
||||
shm::with_buffer_contents as shm_buffer_contents,
|
||||
SERIAL_COUNTER as SCOUNTER,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -381,11 +380,6 @@ impl<F: GLGraphicsBackend + 'static> GliumDrawer<F> {
|
|||
},
|
||||
);
|
||||
}
|
||||
|
||||
// send a frame event to the surface if applicable
|
||||
if let Some(callback) = data.borrow_mut().frame_callback.take() {
|
||||
callback.done(SCOUNTER.next_serial());
|
||||
}
|
||||
}
|
||||
},
|
||||
|_, _, _, _| true,
|
||||
|
|
|
@ -694,6 +694,13 @@ impl SurfaceData {
|
|||
|
||||
self.input_region.as_ref().unwrap().contains(point)
|
||||
}
|
||||
|
||||
/// Send the frame callback if it had been requested
|
||||
pub fn send_frame(&mut self, serial: u32) {
|
||||
if let Some(callback) = self.frame_callback.take() {
|
||||
callback.done(serial);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn surface_commit(
|
||||
|
|
|
@ -70,6 +70,8 @@ impl AnvilState {
|
|||
)
|
||||
.expect("Failed to init the wayland event source.");
|
||||
|
||||
// Init the basic compositor globals
|
||||
|
||||
init_shm_global(&mut display.borrow_mut(), vec![], log.clone());
|
||||
|
||||
let (ctoken, _, _, window_map) = init_shell(&mut display.borrow_mut(), buffer_utils, log.clone());
|
||||
|
@ -83,6 +85,8 @@ impl AnvilState {
|
|||
info!(log, "Listening on wayland socket"; "name" => socket_name.clone());
|
||||
::std::env::set_var("WAYLAND_DISPLAY", &socket_name);
|
||||
|
||||
// init data device
|
||||
|
||||
let dnd_icon = Arc::new(Mutex::new(None));
|
||||
|
||||
let dnd_icon2 = dnd_icon.clone();
|
||||
|
|
|
@ -6,6 +6,7 @@ use std::{
|
|||
path::PathBuf,
|
||||
rc::Rc,
|
||||
sync::{atomic::Ordering, Arc, Mutex},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use glium::Surface as GliumSurface;
|
||||
|
@ -20,7 +21,7 @@ use smithay::{
|
|||
common::fallback::FallbackDevice,
|
||||
device_bind,
|
||||
egl::{EglDevice, EglSurface},
|
||||
gbm::{egl::Gbm as EglGbmBackend, GbmDevice},
|
||||
gbm::{egl::Gbm as EglGbmBackend, GbmDevice, GbmSurface},
|
||||
legacy::LegacyDrmDevice,
|
||||
DevPath, Device, DeviceHandler, Surface,
|
||||
},
|
||||
|
@ -56,6 +57,7 @@ use smithay::{
|
|||
data_device::set_data_device_focus,
|
||||
output::{Mode, Output, PhysicalProperties},
|
||||
seat::{CursorImageStatus, Seat, XkbConfig},
|
||||
SERIAL_COUNTER as SCOUNTER,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -63,8 +65,7 @@ use crate::buffer_utils::BufferUtils;
|
|||
use crate::glium_drawer::GliumDrawer;
|
||||
use crate::input_handler::AnvilInputHandler;
|
||||
use crate::shell::{MyWindowMap, Roles};
|
||||
use crate::AnvilState;
|
||||
use smithay::backend::drm::gbm::GbmSurface;
|
||||
use crate::state::AnvilState;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct SessionFd(RawFd);
|
||||
|
@ -238,7 +239,7 @@ pub fn run_udev(
|
|||
|
||||
while state.running.load(Ordering::SeqCst) {
|
||||
if event_loop
|
||||
.dispatch(Some(::std::time::Duration::from_millis(16)), &mut state)
|
||||
.dispatch(Some(Duration::from_millis(16)), &mut state)
|
||||
.is_err()
|
||||
{
|
||||
state.running.store(false, Ordering::SeqCst);
|
||||
|
@ -599,6 +600,9 @@ impl DeviceHandler for DrmHandlerImpl {
|
|||
if let Err(err) = frame.finish() {
|
||||
error!(self.logger, "Error during rendering: {:?}", err);
|
||||
}
|
||||
|
||||
// Send frame events so that client start drawing their next frame
|
||||
self.window_map.borrow().send_frames(SCOUNTER.next_serial());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -169,6 +169,26 @@ where
|
|||
})
|
||||
.unwrap_or(self.bbox)
|
||||
}
|
||||
|
||||
/// Sends the frame callback to all the subsurfaces in this
|
||||
/// window that requested it
|
||||
pub fn send_frame(&self, serial: u32, ctoken: CompositorToken<R>) {
|
||||
if let Some(wl_surface) = self.toplevel.get_surface() {
|
||||
ctoken.with_surface_tree_downward(
|
||||
wl_surface,
|
||||
(),
|
||||
|_, _, _, &()| TraversalAction::DoChildren(()),
|
||||
|_, attributes, _, &()| {
|
||||
// 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)
|
||||
}
|
||||
},
|
||||
|_, _, _, &()| true,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WindowMap<R> {
|
||||
|
@ -291,4 +311,10 @@ where
|
|||
.find(|w| w.toplevel.equals(toplevel))
|
||||
.map(|w| w.geometry(self.ctoken))
|
||||
}
|
||||
|
||||
pub fn send_frames(&self, serial: u32) {
|
||||
for window in &self.windows {
|
||||
window.send_frame(serial, self.ctoken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ use std::{
|
|||
cell::RefCell,
|
||||
rc::Rc,
|
||||
sync::{atomic::Ordering, Arc, Mutex},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use smithay::{
|
||||
|
@ -14,6 +15,7 @@ use smithay::{
|
|||
data_device::set_data_device_focus,
|
||||
output::{Mode, Output, PhysicalProperties},
|
||||
seat::{CursorImageStatus, Seat, XkbConfig},
|
||||
SERIAL_COUNTER as SCOUNTER,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -22,7 +24,7 @@ use slog::Logger;
|
|||
use crate::buffer_utils::BufferUtils;
|
||||
use crate::glium_drawer::GliumDrawer;
|
||||
use crate::input_handler::AnvilInputHandler;
|
||||
use crate::AnvilState;
|
||||
use crate::state::AnvilState;
|
||||
|
||||
pub fn run_winit(
|
||||
display: Rc<RefCell<Display>>,
|
||||
|
@ -164,9 +166,11 @@ pub fn run_winit(
|
|||
error!(log, "Error during rendering: {:?}", err);
|
||||
}
|
||||
}
|
||||
// Send frame events so that client start drawing their next frame
|
||||
state.window_map.borrow().send_frames(SCOUNTER.next_serial());
|
||||
|
||||
if event_loop
|
||||
.dispatch(Some(::std::time::Duration::from_millis(16)), &mut state)
|
||||
.dispatch(Some(Duration::from_millis(16)), &mut state)
|
||||
.is_err()
|
||||
{
|
||||
state.running.store(false, Ordering::SeqCst);
|
||||
|
|
Loading…
Reference in New Issue