make the frame_callback a list

This commit is contained in:
Christian Meissl 2021-05-23 11:44:21 +02:00 committed by Victor Berger
parent 9d16e7d8bb
commit 4f0161658f
3 changed files with 21 additions and 21 deletions

View File

@ -677,7 +677,7 @@ pub struct CommitedState {
pub buffer: Option<wl_buffer::WlBuffer>, pub buffer: Option<wl_buffer::WlBuffer>,
pub input_region: Option<RegionAttributes>, pub input_region: Option<RegionAttributes>,
pub dimensions: Option<(i32, i32)>, pub dimensions: Option<(i32, i32)>,
pub frame_callback: Option<wl_callback::WlCallback>, pub frame_callbacks: Vec<wl_callback::WlCallback>,
pub sub_location: (i32, i32), pub sub_location: (i32, i32),
} }
@ -734,12 +734,6 @@ impl SurfaceData {
buffer.release(); buffer.release();
} }
} }
// ping the previous callback if relevant
if into.frame_callback != next.frame_callback {
if let Some(callback) = into.frame_callback.take() {
callback.done(0);
}
}
*into = next; *into = next;
new_buffer new_buffer
@ -784,7 +778,7 @@ 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, time: u32) { pub fn send_frame(&mut self, time: u32) {
if let Some(callback) = self.current_state.frame_callback.take() { for callback in self.current_state.frame_callbacks.drain(..) {
callback.done(time); callback.done(time);
} }
} }
@ -863,12 +857,10 @@ fn surface_commit(
None => {} None => {}
} }
if let Some(frame_cb) = attributes.frame_callback.take() { // Append the current frame callbacks to the next state
if let Some(old_cb) = next_state.frame_callback.take() { next_state
old_cb.done(0); .frame_callbacks
} .extend(attributes.frame_callbacks.drain(..));
next_state.frame_callback = Some(frame_cb);
}
data.apply_cache(next_state); data.apply_cache(next_state);

View File

@ -83,7 +83,7 @@ where
} }
wl_surface::Request::Frame { callback } => { wl_surface::Request::Frame { callback } => {
SurfaceData::<R>::with_data(&surface, move |d| { SurfaceData::<R>::with_data(&surface, move |d| {
d.frame_callback = Some((*callback).clone()); d.frame_callbacks.push((*callback).clone());
}); });
} }
wl_surface::Request::SetOpaqueRegion { region } => { wl_surface::Request::SetOpaqueRegion { region } => {

View File

@ -156,14 +156,22 @@ pub struct SurfaceAttributes {
/// Hint provided by the client to suggest that only this part /// Hint provided by the client to suggest that only this part
/// of the surface was changed and needs to be redrawn /// of the surface was changed and needs to be redrawn
pub damage: Vec<Damage>, pub damage: Vec<Damage>,
/// The frame callback associated with this surface for the commit /// The frame callbacks associated with this surface for the commit
/// ///
/// The be triggered to notify the client about when it would be a /// The server must send the notifications so that a client
/// good time to start drawing its next frame. /// will not send excessive updates, while still allowing
/// the highest possible update rate for clients that wait for the reply
/// before drawing again. The server should give some time for the client
/// to draw and commit after sending the frame callback events to let it
/// hit the next output refresh.
///
/// A server should avoid signaling the frame callbacks if the
/// surface is not visible in any way, e.g. the surface is off-screen,
/// or completely obscured by other opaque surfaces.
/// ///
/// An example possibility would be to trigger it once the frame /// An example possibility would be to trigger it once the frame
/// associated with this commit has been displayed on the screen. /// associated with this commit has been displayed on the screen.
pub frame_callback: Option<wl_callback::WlCallback>, pub frame_callbacks: Vec<wl_callback::WlCallback>,
/// User-controlled data /// User-controlled data
/// ///
/// This is your field to host whatever you need. /// This is your field to host whatever you need.
@ -180,7 +188,7 @@ impl fmt::Debug for SurfaceAttributes {
.field("opaque_region", &self.opaque_region) .field("opaque_region", &self.opaque_region)
.field("input_region", &self.input_region) .field("input_region", &self.input_region)
.field("damage", &self.damage) .field("damage", &self.damage)
.field("frame_callback", &self.frame_callback) .field("frame_callbacks", &self.frame_callbacks)
.field("user_data", &"...") .field("user_data", &"...")
.finish() .finish()
} }
@ -195,7 +203,7 @@ impl Default for SurfaceAttributes {
opaque_region: None, opaque_region: None,
input_region: None, input_region: None,
damage: Vec::new(), damage: Vec::new(),
frame_callback: None, frame_callbacks: Vec::new(),
user_data: UserDataMap::new(), user_data: UserDataMap::new(),
} }
} }