Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use weak surface ref inside transaction #1612

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 20 additions & 8 deletions src/wayland/compositor/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ use std::{
sync::{atomic::AtomicBool, Arc, Mutex},
};

use wayland_server::{protocol::wl_surface::WlSurface, DisplayHandle, Resource};
use wayland_server::{protocol::wl_surface::WlSurface, DisplayHandle, Resource, Weak};

use crate::{utils::IsAlive, utils::Serial};
use crate::utils::Serial;

use super::{tree::PrivateSurfaceData, CompositorHandler};

Expand Down Expand Up @@ -110,7 +110,7 @@ impl Blocker for Barrier {

#[derive(Default)]
struct TransactionState {
surfaces: Vec<(WlSurface, Serial)>,
surfaces: Vec<(Weak<WlSurface>, Serial)>,
blockers: Vec<Box<dyn Blocker + Send>>,
}

Expand All @@ -123,7 +123,7 @@ impl TransactionState {
}
} else {
// the surface is not in the list, insert it
self.surfaces.push((surface, id));
self.surfaces.push((surface.downgrade(), id));
}
}
}
Expand Down Expand Up @@ -196,7 +196,9 @@ impl PendingTransaction {
// fuse our surfaces into our new transaction state
self.with_inner_state(|state| {
for (surface, id) in my_state.surfaces {
state.insert(surface, id);
if let Ok(surface) = surface.upgrade() {
state.insert(surface, id);
}
}
state.blockers.extend(my_state.blockers);
});
Expand All @@ -221,7 +223,7 @@ impl PendingTransaction {

#[derive(Debug)]
pub(crate) struct Transaction {
surfaces: Vec<(WlSurface, Serial)>,
surfaces: Vec<(Weak<WlSurface>, Serial)>,
blockers: Vec<Box<dyn Blocker + Send>>,
}

Expand All @@ -240,6 +242,12 @@ impl Transaction {
/// - otherwise, if at least one blocker is pending, the transaction is pending
/// - otherwise, all blockers are released, and the transaction is also released
pub(crate) fn state(&self) -> BlockerState {
// In case all of our surfaces have been destroyed we can cancel this transaction
// as we won't apply its state anyway
if !self.surfaces.iter().any(|surface| surface.0.is_alive()) {
return BlockerState::Cancelled;
}

use BlockerState::*;
self.blockers
.iter()
Expand All @@ -252,6 +260,10 @@ impl Transaction {

pub(crate) fn apply<C: CompositorHandler + 'static>(self, dh: &DisplayHandle, state: &mut C) {
for (surface, id) in self.surfaces {
let Ok(surface) = surface.upgrade() else {
continue;
};

PrivateSurfaceData::with_states(&surface, |states| {
states.cached_state.apply_state(id, dh);
});
Expand Down Expand Up @@ -307,7 +319,7 @@ impl TransactionQueue {
if !skip {
for (s, _) in &self.transactions[i].surfaces {
// TODO: is this alive check still needed?
if !s.alive() {
if !s.is_alive() {
continue;
}
if self.seen_surfaces.contains(&s.id().protocol_id()) {
Expand All @@ -322,7 +334,7 @@ impl TransactionQueue {
// seen list
for (s, _) in &self.transactions[i].surfaces {
// TODO: is this alive check still needed?
if !s.alive() {
if !s.is_alive() {
continue;
}
self.seen_surfaces.insert(s.id().protocol_id());
Expand Down
Loading