Add a SplitRenderElements type, with useful methods

`(w_elements, p_elements)` tuples are used in a bunch of places. A
struct with named fields is generally an improvement just due to the
fact the order is non-obvious.

But we can also add methods. In particular,
`extend_from_workspace_elements` abstracts out some of the more
redundant code in `workspace_elements`.

It would be nice to avoid allocation everywhere, but iterators would
complicate lifetimes, run into issues with needing multiple mutable
borrows to things like the `Renderer`, and be awkward in certain
functions without generator syntax. In any case, cosmic-comp already
relies on allocating vectors here.

If this abstraction is commonly useful in compositors, perhaps it could
be moved to Smithay.
This commit is contained in:
Ian Douglas Scott 2024-07-09 15:21:16 -07:00 committed by Victoria Brekenfeld
parent c506d94ac8
commit 94fecec9cb
9 changed files with 374 additions and 379 deletions

View file

@ -1,7 +1,7 @@
use crate::{
backend::render::{
element::{AsGlowFrame, AsGlowRenderer},
GlMultiError, GlMultiFrame, GlMultiRenderer,
GlMultiError, GlMultiFrame, GlMultiRenderer, SplitRenderElements,
},
state::State,
utils::{iced::IcedElementInternal, prelude::*},
@ -663,7 +663,7 @@ impl CosmicMapped {
location: smithay::utils::Point<i32, smithay::utils::Physical>,
scale: smithay::utils::Scale<f64>,
alpha: f32,
) -> (Vec<C>, Vec<C>)
) -> SplitRenderElements<C>
where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: Send + Clone + 'static,
@ -842,27 +842,28 @@ impl CosmicMapped {
#[cfg(not(feature = "debug"))]
let debug_elements = Vec::new();
#[cfg_attr(not(feature = "debug"), allow(unused_mut))]
let (window_elements, popup_elements) = match &self.element {
CosmicMappedInternal::Stack(s) => s
.split_render_elements::<R, CosmicMappedRenderElement<R>>(
renderer, location, scale, alpha,
),
CosmicMappedInternal::Window(w) => w
.split_render_elements::<R, CosmicMappedRenderElement<R>>(
renderer, location, scale, alpha,
),
_ => unreachable!(),
let mut elements = SplitRenderElements {
w_elements: debug_elements,
p_elements: Vec::new(),
};
(
debug_elements
.into_iter()
.map(C::from)
.chain(window_elements.into_iter().map(C::from))
.collect(),
popup_elements.into_iter().map(C::from).collect(),
)
#[cfg_attr(not(feature = "debug"), allow(unused_mut))]
elements.extend_map(
match &self.element {
CosmicMappedInternal::Stack(s) => s
.split_render_elements::<R, CosmicMappedRenderElement<R>>(
renderer, location, scale, alpha,
),
CosmicMappedInternal::Window(w) => w
.split_render_elements::<R, CosmicMappedRenderElement<R>>(
renderer, location, scale, alpha,
),
_ => unreachable!(),
},
C::from,
);
elements
}
pub(crate) fn update_theme(&self, theme: cosmic::Theme) {

View file

@ -1,6 +1,9 @@
use super::{surface::RESIZE_BORDER, window::Focus, CosmicSurface};
use crate::{
backend::render::cursor::{CursorShape, CursorState},
backend::render::{
cursor::{CursorShape, CursorState},
SplitRenderElements,
},
shell::{
focus::target::PointerFocusTarget,
grabs::{ReleaseMode, ResizeEdge},
@ -547,7 +550,7 @@ impl CosmicStack {
location: Point<i32, Physical>,
scale: Scale<f64>,
alpha: f32,
) -> (Vec<C>, Vec<C>)
) -> SplitRenderElements<C>
where
R: Renderer + ImportAll + ImportMem,
<R as Renderer>::TextureId: Send + Clone + 'static,
@ -564,30 +567,28 @@ impl CosmicStack {
let stack_loc = location + offset;
let window_loc = location + Point::from((0, (TAB_HEIGHT as f64 * scale.y) as i32));
let elements = AsRenderElements::<R>::render_elements::<CosmicStackRenderElement<R>>(
let w_elements = AsRenderElements::<R>::render_elements::<CosmicStackRenderElement<R>>(
&self.0, renderer, stack_loc, scale, alpha,
);
let (window_elements, popup_elements) = self.0.with_program(|p| {
let windows = p.windows.lock().unwrap();
let active = p.active.load(Ordering::SeqCst);
let mut elements = SplitRenderElements {
w_elements: w_elements.into_iter().map(C::from).collect(),
p_elements: Vec::new(),
};
let (window_elements, popup_elements) = windows[active]
.split_render_elements::<R, CosmicStackRenderElement<R>>(
elements.extend_map(
self.0.with_program(|p| {
let windows = p.windows.lock().unwrap();
let active = p.active.load(Ordering::SeqCst);
windows[active].split_render_elements::<R, CosmicStackRenderElement<R>>(
renderer, window_loc, scale, alpha,
);
)
}),
C::from,
);
(window_elements, popup_elements)
});
(
elements
.into_iter()
.map(C::from)
.chain(window_elements.into_iter().map(C::from))
.collect(),
popup_elements.into_iter().map(C::from).collect(),
)
elements
}
pub(crate) fn set_theme(&self, theme: cosmic::Theme) {

View file

@ -42,6 +42,7 @@ use smithay::{
};
use crate::{
backend::render::SplitRenderElements,
state::{State, SurfaceDmabufFeedback},
utils::prelude::*,
wayland::handlers::decoration::PreferredDecorationMode,
@ -563,7 +564,7 @@ impl CosmicSurface {
location: smithay::utils::Point<i32, smithay::utils::Physical>,
scale: smithay::utils::Scale<f64>,
alpha: f32,
) -> (Vec<C>, Vec<C>)
) -> SplitRenderElements<C>
where
R: Renderer + ImportAll,
<R as Renderer>::TextureId: Clone + 'static,
@ -573,7 +574,7 @@ impl CosmicSurface {
WindowSurface::Wayland(toplevel) => {
let surface = toplevel.wl_surface();
let popup_render_elements = PopupManager::popups_for_surface(surface)
let p_elements = PopupManager::popups_for_surface(surface)
.flat_map(|(popup, popup_offset)| {
let offset = (self.0.geometry().loc + popup_offset - popup.geometry().loc)
.to_physical_precise_round(scale);
@ -589,7 +590,7 @@ impl CosmicSurface {
})
.collect();
let window_render_elements = render_elements_from_surface_tree(
let w_elements = render_elements_from_surface_tree(
renderer,
surface,
location,
@ -598,12 +599,15 @@ impl CosmicSurface {
element::Kind::Unspecified,
);
(window_render_elements, popup_render_elements)
SplitRenderElements {
w_elements,
p_elements,
}
}
WindowSurface::X11(surface) => (
surface.render_elements(renderer, location, scale, alpha),
Vec::new(),
),
WindowSurface::X11(surface) => SplitRenderElements {
w_elements: surface.render_elements(renderer, location, scale, alpha),
p_elements: Vec::new(),
},
}
}

View file

@ -1,5 +1,8 @@
use crate::{
backend::render::cursor::{CursorShape, CursorState},
backend::render::{
cursor::{CursorShape, CursorState},
SplitRenderElements,
},
shell::{
focus::target::PointerFocusTarget,
grabs::{ReleaseMode, ResizeEdge},
@ -317,7 +320,7 @@ impl CosmicWindow {
location: smithay::utils::Point<i32, smithay::utils::Physical>,
scale: smithay::utils::Scale<f64>,
alpha: f32,
) -> (Vec<C>, Vec<C>)
) -> SplitRenderElements<C>
where
R: Renderer + ImportAll + ImportMem,
<R as Renderer>::TextureId: Send + Clone + 'static,
@ -331,12 +334,17 @@ impl CosmicWindow {
location
};
let (mut window_elements, popup_elements) = self.0.with_program(|p| {
p.window
.split_render_elements::<R, CosmicWindowRenderElement<R>>(
renderer, window_loc, scale, alpha,
)
});
let mut elements = SplitRenderElements::default();
elements.extend_map(
self.0.with_program(|p| {
p.window
.split_render_elements::<R, CosmicWindowRenderElement<R>>(
renderer, window_loc, scale, alpha,
)
}),
C::from,
);
if has_ssd {
let ssd_loc = location
@ -344,15 +352,16 @@ impl CosmicWindow {
.0
.with_program(|p| p.window.geometry().loc)
.to_physical_precise_round(scale);
window_elements.extend(AsRenderElements::<R>::render_elements::<
CosmicWindowRenderElement<R>,
>(&self.0, renderer, ssd_loc, scale, alpha))
elements.w_elements.extend(
AsRenderElements::<R>::render_elements::<CosmicWindowRenderElement<R>>(
&self.0, renderer, ssd_loc, scale, alpha,
)
.into_iter()
.map(C::from),
)
}
(
window_elements.into_iter().map(C::from).collect(),
popup_elements.into_iter().map(C::from).collect(),
)
elements
}
pub(crate) fn set_theme(&self, theme: cosmic::Theme) {