wl_surface: handle presentation feedback cleanup automatically
This commit is contained in:
parent
7b0dc8879a
commit
6bdd1ff6e7
4 changed files with 62 additions and 46 deletions
|
|
@ -67,7 +67,7 @@ use {
|
||||||
zwlr_layer_surface_v1::{PendingLayerSurfaceData, ZwlrLayerSurfaceV1Error},
|
zwlr_layer_surface_v1::{PendingLayerSurfaceData, ZwlrLayerSurfaceV1Error},
|
||||||
},
|
},
|
||||||
wp_content_type_v1::ContentType,
|
wp_content_type_v1::ContentType,
|
||||||
wp_presentation_feedback::{VRR_REFRESH_SINCE, WpPresentationFeedback},
|
wp_presentation_feedback::PresentationFeedback,
|
||||||
zwp_linux_dmabuf_feedback_v1::ZwpLinuxDmabufFeedbackV1,
|
zwp_linux_dmabuf_feedback_v1::ZwpLinuxDmabufFeedbackV1,
|
||||||
},
|
},
|
||||||
io_uring::IoUringError,
|
io_uring::IoUringError,
|
||||||
|
|
@ -311,8 +311,8 @@ pub struct WlSurface {
|
||||||
pub children: RefCell<Option<Box<ParentData>>>,
|
pub children: RefCell<Option<Box<ParentData>>>,
|
||||||
ext: CloneCell<Rc<dyn SurfaceExt>>,
|
ext: CloneCell<Rc<dyn SurfaceExt>>,
|
||||||
frame_requests: RefCell<Vec<FrameRequest>>,
|
frame_requests: RefCell<Vec<FrameRequest>>,
|
||||||
presentation_feedback: RefCell<Vec<Rc<WpPresentationFeedback>>>,
|
presentation_feedback: RefCell<Vec<PresentationFeedback>>,
|
||||||
latched_presentation_feedback: RefCell<Vec<Rc<WpPresentationFeedback>>>,
|
latched_presentation_feedback: RefCell<Vec<PresentationFeedback>>,
|
||||||
seat_state: NodeSeatState,
|
seat_state: NodeSeatState,
|
||||||
toplevel: CloneCell<Option<Rc<dyn ToplevelNode>>>,
|
toplevel: CloneCell<Option<Rc<dyn ToplevelNode>>>,
|
||||||
cursors: SmallMap<CursorUserId, Rc<CursorSurface>, 1>,
|
cursors: SmallMap<CursorUserId, Rc<CursorSurface>, 1>,
|
||||||
|
|
@ -469,7 +469,7 @@ struct PendingState {
|
||||||
damage_full: bool,
|
damage_full: bool,
|
||||||
buffer_damage: Vec<Rect>,
|
buffer_damage: Vec<Rect>,
|
||||||
surface_damage: Vec<Rect>,
|
surface_damage: Vec<Rect>,
|
||||||
presentation_feedback: Vec<Rc<WpPresentationFeedback>>,
|
presentation_feedback: Vec<PresentationFeedback>,
|
||||||
src_rect: Option<Option<[Fixed; 4]>>,
|
src_rect: Option<Option<[Fixed; 4]>>,
|
||||||
dst_size: Option<Option<(i32, i32)>>,
|
dst_size: Option<Option<(i32, i32)>>,
|
||||||
scale: Option<i32>,
|
scale: Option<i32>,
|
||||||
|
|
@ -511,10 +511,7 @@ impl PendingState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for fb in self.presentation_feedback.drain(..) {
|
self.presentation_feedback.clear();
|
||||||
fb.send_discarded();
|
|
||||||
let _ = client.remove_obj(&*fb);
|
|
||||||
}
|
|
||||||
|
|
||||||
// overwrite state
|
// overwrite state
|
||||||
|
|
||||||
|
|
@ -799,11 +796,8 @@ impl WlSurface {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_presentation_feedback(&self, fb: &Rc<WpPresentationFeedback>) {
|
pub fn add_presentation_feedback(&self, fb: PresentationFeedback) {
|
||||||
self.pending
|
self.pending.borrow_mut().presentation_feedback.push(fb);
|
||||||
.borrow_mut()
|
|
||||||
.presentation_feedback
|
|
||||||
.push(fb.clone());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_cursor(&self) -> bool {
|
pub fn is_cursor(&self) -> bool {
|
||||||
|
|
@ -1382,10 +1376,7 @@ impl WlSurface {
|
||||||
}
|
}
|
||||||
let has_presentation_feedback = {
|
let has_presentation_feedback = {
|
||||||
let mut fbs = self.presentation_feedback.borrow_mut();
|
let mut fbs = self.presentation_feedback.borrow_mut();
|
||||||
for fb in fbs.drain(..) {
|
fbs.clear();
|
||||||
fb.send_discarded();
|
|
||||||
let _ = self.client.remove_obj(&*fb);
|
|
||||||
}
|
|
||||||
mem::swap(fbs.deref_mut(), &mut pending.presentation_feedback);
|
mem::swap(fbs.deref_mut(), &mut pending.presentation_feedback);
|
||||||
fbs.is_not_empty()
|
fbs.is_not_empty()
|
||||||
};
|
};
|
||||||
|
|
@ -2224,10 +2215,7 @@ impl LatchListener for WlSurface {
|
||||||
if self.visible.get() {
|
if self.visible.get() {
|
||||||
if self.latched_commit_version.get() < self.commit_version.get() {
|
if self.latched_commit_version.get() < self.commit_version.get() {
|
||||||
let latched = &mut *self.latched_presentation_feedback.borrow_mut();
|
let latched = &mut *self.latched_presentation_feedback.borrow_mut();
|
||||||
for pf in latched.drain(..) {
|
latched.clear();
|
||||||
pf.send_discarded();
|
|
||||||
let _ = pf.client.remove_obj(&*pf);
|
|
||||||
}
|
|
||||||
latched.append(&mut self.presentation_feedback.borrow_mut());
|
latched.append(&mut self.presentation_feedback.borrow_mut());
|
||||||
if latched.is_not_empty() {
|
if latched.is_not_empty() {
|
||||||
self.presentation_listener
|
self.presentation_listener
|
||||||
|
|
@ -2262,17 +2250,7 @@ impl PresentationListener for WlSurface {
|
||||||
let bindings = output.global.bindings.borrow();
|
let bindings = output.global.bindings.borrow();
|
||||||
let bindings = bindings.get(&self.client.id);
|
let bindings = bindings.get(&self.client.id);
|
||||||
for pf in self.latched_presentation_feedback.borrow_mut().drain(..) {
|
for pf in self.latched_presentation_feedback.borrow_mut().drain(..) {
|
||||||
if let Some(bindings) = bindings {
|
pf.presented(bindings, tv_sec, tv_nsec, refresh, seq, flags, vrr);
|
||||||
for binding in bindings.values() {
|
|
||||||
pf.send_sync_output(binding);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let mut refresh = refresh;
|
|
||||||
if vrr && pf.version < VRR_REFRESH_SINCE {
|
|
||||||
refresh = 0;
|
|
||||||
}
|
|
||||||
pf.send_presented(tv_sec, tv_nsec, refresh, seq, flags);
|
|
||||||
let _ = pf.client.remove_obj(&*pf);
|
|
||||||
}
|
}
|
||||||
self.presentation_listener.detach();
|
self.presentation_listener.detach();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ use {
|
||||||
scale::Scale,
|
scale::Scale,
|
||||||
tree::{Node, NodeLocation, NodeVisitorBase, OutputNode},
|
tree::{Node, NodeLocation, NodeVisitorBase, OutputNode},
|
||||||
},
|
},
|
||||||
std::{cell::Cell, ops::Deref, rc::Rc},
|
std::{cell::Cell, rc::Rc},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct CursorSurface {
|
pub struct CursorSurface {
|
||||||
|
|
@ -103,14 +103,8 @@ impl Cursor for CursorSurface {
|
||||||
fr.now = self.0;
|
fr.now = self.0;
|
||||||
drop(fr);
|
drop(fr);
|
||||||
}
|
}
|
||||||
for fr in node.presentation_feedback.borrow_mut().drain(..) {
|
node.presentation_feedback.borrow_mut().clear();
|
||||||
fr.send_discarded();
|
node.latched_presentation_feedback.borrow_mut().clear();
|
||||||
let _ = fr.client.remove_obj(fr.deref());
|
|
||||||
}
|
|
||||||
for fr in node.latched_presentation_feedback.borrow_mut().drain(..) {
|
|
||||||
fr.send_discarded();
|
|
||||||
let _ = fr.client.remove_obj(fr.deref());
|
|
||||||
}
|
|
||||||
node.node_visit_children(self);
|
node.node_visit_children(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use {
|
||||||
crate::{
|
crate::{
|
||||||
client::{Client, ClientError},
|
client::{Client, ClientError},
|
||||||
globals::{Global, GlobalName},
|
globals::{Global, GlobalName},
|
||||||
ifs::wp_presentation_feedback::WpPresentationFeedback,
|
ifs::wp_presentation_feedback::{PresentationFeedback, WpPresentationFeedback},
|
||||||
leaks::Tracker,
|
leaks::Tracker,
|
||||||
object::{Object, Version},
|
object::{Object, Version},
|
||||||
state::State,
|
state::State,
|
||||||
|
|
@ -94,7 +94,7 @@ impl WpPresentationRequestHandler for WpPresentation {
|
||||||
});
|
});
|
||||||
track!(self.client, fb);
|
track!(self.client, fb);
|
||||||
self.client.add_client_obj(&fb)?;
|
self.client.add_client_obj(&fb)?;
|
||||||
surface.add_presentation_feedback(&fb);
|
surface.add_presentation_feedback(PresentationFeedback::new(fb));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,55 @@ use {
|
||||||
ifs::{wl_output::WlOutput, wl_surface::WlSurface},
|
ifs::{wl_output::WlOutput, wl_surface::WlSurface},
|
||||||
leaks::Tracker,
|
leaks::Tracker,
|
||||||
object::{Object, Version},
|
object::{Object, Version},
|
||||||
wire::{WpPresentationFeedbackId, wp_presentation_feedback::*},
|
wire::{WlOutputId, WpPresentationFeedbackId, wp_presentation_feedback::*},
|
||||||
},
|
},
|
||||||
|
ahash::AHashMap,
|
||||||
std::{convert::Infallible, rc::Rc},
|
std::{convert::Infallible, rc::Rc},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub struct PresentationFeedback {
|
||||||
|
fb: Option<Rc<WpPresentationFeedback>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PresentationFeedback {
|
||||||
|
pub fn new(fb: Rc<WpPresentationFeedback>) -> Self {
|
||||||
|
Self { fb: Some(fb) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn presented(
|
||||||
|
mut self,
|
||||||
|
outputs: Option<&AHashMap<WlOutputId, Rc<WlOutput>>>,
|
||||||
|
tv_sec: u64,
|
||||||
|
tv_nsec: u32,
|
||||||
|
mut refresh: u32,
|
||||||
|
seq: u64,
|
||||||
|
flags: u32,
|
||||||
|
vrr: bool,
|
||||||
|
) {
|
||||||
|
if let Some(fb) = self.fb.take() {
|
||||||
|
if let Some(outputs) = outputs {
|
||||||
|
for output in outputs.values() {
|
||||||
|
fb.send_sync_output(output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if vrr && fb.version < VRR_REFRESH_SINCE {
|
||||||
|
refresh = 0;
|
||||||
|
}
|
||||||
|
fb.send_presented(tv_sec, tv_nsec, refresh, seq, flags);
|
||||||
|
let _ = fb.client.remove_obj(&*fb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for PresentationFeedback {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if let Some(fb) = self.fb.take() {
|
||||||
|
fb.send_discarded();
|
||||||
|
let _ = fb.client.remove_obj(&*fb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct WpPresentationFeedback {
|
pub struct WpPresentationFeedback {
|
||||||
pub id: WpPresentationFeedbackId,
|
pub id: WpPresentationFeedbackId,
|
||||||
pub client: Rc<Client>,
|
pub client: Rc<Client>,
|
||||||
|
|
@ -33,7 +77,7 @@ impl WpPresentationFeedback {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_presented(&self, tv_sec: u64, tv_nsec: u32, refresh: u32, seq: u64, flags: u32) {
|
fn send_presented(&self, tv_sec: u64, tv_nsec: u32, refresh: u32, seq: u64, flags: u32) {
|
||||||
self.client.event(Presented {
|
self.client.event(Presented {
|
||||||
self_id: self.id,
|
self_id: self.id,
|
||||||
tv_sec,
|
tv_sec,
|
||||||
|
|
@ -44,7 +88,7 @@ impl WpPresentationFeedback {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_discarded(&self) {
|
fn send_discarded(&self) {
|
||||||
self.client.event(Discarded { self_id: self.id });
|
self.client.event(Discarded { self_id: self.id });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue