rework renderlayer to zindex solution

This commit is contained in:
dragonn 2022-01-20 19:11:58 +01:00
parent dea000921b
commit 957f1c522b
6 changed files with 70 additions and 90 deletions

View File

@ -269,6 +269,11 @@ impl LayerMap {
pub fn cleanup(&mut self) {
self.layers.retain(|layer| layer.alive())
}
/// Returns layers count
pub fn len(&self) -> usize {
self.layers.len()
}
}
#[derive(Debug, Default)]

View File

@ -10,22 +10,22 @@ use std::{
};
use wayland_server::protocol::wl_surface::WlSurface;
/// Enum for indicating on with layer a render element schould be draw
#[derive(Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum RenderLayer {
/// Bellow every other elements
Bottom,
/// Above WlrLayer::Background but bellow WlrLayer::Bottom
AboveBackground,
/// Right before programs windows are draw
BeforeWindows,
/// Right after programs windows are draw
AfterWindows,
/// Above WlrLayer::Top but bellow WlrLayer::Overlay
BeforeOverlay,
/// Above anything else
Top,
/// Indicates default values for some zindexs inside smithay
#[derive(Debug)]
#[repr(u8)]
pub enum RenderZindex {
/// WlrLayer::Background default zindex
Background = 10,
/// WlrLayer::Bottom default zindex
Bottom = 20,
/// Not used yet?
Shell = 30,
/// Default zindex for Windows
Top = 40,
/// Default Layer for RenderElements
Overlay = 50,
/// Default Layer for PopUps?
PopUp = 60,
}
/// Elements rendered by [`Space::render_output`] in addition to windows, layers and popups.
@ -35,57 +35,6 @@ pub type DynamicRenderElements<R> =
pub(super) type SpaceElem<R> =
dyn SpaceElement<R, <R as Renderer>::Frame, <R as Renderer>::Error, <R as Renderer>::TextureId>;
/// Helper struct for iterating over diffrent layers of `DynamicRenderElements`
pub(super) struct DynamicRenderElementMap<'a, R: Renderer>(pub(super) &'a [DynamicRenderElements<R>]);
impl<'a, R> DynamicRenderElementMap<'a, R>
where
R: Renderer + ImportAll + 'static,
R::TextureId: 'static,
R::Error: 'static,
R::Frame: 'static,
{
/// Iterate over `DynamicRenderElements` with layer `RenderLayer::Bottom`
pub fn iter_bottom(&'a self) -> Box<dyn Iterator<Item = &SpaceElem<R>> + 'a> {
self.iter_layer(RenderLayer::Bottom)
}
/// Iterate over `DynamicRenderElements with layer `RenderLayer::AboveBackground`
pub fn iter_above_background(&'a self) -> Box<dyn Iterator<Item = &SpaceElem<R>> + 'a> {
self.iter_layer(RenderLayer::AboveBackground)
}
/// Iterate over `DynamicRenderElements` with layer `RenderLayer::BeforeWindows`
pub fn iter_before_windows(&'a self) -> Box<dyn Iterator<Item = &SpaceElem<R>> + 'a> {
self.iter_layer(RenderLayer::BeforeWindows)
}
/// Iterate over `DynamicRenderElements` with layer `RenderLayer::AfterWindows`
pub fn iter_after_windows(&'a self) -> Box<dyn Iterator<Item = &SpaceElem<R>> + 'a> {
self.iter_layer(RenderLayer::AfterWindows)
}
/// Iterate over `DynamicRenderElements` with layer `RenderLayer::BeforeOverlay`
pub fn iter_before_overlay(&'a self) -> Box<dyn Iterator<Item = &SpaceElem<R>> + 'a> {
self.iter_layer(RenderLayer::BeforeOverlay)
}
/// Iterate over `DynamicRenderElements` with layer `RenderLayer::Top`
pub fn iter_top(&'a self) -> Box<dyn Iterator<Item = &SpaceElem<R>> + 'a> {
self.iter_layer(RenderLayer::Top)
}
/// Iterate over `DynamicRenderElements` with provided `layer`
pub fn iter_layer(&'a self, layer: RenderLayer) -> Box<dyn Iterator<Item = &SpaceElem<R>> + 'a> {
Box::new(
self.0
.iter()
.filter(move |c| c.layer() == layer)
.map(|c| c as &SpaceElem<R>),
)
}
}
/// Trait for custom elements to be rendered during [`Space::render_output`].
pub trait RenderElement<R, F, E, T>
where
@ -132,9 +81,9 @@ where
log: &slog::Logger,
) -> Result<(), R::Error>;
/// Returns they layer the elements schould be draw on, defaults to Top
fn layer(&self) -> RenderLayer {
RenderLayer::Top
/// Returns z_index of RenderElement, reverf too [`RenderZindex`] for default values
fn z_index(&self) -> u8 {
RenderZindex::Overlay as u8
}
}
@ -163,6 +112,9 @@ where
damage: &[Rectangle<i32, Logical>],
log: &slog::Logger,
) -> Result<(), R::Error>;
fn z_index(&self) -> u8; //{
// 0
//}
}
impl<R, F, E, T> SpaceElement<R, F, E, T> for Box<dyn RenderElement<R, F, E, T>>
@ -196,6 +148,10 @@ where
) -> Result<(), R::Error> {
(&**self as &dyn RenderElement<R, F, E, T>).draw(renderer, frame, scale, damage, log)
}
fn z_index(&self) -> u8 {
RenderElement::z_index(self.as_ref())
}
}
/// Generic helper for drawing [`WlSurface`]s and their subsurfaces

View File

@ -5,7 +5,7 @@ use crate::{
space::{Space, SpaceElement},
},
utils::{Logical, Point, Rectangle},
wayland::output::Output,
wayland::{output::Output, shell::wlr_layer::Layer},
};
use std::{
any::TypeId,
@ -13,6 +13,8 @@ use std::{
collections::HashMap,
};
use super::RenderZindex;
#[derive(Default)]
pub struct LayerState {
pub drawn: bool,
@ -69,4 +71,19 @@ where
}
res
}
fn z_index(&self) -> u8 {
if let Some(layer) = self.layer() {
let z_index = match layer {
Layer::Background => RenderZindex::Background,
Layer::Bottom => RenderZindex::Bottom,
Layer::Top => RenderZindex::Top,
Layer::Overlay => RenderZindex::Overlay,
};
z_index as u8
} else {
//TODO: what to do when layersurface doesn't have a layer?
0
}
}
}

View File

@ -14,7 +14,6 @@ use crate::{
TraversalAction,
},
output::Output,
shell::wlr_layer::Layer as WlrLayer,
},
};
use indexmap::{IndexMap, IndexSet};
@ -605,27 +604,18 @@ impl Space {
.collect::<Vec<_>>(),
)?;
let custom_elements = DynamicRenderElementMap(custom_elements);
let mut render_elements: Vec<&SpaceElem<R>> =
Vec::with_capacity(custom_elements.len() + layer_map.len() + self.windows.len());
render_elements.append(&mut custom_elements.iter().map(|l| l as &SpaceElem<R>).collect());
render_elements.append(&mut self.windows.iter().map(|l| l as &SpaceElem<R>).collect());
render_elements.append(&mut layer_map.layers().map(|l| l as &SpaceElem<R>).collect());
render_elements.sort_by_key(|e| e.z_index());
// Then re-draw all windows & layers overlapping with a damage rect.
for element in custom_elements
.iter_bottom()
.chain(
layer_map
.layers_on(WlrLayer::Background)
.map(|l| l as &SpaceElem<R>),
)
.chain(custom_elements.iter_above_background())
.chain(layer_map.layers_on(WlrLayer::Bottom).map(|l| l as &SpaceElem<R>))
.chain(custom_elements.iter_before_windows())
.chain(self.windows.iter().map(|w| w as &SpaceElem<R>))
.chain(custom_elements.iter_after_windows())
.chain(layer_map.layers_on(WlrLayer::Top).map(|l| l as &SpaceElem<R>))
.chain(custom_elements.iter_before_overlay())
.chain(layer_map.layers_on(WlrLayer::Overlay).map(|l| l as &SpaceElem<R>))
.chain(custom_elements.iter_top())
{
for element in render_elements {
let geo = element.geometry(self.id);
if damage.iter().any(|d| d.overlaps(geo)) {
let loc = element.location(self.id);

View File

@ -12,6 +12,8 @@ use crate::{
};
use std::any::TypeId;
use super::RenderZindex;
#[derive(Debug)]
pub struct RenderPopup {
location: Point<i32, Logical>,
@ -126,4 +128,8 @@ where
// popups are special, we track them, but they render with their parents
Ok(())
}
fn z_index(&self) -> u8 {
RenderZindex::PopUp as u8
}
}

View File

@ -13,6 +13,8 @@ use std::{
collections::HashMap,
};
use super::RenderZindex;
#[derive(Default)]
pub struct WindowState {
pub location: Point<i32, Logical>,
@ -103,4 +105,8 @@ where
}
res
}
fn z_index(&self) -> u8 {
RenderZindex::Top as u8
}
}