Skip to content

Commit

Permalink
drm-syncobj: Fix handling of `wp_linux_drm_syncobj_surface_v1::destro…
Browse files Browse the repository at this point in the history
…y` (#1547)
  • Loading branch information
ids1024 authored Sep 25, 2024
1 parent 950458c commit 8e9c7aa
Showing 1 changed file with 34 additions and 5 deletions.
39 changes: 34 additions & 5 deletions src/wayland/drm_syncobj/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ use wayland_server::{
};

use super::{
compositor::{self, with_states, BufferAssignment, Cacheable, SurfaceAttributes},
compositor::{self, with_states, BufferAssignment, Cacheable, HookId, SurfaceAttributes},
dmabuf::get_dmabuf,
};
use crate::backend::drm::DrmDeviceFd;
Expand Down Expand Up @@ -273,19 +273,22 @@ where
);
return;
}
let commit_hook_id = compositor::add_pre_commit_hook::<D, _>(&surface, commit_hook);
let destruction_hook_id =
compositor::add_destruction_hook::<D, _>(&surface, destruction_hook);
let syncobj_surface = data_init.init::<_, _>(
id,
DrmSyncobjSurfaceData {
surface: surface.downgrade(),
commit_hook_id,
destruction_hook_id,
},
);
with_states(&surface, |states| {
states
.data_map
.insert_if_missing(|| RefCell::new(Some(syncobj_surface)))
});
compositor::add_pre_commit_hook::<D, _>(&surface, commit_hook);
compositor::add_destruction_hook::<D, _>(&surface, destruction_hook);
}
wp_linux_drm_syncobj_manager_v1::Request::ImportTimeline { id, fd } => {
match DrmTimeline::new(&state.drm_syncobj_state().import_device, fd.as_fd()) {
Expand All @@ -310,9 +313,14 @@ where
#[derive(Debug)]
pub struct DrmSyncobjSurfaceData {
surface: Weak<WlSurface>,
commit_hook_id: HookId,
destruction_hook_id: HookId,
}

impl<D> Dispatch<WpLinuxDrmSyncobjSurfaceV1, DrmSyncobjSurfaceData, D> for DrmSyncobjState {
impl<D> Dispatch<WpLinuxDrmSyncobjSurfaceV1, DrmSyncobjSurfaceData, D> for DrmSyncobjState
where
D: DrmSyncobjHandler,
{
fn request(
_state: &mut D,
_client: &Client,
Expand All @@ -323,7 +331,28 @@ impl<D> Dispatch<WpLinuxDrmSyncobjSurfaceV1, DrmSyncobjSurfaceData, D> for DrmSy
_data_init: &mut DataInit<'_, D>,
) {
match request {
wp_linux_drm_syncobj_surface_v1::Request::Destroy => {}
wp_linux_drm_syncobj_surface_v1::Request::Destroy => {
if let Ok(surface) = data.surface.upgrade() {
compositor::remove_pre_commit_hook(&surface, data.commit_hook_id);
compositor::remove_destruction_hook(&surface, data.destruction_hook_id);
with_states(&surface, |states| {
*states
.data_map
.get::<RefCell<Option<WpLinuxDrmSyncobjSurfaceV1>>>()
.unwrap()
.borrow_mut() = None;
// Committed sync points should still be used, but pending points can
// be cleared.
let mut cached = states.cached_state.get::<DrmSyncobjCachedState>();
cached.pending().acquire_point = None;
if let Some(release_point) = cached.pending().release_point.take() {
if let Err(err) = release_point.signal() {
tracing::error!("Failed to signal syncobj release point: {}", err);
}
}
});
}
}
wp_linux_drm_syncobj_surface_v1::Request::SetAcquirePoint {
timeline,
point_hi,
Expand Down

0 comments on commit 8e9c7aa

Please sign in to comment.