tiling: Refactor blocker code
This commit is contained in:
parent
560d234036
commit
75661c6ca7
2 changed files with 25 additions and 41 deletions
|
|
@ -9,25 +9,18 @@ use smithay::{
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
sync::{
|
|
||||||
atomic::{AtomicBool, Ordering},
|
|
||||||
Arc,
|
|
||||||
},
|
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TilingBlocker {
|
pub struct TilingBlocker {
|
||||||
pub necessary_acks: Vec<(CosmicSurface, Serial)>,
|
pub necessary_acks: Vec<(CosmicSurface, Serial)>,
|
||||||
ready: Arc<AtomicBool>,
|
|
||||||
signaled: Arc<AtomicBool>,
|
|
||||||
start: Instant,
|
start: Instant,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Blocker for TilingBlocker {
|
impl Blocker for TilingBlocker {
|
||||||
fn state(&self) -> BlockerState {
|
fn state(&self) -> BlockerState {
|
||||||
self.signaled.store(true, Ordering::SeqCst);
|
if self.is_ready() {
|
||||||
if self.ready.load(Ordering::SeqCst) {
|
|
||||||
BlockerState::Released
|
BlockerState::Released
|
||||||
} else {
|
} else {
|
||||||
BlockerState::Pending
|
BlockerState::Pending
|
||||||
|
|
@ -39,8 +32,6 @@ impl TilingBlocker {
|
||||||
pub fn new(configures: impl IntoIterator<Item = (CosmicSurface, Serial)>) -> Self {
|
pub fn new(configures: impl IntoIterator<Item = (CosmicSurface, Serial)>) -> Self {
|
||||||
TilingBlocker {
|
TilingBlocker {
|
||||||
necessary_acks: configures.into_iter().collect(),
|
necessary_acks: configures.into_iter().collect(),
|
||||||
ready: Arc::new(AtomicBool::new(false)),
|
|
||||||
signaled: Arc::new(AtomicBool::new(false)),
|
|
||||||
start: Instant::now(),
|
start: Instant::now(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -53,14 +44,15 @@ impl TilingBlocker {
|
||||||
.all(|(surf, serial)| !surf.alive() || surf.serial_acked(serial))
|
.all(|(surf, serial)| !surf.alive() || surf.serial_acked(serial))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_signaled(&self) -> bool {
|
pub fn is_processed(&self) -> bool {
|
||||||
self.signaled.load(Ordering::SeqCst)
|
Instant::now().duration_since(self.start) >= Duration::from_millis(500)
|
||||||
|| !self.necessary_acks.iter().any(|(surf, _)| surf.alive())
|
|| self
|
||||||
|
.necessary_acks
|
||||||
|
.iter()
|
||||||
|
.all(|(surf, serial)| !surf.alive() || surf.serial_past(serial))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
pub fn clients(&self) -> HashMap<ClientId, Client> {
|
||||||
pub fn signal_ready(&self) -> HashMap<ClientId, Client> {
|
|
||||||
self.ready.swap(true, Ordering::SeqCst);
|
|
||||||
self.necessary_acks
|
self.necessary_acks
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|(surface, _)| surface.wl_surface().and_then(|s| s.client()))
|
.flat_map(|(surface, _)| surface.wl_surface().and_then(|s| s.client()))
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,6 @@ impl TreeQueue {
|
||||||
pub struct TilingLayout {
|
pub struct TilingLayout {
|
||||||
output: Output,
|
output: Output,
|
||||||
queue: TreeQueue,
|
queue: TreeQueue,
|
||||||
pending_blockers: Vec<TilingBlocker>,
|
|
||||||
placeholder_id: Id,
|
placeholder_id: Id,
|
||||||
swapping_stack_surface_id: Id,
|
swapping_stack_surface_id: Id,
|
||||||
last_overview_hover: Option<(Option<Instant>, TargetZone)>,
|
last_overview_hover: Option<(Option<Instant>, TargetZone)>,
|
||||||
|
|
@ -353,7 +352,6 @@ impl TilingLayout {
|
||||||
animation_start: None,
|
animation_start: None,
|
||||||
},
|
},
|
||||||
output: output.clone(),
|
output: output.clone(),
|
||||||
pending_blockers: Vec::new(),
|
|
||||||
placeholder_id: Id::new(),
|
placeholder_id: Id::new(),
|
||||||
swapping_stack_surface_id: Id::new(),
|
swapping_stack_surface_id: Id::new(),
|
||||||
last_overview_hover: None,
|
last_overview_hover: None,
|
||||||
|
|
@ -2345,8 +2343,20 @@ impl TilingLayout {
|
||||||
|
|
||||||
pub fn update_animation_state(&mut self) -> HashMap<ClientId, Client> {
|
pub fn update_animation_state(&mut self) -> HashMap<ClientId, Client> {
|
||||||
let mut clients = HashMap::new();
|
let mut clients = HashMap::new();
|
||||||
for blocker in self.pending_blockers.drain(..) {
|
let mut ready_trees = 0;
|
||||||
clients.extend(blocker.signal_ready());
|
for (_, _, blocker) in self.queue.trees.iter().skip(1) {
|
||||||
|
if let Some(blocker) = blocker.as_ref() {
|
||||||
|
if blocker.is_processed() {
|
||||||
|
ready_trees += 1;
|
||||||
|
}
|
||||||
|
if blocker.is_ready() {
|
||||||
|
clients.extend(blocker.clients());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
ready_trees += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(start) = self.queue.animation_start {
|
if let Some(start) = self.queue.animation_start {
|
||||||
|
|
@ -2361,6 +2371,7 @@ impl TilingLayout {
|
||||||
{
|
{
|
||||||
let _ = self.queue.animation_start.take();
|
let _ = self.queue.animation_start.take();
|
||||||
let _ = self.queue.trees.pop_front();
|
let _ = self.queue.trees.pop_front();
|
||||||
|
ready_trees -= 1;
|
||||||
let front = self.queue.trees.front_mut().unwrap();
|
let front = self.queue.trees.front_mut().unwrap();
|
||||||
if let Some(root_id) = front.0.root_node_id() {
|
if let Some(root_id) = front.0.root_node_id() {
|
||||||
for node in front
|
for node in front
|
||||||
|
|
@ -2383,28 +2394,12 @@ impl TilingLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let ready_trees = self
|
|
||||||
.queue
|
|
||||||
.trees
|
|
||||||
.iter()
|
|
||||||
.skip(1)
|
|
||||||
.take_while(|(_, _, blocker)| {
|
|
||||||
blocker
|
|
||||||
.as_ref()
|
|
||||||
.map(|blocker| blocker.is_ready() && blocker.is_signaled())
|
|
||||||
.unwrap_or(true)
|
|
||||||
})
|
|
||||||
.count();
|
|
||||||
|
|
||||||
// merge
|
// merge
|
||||||
let other_duration = if ready_trees > 1 {
|
let other_duration = if ready_trees > 1 {
|
||||||
self.queue
|
self.queue
|
||||||
.trees
|
.trees
|
||||||
.drain(1..ready_trees)
|
.drain(1..ready_trees)
|
||||||
.fold(None, |res, (_, duration, blocker)| {
|
.fold(None, |res, (_, duration, _)| {
|
||||||
if let Some(blocker) = blocker {
|
|
||||||
clients.extend(blocker.signal_ready());
|
|
||||||
}
|
|
||||||
Some(
|
Some(
|
||||||
res.map(|old_duration: Duration| old_duration.max(duration))
|
res.map(|old_duration: Duration| old_duration.max(duration))
|
||||||
.unwrap_or(duration),
|
.unwrap_or(duration),
|
||||||
|
|
@ -2416,13 +2411,10 @@ impl TilingLayout {
|
||||||
|
|
||||||
// start
|
// start
|
||||||
if ready_trees > 0 {
|
if ready_trees > 0 {
|
||||||
let (_, duration, blocker) = self.queue.trees.get_mut(1).unwrap();
|
let (_, duration, _) = self.queue.trees.get_mut(1).unwrap();
|
||||||
*duration = other_duration
|
*duration = other_duration
|
||||||
.map(|other| other.max(*duration))
|
.map(|other| other.max(*duration))
|
||||||
.unwrap_or(*duration);
|
.unwrap_or(*duration);
|
||||||
if let Some(blocker) = blocker {
|
|
||||||
clients.extend(blocker.signal_ready());
|
|
||||||
}
|
|
||||||
self.queue.animation_start = Some(Instant::now());
|
self.queue.animation_start = Some(Instant::now());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue