From 957f1c522b5a486ce16c9b01b34dfa287ea3c45c Mon Sep 17 00:00:00 2001 From: dragonn Date: Thu, 20 Jan 2022 19:11:58 +0100 Subject: [PATCH] rework renderlayer to zindex solution --- src/desktop/layer.rs | 5 ++ src/desktop/space/element.rs | 96 ++++++++++-------------------------- src/desktop/space/layer.rs | 19 ++++++- src/desktop/space/mod.rs | 28 ++++------- src/desktop/space/popup.rs | 6 +++ src/desktop/space/window.rs | 6 +++ 6 files changed, 70 insertions(+), 90 deletions(-) diff --git a/src/desktop/layer.rs b/src/desktop/layer.rs index 1dc4b9a..b6e2c06 100644 --- a/src/desktop/layer.rs +++ b/src/desktop/layer.rs @@ -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)] diff --git a/src/desktop/space/element.rs b/src/desktop/space/element.rs index 6752af9..4f915af 100644 --- a/src/desktop/space/element.rs +++ b/src/desktop/space/element.rs @@ -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 = pub(super) type SpaceElem = dyn SpaceElement::Frame, ::Error, ::TextureId>; -/// Helper struct for iterating over diffrent layers of `DynamicRenderElements` -pub(super) struct DynamicRenderElementMap<'a, R: Renderer>(pub(super) &'a [DynamicRenderElements]); - -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> + 'a> { - self.iter_layer(RenderLayer::Bottom) - } - - /// Iterate over `DynamicRenderElements with layer `RenderLayer::AboveBackground` - pub fn iter_above_background(&'a self) -> Box> + 'a> { - self.iter_layer(RenderLayer::AboveBackground) - } - - /// Iterate over `DynamicRenderElements` with layer `RenderLayer::BeforeWindows` - pub fn iter_before_windows(&'a self) -> Box> + 'a> { - self.iter_layer(RenderLayer::BeforeWindows) - } - - /// Iterate over `DynamicRenderElements` with layer `RenderLayer::AfterWindows` - pub fn iter_after_windows(&'a self) -> Box> + 'a> { - self.iter_layer(RenderLayer::AfterWindows) - } - - /// Iterate over `DynamicRenderElements` with layer `RenderLayer::BeforeOverlay` - pub fn iter_before_overlay(&'a self) -> Box> + 'a> { - self.iter_layer(RenderLayer::BeforeOverlay) - } - - /// Iterate over `DynamicRenderElements` with layer `RenderLayer::Top` - pub fn iter_top(&'a self) -> Box> + 'a> { - self.iter_layer(RenderLayer::Top) - } - - /// Iterate over `DynamicRenderElements` with provided `layer` - pub fn iter_layer(&'a self, layer: RenderLayer) -> Box> + 'a> { - Box::new( - self.0 - .iter() - .filter(move |c| c.layer() == layer) - .map(|c| c as &SpaceElem), - ) - } -} - /// Trait for custom elements to be rendered during [`Space::render_output`]. pub trait RenderElement 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], log: &slog::Logger, ) -> Result<(), R::Error>; + fn z_index(&self) -> u8; //{ + // 0 + //} } impl SpaceElement for Box> @@ -196,6 +148,10 @@ where ) -> Result<(), R::Error> { (&**self as &dyn RenderElement).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 diff --git a/src/desktop/space/layer.rs b/src/desktop/space/layer.rs index 89a4799..e6f397e 100644 --- a/src/desktop/space/layer.rs +++ b/src/desktop/space/layer.rs @@ -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 + } + } } diff --git a/src/desktop/space/mod.rs b/src/desktop/space/mod.rs index 93b0ed9..36e817c 100644 --- a/src/desktop/space/mod.rs +++ b/src/desktop/space/mod.rs @@ -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::>(), )?; - let custom_elements = DynamicRenderElementMap(custom_elements); + let mut render_elements: Vec<&SpaceElem> = + Vec::with_capacity(custom_elements.len() + layer_map.len() + self.windows.len()); + + render_elements.append(&mut custom_elements.iter().map(|l| l as &SpaceElem).collect()); + render_elements.append(&mut self.windows.iter().map(|l| l as &SpaceElem).collect()); + render_elements.append(&mut layer_map.layers().map(|l| l as &SpaceElem).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), - ) - .chain(custom_elements.iter_above_background()) - .chain(layer_map.layers_on(WlrLayer::Bottom).map(|l| l as &SpaceElem)) - .chain(custom_elements.iter_before_windows()) - .chain(self.windows.iter().map(|w| w as &SpaceElem)) - .chain(custom_elements.iter_after_windows()) - .chain(layer_map.layers_on(WlrLayer::Top).map(|l| l as &SpaceElem)) - .chain(custom_elements.iter_before_overlay()) - .chain(layer_map.layers_on(WlrLayer::Overlay).map(|l| l as &SpaceElem)) - .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); diff --git a/src/desktop/space/popup.rs b/src/desktop/space/popup.rs index dbef156..6a0c423 100644 --- a/src/desktop/space/popup.rs +++ b/src/desktop/space/popup.rs @@ -12,6 +12,8 @@ use crate::{ }; use std::any::TypeId; +use super::RenderZindex; + #[derive(Debug)] pub struct RenderPopup { location: Point, @@ -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 + } } diff --git a/src/desktop/space/window.rs b/src/desktop/space/window.rs index f1ece6b..c000f04 100644 --- a/src/desktop/space/window.rs +++ b/src/desktop/space/window.rs @@ -13,6 +13,8 @@ use std::{ collections::HashMap, }; +use super::RenderZindex; + #[derive(Default)] pub struct WindowState { pub location: Point, @@ -103,4 +105,8 @@ where } res } + + fn z_index(&self) -> u8 { + RenderZindex::Top as u8 + } }