When cosmic-workspaces is shown, render only layer-shell surfaces

This allows `cosmic-workspaces` to rely on cosmic-comp for rendering the
background, and just have transparency. This should be a more reliable
and performant way of doing things, at least for now.

Instead of adding another opaque bool argument, this defines an
`ElementFilter` enum, which makes calls more readable.

Window surfaces are still included in screencopy, as needed for the
workspace previews.
This commit is contained in:
Ian Douglas Scott 2024-07-09 20:46:41 -07:00 committed by Victoria Brekenfeld
parent 31358d1993
commit 355b142c52
3 changed files with 83 additions and 60 deletions

View file

@ -3,13 +3,15 @@
use crate::{ use crate::{
backend::render::{ backend::render::{
element::{CosmicElement, DamageElement}, element::{CosmicElement, DamageElement},
init_shaders, workspace_elements, CursorMode, GlMultiRenderer, CLEAR_COLOR, init_shaders, workspace_elements, CursorMode, ElementFilter, GlMultiRenderer, CLEAR_COLOR,
}, },
shell::Shell, shell::Shell,
state::SurfaceDmabufFeedback, state::SurfaceDmabufFeedback,
utils::prelude::*, utils::prelude::*,
wayland::{ wayland::{
handlers::screencopy::{submit_buffer, FrameHolder, SessionData}, handlers::screencopy::{
submit_buffer, FrameHolder, SessionData, WORKSPACE_OVERVIEW_NAMESPACE,
},
protocols::screencopy::{ protocols::screencopy::{
FailureReason, Frame as ScreencopyFrame, Session as ScreencopySession, FailureReason, Frame as ScreencopyFrame, Session as ScreencopySession,
}, },
@ -46,7 +48,7 @@ use smithay::{
Bind, ImportDma, Offscreen, Renderer, Texture, Bind, ImportDma, Offscreen, Renderer, Texture,
}, },
}, },
desktop::utils::OutputPresentationFeedback, desktop::{layer_map_for_output, utils::OutputPresentationFeedback},
output::{Output, OutputNoMode}, output::{Output, OutputNoMode},
reexports::{ reexports::{
calloop::{ calloop::{
@ -869,6 +871,15 @@ impl SurfaceThreadState {
std::mem::drop(shell); std::mem::drop(shell);
let element_filter = if layer_map_for_output(output)
.layers()
.any(|s| s.namespace() == WORKSPACE_OVERVIEW_NAMESPACE)
{
ElementFilter::LayerShellOnly
} else {
ElementFilter::All
};
workspace_elements( workspace_elements(
Some(&render_node), Some(&render_node),
&mut renderer, &mut renderer,
@ -878,7 +889,7 @@ impl SurfaceThreadState {
previous_workspace, previous_workspace,
workspace, workspace,
CursorMode::All, CursorMode::All,
false, element_filter,
#[cfg(not(feature = "debug"))] #[cfg(not(feature = "debug"))]
None, None,
#[cfg(feature = "debug")] #[cfg(feature = "debug")]

View file

@ -464,6 +464,13 @@ where
#[cfg(not(feature = "debug"))] #[cfg(not(feature = "debug"))]
pub type EguiState = (); pub type EguiState = ();
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ElementFilter {
All,
ExcludeWorkspaceOverview,
LayerShellOnly,
}
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct SplitRenderElements<E> { pub struct SplitRenderElements<E> {
pub w_elements: Vec<E>, pub w_elements: Vec<E>,
@ -528,7 +535,7 @@ pub fn workspace_elements<R>(
previous: Option<(WorkspaceHandle, usize, WorkspaceDelta)>, previous: Option<(WorkspaceHandle, usize, WorkspaceDelta)>,
current: (WorkspaceHandle, usize), current: (WorkspaceHandle, usize),
cursor_mode: CursorMode, cursor_mode: CursorMode,
exclude_workspace_overview: bool, element_filter: ElementFilter,
_fps: Option<(&EguiState, &Timings)>, _fps: Option<(&EguiState, &Timings)>,
) -> Result<Vec<CosmicElement<R>>, RenderError<R>> ) -> Result<Vec<CosmicElement<R>>, RenderError<R>>
where where
@ -556,7 +563,7 @@ where
now, now,
output, output,
cursor_mode, cursor_mode,
exclude_workspace_overview, element_filter == ElementFilter::ExcludeWorkspaceOverview,
)); ));
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
@ -642,8 +649,7 @@ where
.as_ref() .as_ref()
.filter(|f| !f.is_animating()) .filter(|f| !f.is_animating())
.is_some(); .is_some();
let overlay_elements = let overlay_elements = split_layer_elements(renderer, output, Layer::Overlay, element_filter);
split_layer_elements(renderer, output, Layer::Overlay, exclude_workspace_overview);
// overlay is above everything // overlay is above everything
elements elements
@ -655,7 +661,7 @@ where
if !has_fullscreen { if !has_fullscreen {
elements.extend_from_workspace_elements( elements.extend_from_workspace_elements(
split_layer_elements(renderer, output, Layer::Top, exclude_workspace_overview), split_layer_elements(renderer, output, Layer::Top, element_filter),
(0, 0).into(), (0, 0).into(),
); );
}; };
@ -669,32 +675,34 @@ where
// overlay redirect windows // overlay redirect windows
// they need to be over sticky windows, because they could be popups of sticky windows, // they need to be over sticky windows, because they could be popups of sticky windows,
// and we can't differenciate that. // and we can't differenciate that.
elements.p_elements.extend( if element_filter != ElementFilter::LayerShellOnly {
shell elements.p_elements.extend(
.override_redirect_windows shell
.iter() .override_redirect_windows
.filter(|or| { .iter()
(*or) .filter(|or| {
.geometry() (*or)
.as_global() .geometry()
.intersection(workspace.output.geometry()) .as_global()
.is_some() .intersection(workspace.output.geometry())
}) .is_some()
.flat_map(|or| { })
AsRenderElements::<R>::render_elements::<WorkspaceRenderElement<R>>( .flat_map(|or| {
or, AsRenderElements::<R>::render_elements::<WorkspaceRenderElement<R>>(
renderer, or,
(or.geometry().loc - workspace.output.geometry().loc.as_logical()) renderer,
.to_physical_precise_round(output_scale), (or.geometry().loc - workspace.output.geometry().loc.as_logical())
Scale::from(output_scale), .to_physical_precise_round(output_scale),
1.0, Scale::from(output_scale),
) 1.0,
}) )
.map(|p_element| p_element.into()), })
); .map(|p_element| p_element.into()),
);
}
// sticky windows // sticky windows
if !has_fullscreen { if !has_fullscreen && element_filter != ElementFilter::LayerShellOnly {
let alpha = match &overview.0 { let alpha = match &overview.0 {
OverviewMode::Started(_, started) => { OverviewMode::Started(_, started) => {
(1.0 - (Instant::now().duration_since(*started).as_millis() (1.0 - (Instant::now().duration_since(*started).as_millis()
@ -785,7 +793,7 @@ where
if !has_fullscreen { if !has_fullscreen {
elements.extend_from_workspace_elements( elements.extend_from_workspace_elements(
background_layer_elements(renderer, output, exclude_workspace_overview), background_layer_elements(renderer, output, element_filter),
offset.to_physical_precise_round(output_scale), offset.to_physical_precise_round(output_scale),
); );
} }
@ -800,23 +808,25 @@ where
None => (0, 0).into(), None => (0, 0).into(),
}; };
elements.extend_from_workspace_elements( if element_filter != ElementFilter::LayerShellOnly {
workspace elements.extend_from_workspace_elements(
.render::<R>( workspace
renderer, .render::<R>(
(!move_active && is_active_space).then_some(&last_active_seat), renderer,
overview, (!move_active && is_active_space).then_some(&last_active_seat),
resize_indicator, overview,
active_hint, resize_indicator,
theme, active_hint,
) theme,
.map_err(|_| OutputNoMode)?, )
offset.to_physical_precise_round(output_scale), .map_err(|_| OutputNoMode)?,
); offset.to_physical_precise_round(output_scale),
);
}
if !has_fullscreen { if !has_fullscreen {
elements.extend_from_workspace_elements( elements.extend_from_workspace_elements(
background_layer_elements(renderer, output, exclude_workspace_overview), background_layer_elements(renderer, output, element_filter),
offset.to_physical_precise_round(output_scale), offset.to_physical_precise_round(output_scale),
); );
} }
@ -828,7 +838,7 @@ pub fn split_layer_elements<R>(
renderer: &mut R, renderer: &mut R,
output: &Output, output: &Output,
layer: Layer, layer: Layer,
exclude_workspace_overview: bool, element_filter: ElementFilter,
) -> SplitRenderElements<WorkspaceRenderElement<R>> ) -> SplitRenderElements<WorkspaceRenderElement<R>>
where where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer, R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
@ -845,7 +855,10 @@ where
layer_map layer_map
.layers_on(layer) .layers_on(layer)
.rev() .rev()
.filter(|s| !(exclude_workspace_overview && s.namespace() == WORKSPACE_OVERVIEW_NAMESPACE)) .filter(|s| {
!(element_filter == ElementFilter::ExcludeWorkspaceOverview
&& s.namespace() == WORKSPACE_OVERVIEW_NAMESPACE)
})
.filter_map(|surface| { .filter_map(|surface| {
layer_map layer_map
.layer_geometry(surface) .layer_geometry(surface)
@ -895,7 +908,7 @@ where
pub fn background_layer_elements<R>( pub fn background_layer_elements<R>(
renderer: &mut R, renderer: &mut R,
output: &Output, output: &Output,
exclude_workspace_overview: bool, element_filter: ElementFilter,
) -> SplitRenderElements<WorkspaceRenderElement<R>> ) -> SplitRenderElements<WorkspaceRenderElement<R>>
where where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer, R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
@ -904,13 +917,12 @@ where
CosmicMappedRenderElement<R>: RenderElement<R>, CosmicMappedRenderElement<R>: RenderElement<R>,
WorkspaceRenderElement<R>: RenderElement<R>, WorkspaceRenderElement<R>: RenderElement<R>,
{ {
let mut elements = let mut elements = split_layer_elements(renderer, output, Layer::Bottom, element_filter);
split_layer_elements(renderer, output, Layer::Bottom, exclude_workspace_overview);
elements.extend(split_layer_elements( elements.extend(split_layer_elements(
renderer, renderer,
output, output,
Layer::Background, Layer::Background,
exclude_workspace_overview, element_filter,
)); ));
elements elements
} }
@ -990,7 +1002,7 @@ where
previous_workspace, previous_workspace,
workspace, workspace,
cursor_mode, cursor_mode,
false, ElementFilter::All,
); );
match result { match result {
@ -1102,7 +1114,7 @@ pub fn render_workspace<'d, R, Target, OffTarget>(
previous: Option<(WorkspaceHandle, usize, WorkspaceDelta)>, previous: Option<(WorkspaceHandle, usize, WorkspaceDelta)>,
current: (WorkspaceHandle, usize), current: (WorkspaceHandle, usize),
cursor_mode: CursorMode, cursor_mode: CursorMode,
exclude_workspace_overview: bool, element_filter: ElementFilter,
) -> Result<(RenderOutputResult<'d>, Vec<CosmicElement<R>>), RenderError<R>> ) -> Result<(RenderOutputResult<'d>, Vec<CosmicElement<R>>), RenderError<R>>
where where
R: Renderer R: Renderer
@ -1128,7 +1140,7 @@ where
previous, previous,
current, current,
cursor_mode, cursor_mode,
exclude_workspace_overview, element_filter,
None, None,
)?; )?;

View file

@ -36,7 +36,7 @@ use crate::{
backend::render::{ backend::render::{
cursor, cursor,
element::{AsGlowRenderer, CosmicElement, DamageElement, FromGlesError}, element::{AsGlowRenderer, CosmicElement, DamageElement, FromGlesError},
render_workspace, CursorMode, CLEAR_COLOR, render_workspace, CursorMode, ElementFilter, CLEAR_COLOR,
}, },
shell::{CosmicMappedRenderElement, CosmicSurface, WorkspaceRenderElement}, shell::{CosmicMappedRenderElement, CosmicSurface, WorkspaceRenderElement},
state::{BackendData, Common, State}, state::{BackendData, Common, State},
@ -287,7 +287,7 @@ pub fn render_workspace_to_buffer(
None, None,
handle, handle,
cursor_mode, cursor_mode,
true, ElementFilter::ExcludeWorkspaceOverview,
) )
.map(|res| res.0) .map(|res| res.0)
} else { } else {
@ -316,7 +316,7 @@ pub fn render_workspace_to_buffer(
None, None,
handle, handle,
cursor_mode, cursor_mode,
true, ElementFilter::ExcludeWorkspaceOverview,
) )
.map(|res| res.0) .map(|res| res.0)
} }