use crate::allocator::{LayerId, LayerRef};
use crate::layer::Layer;
use crate::prop::PropTag;
#[derive(Debug, Default)]
pub struct Output {
crtc_id: u32,
layers: Vec<(LayerId, Layer)>,
next_id: u64,
composition: Option<LayerId>,
}
impl Output {
#[must_use]
pub const fn new(crtc_id: u32) -> Self {
Self {
crtc_id,
layers: Vec::new(),
next_id: 1,
composition: None,
}
}
#[must_use]
pub const fn crtc_id(&self) -> u32 {
self.crtc_id
}
pub fn add_layer(&mut self) -> LayerId {
let id = LayerId(self.next_id);
self.next_id += 1;
self.layers.push((id, Layer::new()));
id
}
pub fn remove_layer(&mut self, id: LayerId) -> bool {
let Some(index) = self.layers.iter().position(|(known, _)| *known == id) else {
return false;
};
self.layers.remove(index);
if self.composition == Some(id) {
self.composition = None;
}
true
}
#[must_use]
pub fn layer(&self, id: LayerId) -> Option<&Layer> {
self.layers
.iter()
.find(|(known, _)| *known == id)
.map(|(_, layer)| layer)
}
pub fn layer_mut(&mut self, id: LayerId) -> Option<&mut Layer> {
self.layers
.iter_mut()
.find(|(known, _)| *known == id)
.map(|(_, layer)| layer)
}
pub fn layers(&self) -> impl Iterator<Item = LayerRef<'_>> + '_ {
self.layers
.iter()
.map(|(id, layer)| LayerRef { id: *id, layer })
}
#[must_use]
pub fn layer_refs(&self) -> Vec<LayerRef<'_>> {
self.layers().collect()
}
#[must_use]
pub fn len(&self) -> usize {
self.layers.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.layers.is_empty()
}
pub fn set_composition_layer(&mut self, id: LayerId) -> bool {
if self.layer(id).is_none() {
return false;
}
if let Some(previous) = self.composition
&& let Some(layer) = self.layer_mut(previous)
{
layer.set_composition_layer(false);
}
self.composition = Some(id);
if let Some(layer) = self.layer_mut(id) {
layer.set_composition_layer(true);
}
true
}
#[must_use]
pub const fn composition_layer(&self) -> Option<LayerId> {
self.composition
}
#[must_use]
pub fn any_layer_dirty(&self) -> bool {
self.layers.iter().any(|(_, layer)| layer.is_dirty())
}
pub fn changed_layers(&self) -> impl Iterator<Item = LayerRef<'_>> + '_ {
self.layers().filter(|entry| entry.layer.is_dirty())
}
pub fn mark_clean(&mut self) {
for (_, layer) in &mut self.layers {
layer.mark_clean();
}
}
pub fn sort_layers_by_zpos(&mut self) {
self.layers
.sort_by_key(|(_, layer)| layer.property(PropTag::Zpos).unwrap_or(0));
}
}