desktop: Decouple feature-set from wayland_frontend

This commit is contained in:
Victoria Brekenfeld 2022-09-05 14:26:42 +02:00
parent 768dcc0e4a
commit e31843762b
9 changed files with 133 additions and 60 deletions

View file

@ -37,7 +37,7 @@ drm-ffi = { version = "0.3.0", optional = true }
gbm = { version = "0.9.0", optional = true, default-features = false, features = ["drm-support"] }
glow = { version = "0.11.2", optional = true }
input = { version = "0.7", default-features = false, features=["libinput_1_14"], optional = true }
indexmap = { version = "1.7", optional = true }
indexmap = "1.7"
lazy_static = "1"
libc = "0.2.103"
libseat= { version = "0.1.1", optional = true }
@ -87,12 +87,12 @@ backend_vulkan = ["ash", "scopeguard"]
backend_session_logind = ["dbus", "backend_session", "pkg-config"]
backend_session_elogind = ["backend_session_logind"]
backend_session_libseat = ["backend_session", "libseat"]
desktop = ["wayland_frontend"]
desktop = []
renderer_gl = ["gl_generator", "backend_egl"]
renderer_glow = ["renderer_gl", "glow"]
renderer_multi = ["backend_drm"]
use_system_lib = ["wayland_frontend", "wayland-backend/server_system", "wayland-sys"]
wayland_frontend = ["wayland-server", "wayland-protocols", "tempfile", "indexmap"]
wayland_frontend = ["wayland-server", "wayland-protocols", "tempfile"]
x11rb_event_source = ["x11rb"]
xwayland = ["wayland_frontend"]
test_all_features = ["default", "renderer_glow"]

View file

@ -49,7 +49,8 @@ impl<T: Texture> PointerElement<T> {
}
render_elements! {
pub PointerRenderElement<R>;
pub PointerRenderElement<R> where
R: ImportAll;
Surface=WaylandSurfaceRenderElement,
Texture=TextureRenderElement<<R as Renderer>::TextureId>,
}

View file

@ -17,7 +17,8 @@ use crate::{
};
smithay::backend::renderer::element::render_elements! {
pub CustomRenderElements<R>;
pub CustomRenderElements<R> where
R: ImportAll;
Pointer=PointerRenderElement<R>,
Surface=WaylandSurfaceRenderElement,
#[cfg(feature = "debug")]

View file

@ -2,6 +2,7 @@
use std::sync::Arc;
#[cfg(feature = "wayland_frontend")]
use wayland_server::{backend::ObjectId, protocol::wl_buffer, Resource};
use crate::utils::{Physical, Point, Rectangle, Scale};
@ -9,6 +10,7 @@ use crate::utils::{Physical, Point, Rectangle, Scale};
use super::{utils::CommitCounter, Renderer};
pub mod memory;
#[cfg(feature = "wayland_frontend")]
pub mod surface;
pub mod texture;
@ -20,6 +22,7 @@ pub struct Id(InnerId);
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
enum InnerId {
#[cfg(feature = "wayland_frontend")]
WaylandResource(ObjectId),
External(Arc<ExternalId>),
}
@ -44,6 +47,7 @@ impl Id {
///
/// Note: Calling this function for the same [`Resource`]
/// multiple times will return the same id.
#[cfg(feature = "wayland_frontend")]
pub fn from_wayland_resource<R: Resource>(resource: &R) -> Self {
Id(InnerId::WaylandResource(resource.id()))
}
@ -61,6 +65,7 @@ impl Id {
#[derive(Debug)]
pub enum UnderlyingStorage<'a, R: Renderer> {
/// A wayland buffer
#[cfg(feature = "wayland_frontend")]
Wayland(wl_buffer::WlBuffer),
/// A texture
External(&'a R::TextureId),
@ -233,7 +238,7 @@ macro_rules! render_elements_internal {
$(#[$attr])*
$vis enum $name<$renderer>
where
$renderer: $crate::backend::renderer::Renderer + $crate::backend::renderer::ImportAll,
$renderer: $crate::backend::renderer::Renderer,
{
$(
$(
@ -249,7 +254,7 @@ macro_rules! render_elements_internal {
$(#[$attr])*
$vis enum $name<$renderer, $($custom),+>
where
$renderer: $crate::backend::renderer::Renderer + $crate::backend::renderer::ImportAll,
$renderer: $crate::backend::renderer::Renderer,
$(
$custom: $crate::backend::renderer::element::RenderElement<$renderer>,
)+
@ -268,7 +273,7 @@ macro_rules! render_elements_internal {
$(#[$attr])*
$vis enum $name<$lt, $renderer>
where
$renderer: $crate::backend::renderer::Renderer + $crate::backend::renderer::ImportAll,
$renderer: $crate::backend::renderer::Renderer,
<$renderer as $crate::backend::renderer::Renderer>::TextureId: 'static,
{
$(
@ -285,7 +290,7 @@ macro_rules! render_elements_internal {
$(#[$attr])*
$vis enum $name<$lt, $renderer, $($custom),+>
where
$renderer: $crate::backend::renderer::Renderer + $crate::backend::renderer::ImportAll,
$renderer: $crate::backend::renderer::Renderer,
<$renderer as $crate::backend::renderer::Renderer>::TextureId: 'static,
$(
$custom: $crate::backend::renderer::element::RenderElement<$renderer>,
@ -459,7 +464,7 @@ macro_rules! render_elements_internal {
(@impl $name:ident<$renderer:ident> $(where $($target:ty: $bound:tt $(+ $additional_bound:tt)*),+)?; $($tail:tt)*) => {
impl<$renderer> $crate::backend::renderer::element::RenderElement<$renderer> for $name<$renderer>
where
$renderer: $crate::backend::renderer::Renderer + $crate::backend::renderer::ImportAll,
$renderer: $crate::backend::renderer::Renderer,
<$renderer as Renderer>::TextureId: 'static,
$($($target: $bound $(+ $additional_bound)*),+)?
{
@ -470,7 +475,7 @@ macro_rules! render_elements_internal {
(@impl $name:ident<$lt:lifetime, $renderer:ident> $(where $($target:ty: $bound:tt $(+ $additional_bound:tt)*),+)?; $($tail:tt)*) => {
impl<$lt, $renderer> $crate::backend::renderer::element::RenderElement<$renderer> for $name<$lt, $renderer>
where
$renderer: $crate::backend::renderer::Renderer + $crate::backend::renderer::ImportAll,
$renderer: $crate::backend::renderer::Renderer,
<$renderer as Renderer>::TextureId: 'static,
$($($target: $bound $(+ $additional_bound)*),+)?
{
@ -481,7 +486,7 @@ macro_rules! render_elements_internal {
(@impl $name:ident<$renderer:ident, $($custom:ident),+> $(where $($target:ty: $bound:tt $(+ $additional_bound:tt)*),+)?; $($tail:tt)*) => {
impl<$renderer, $($custom),+> $crate::backend::renderer::element::RenderElement<$renderer> for $name<$renderer, $($custom),+>
where
$renderer: $crate::backend::renderer::Renderer + $crate::backend::renderer::ImportAll,
$renderer: $crate::backend::renderer::Renderer,
<$renderer as Renderer>::TextureId: 'static,
$(
$custom: $crate::backend::renderer::element::RenderElement<$renderer>,
@ -495,7 +500,7 @@ macro_rules! render_elements_internal {
(@impl $name:ident<$lt:lifetime, $renderer:ident, $($custom:ident),+> $(where $($target:ty: $bound:tt $(+ $additional_bound:tt)*),+)?; $($tail:tt)*) => {
impl<$lt, $renderer, $($custom),+> $crate::backend::renderer::element::RenderElement<$renderer> for $name<$lt, $renderer, $($custom),+>
where
$renderer: $crate::backend::renderer::Renderer + $crate::backend::renderer::ImportAll,
$renderer: $crate::backend::renderer::Renderer,
<$renderer as Renderer>::TextureId: 'static,
$(
$custom: $crate::backend::renderer::element::RenderElement<$renderer>,
@ -509,7 +514,7 @@ macro_rules! render_elements_internal {
(@impl $name:ident; $renderer:ident; $($tail:tt)*) => {
impl<$renderer> $crate::backend::renderer::element::RenderElement<$renderer> for $name
where
$renderer: $crate::backend::renderer::Renderer + $crate::backend::renderer::ImportAll,
$renderer: $crate::backend::renderer::Renderer,
<$renderer as Renderer>::TextureId: 'static,
{
$crate::render_elements_internal!(@body $renderer; $($tail)*);
@ -567,7 +572,7 @@ macro_rules! render_elements_internal {
)*
impl<$renderer> From<$field> for $name<$renderer>
where
$renderer: $crate::backend::renderer::Renderer + $crate::backend::renderer::ImportAll,
$renderer: $crate::backend::renderer::Renderer,
$(
$($renderer: std::convert::AsMut<$other_renderer>,)?
)*
@ -585,7 +590,7 @@ macro_rules! render_elements_internal {
)*
impl<$renderer, $custom> From<$field> for $name<$renderer, $custom>
where
$renderer: $crate::backend::renderer::Renderer + $crate::backend::renderer::ImportAll,
$renderer: $crate::backend::renderer::Renderer,
$custom: $crate::backend::renderer::element::RenderElement<$renderer>,
$(
$($renderer: std::convert::AsMut<$other_renderer>,)?
@ -604,7 +609,7 @@ macro_rules! render_elements_internal {
)*
impl<$lt, $renderer> From<$field> for $name<$lt, $renderer>
where
$renderer: $crate::backend::renderer::Renderer + $crate::backend::renderer::ImportAll,
$renderer: $crate::backend::renderer::Renderer,
$(
$($renderer: std::convert::AsMut<$other_renderer>,)?
)*
@ -622,7 +627,7 @@ macro_rules! render_elements_internal {
)*
impl<$lt, $renderer, $custom> From<$field> for $name<$lt, $renderer, $custom>
where
$renderer: $crate::backend::renderer::Renderer + $crate::backend::renderer::ImportAll,
$renderer: $crate::backend::renderer::Renderer,
$custom: $crate::backend::renderer::element::RenderElement<$renderer>,
$(
$($renderer: std::convert::AsMut<$other_renderer>,)?

View file

@ -40,10 +40,8 @@ pub mod multigpu;
#[cfg(feature = "wayland_frontend")]
pub mod utils;
#[cfg(feature = "wayland_frontend")]
pub mod element;
#[cfg(feature = "wayland_frontend")]
pub mod damage;
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]

View file

@ -49,13 +49,20 @@
//! to manage client buffers to do so. If you plan to use the provided drawing functions, you need to use
//! [`on_commit_buffer_handler`](crate::backend::renderer::utils::on_commit_buffer_handler).
#[cfg(feature = "wayland_frontend")]
pub(crate) mod layer;
#[cfg(feature = "wayland_frontend")]
mod popup;
pub mod space;
#[cfg(feature = "wayland_frontend")]
pub mod utils;
#[cfg(feature = "wayland_frontend")]
mod window;
#[cfg(feature = "wayland_frontend")]
pub use self::layer::{draw_layer_surface, layer_map_for_output, LayerMap, LayerSurface};
#[cfg(feature = "wayland_frontend")]
pub use self::popup::*;
pub use self::space::Space;
#[cfg(feature = "wayland_frontend")]
pub use self::window::*;

View file

@ -1,8 +1,12 @@
use crate::{
backend::renderer::{ImportAll, Renderer},
desktop::{space::*, utils as desktop_utils},
backend::renderer::{element::Wrap, Renderer},
desktop::space::*,
output::Output,
utils::{Logical, Physical, Point, Rectangle, Scale},
};
#[cfg(feature = "wayland_frontend")]
use crate::{
desktop::utils as desktop_utils,
wayland::compositor::{with_surface_tree_downward, TraversalAction},
};
use std::hash::Hash;
@ -89,6 +93,7 @@ impl<T: SpaceElement> SpaceElement for &T {
#[derive(Debug)]
pub(super) enum SpaceElements<'a, E> {
#[cfg(feature = "wayland_frontend")]
Layer {
surface: LayerSurface,
output_location: Point<i32, Logical>,
@ -102,6 +107,7 @@ where
{
pub(super) fn z_index(&self) -> u8 {
match self {
#[cfg(feature = "wayland_frontend")]
SpaceElements::Layer { surface, .. } => surface.z_index(),
SpaceElements::Element(inner) => inner.element.z_index(),
}
@ -109,6 +115,7 @@ where
pub(super) fn bbox(&self) -> Rectangle<i32, Logical> {
match self {
#[cfg(feature = "wayland_frontend")]
SpaceElements::Layer {
surface,
output_location,
@ -123,20 +130,24 @@ where
pub(super) fn render_location(&self) -> Point<i32, Logical> {
match self {
#[cfg(feature = "wayland_frontend")]
SpaceElements::Layer { .. } => self.bbox().loc,
SpaceElements::Element(inner) => inner.render_location(),
}
}
}
impl<'a, R, E> AsRenderElements<R> for SpaceElements<'a, E>
impl<
'a,
#[cfg(feature = "wayland_frontend")] R: Renderer + ImportAll,
#[cfg(not(feature = "wayland_frontend"))] R: Renderer,
E: AsRenderElements<R>,
> AsRenderElements<R> for SpaceElements<'a, E>
where
R: Renderer + ImportAll,
<R as Renderer>::TextureId: Texture + 'static,
E: AsRenderElements<R>,
<E as AsRenderElements<R>>::RenderElement: 'a,
SpaceRenderElements<R, <E as AsRenderElements<R>>::RenderElement>:
From<Wrap<<E as AsRenderElements<R>>::RenderElement>> + From<WaylandSurfaceRenderElement>,
From<Wrap<<E as AsRenderElements<R>>::RenderElement>>,
{
type RenderElement = SpaceRenderElements<R, <E as AsRenderElements<R>>::RenderElement>;
@ -146,22 +157,26 @@ where
scale: Scale<f64>,
) -> Vec<C> {
match &self {
SpaceElements::Layer { surface, .. } => {
AsRenderElements::<R>::render_elements::<Self::RenderElement>(surface, location, scale)
.into_iter()
.map(C::from)
.collect()
}
#[cfg(feature = "wayland_frontend")]
SpaceElements::Layer { surface, .. } => AsRenderElements::<R>::render_elements::<
WaylandSurfaceRenderElement,
>(surface, location, scale)
.into_iter()
.map(SpaceRenderElements::Surface)
.map(C::from)
.collect(),
SpaceElements::Element(element) => element
.element
.render_elements::<Wrap<<E as AsRenderElements<R>>::RenderElement>>(location, scale)
.into_iter()
.map(SpaceRenderElements::from)
.map(SpaceRenderElements::Element)
.map(C::from)
.collect(),
}
}
}
#[cfg(feature = "wayland_frontend")]
/// A custom surface tree
#[derive(Debug)]
pub struct SurfaceTree {
@ -169,6 +184,7 @@ pub struct SurfaceTree {
surface: WlSurface,
}
#[cfg(feature = "wayland_frontend")]
impl SurfaceTree {
/// Create a surface tree from a surface
pub fn from_surface(surface: &WlSurface, location: impl Into<Point<i32, Logical>>) -> Self {
@ -179,12 +195,14 @@ impl SurfaceTree {
}
}
#[cfg(feature = "wayland_frontend")]
impl IsAlive for SurfaceTree {
fn alive(&self) -> bool {
self.surface.alive()
}
}
#[cfg(feature = "wayland_frontend")]
impl SpaceElement for SurfaceTree {
fn geometry(&self) -> Rectangle<i32, Logical> {
self.bbox()
@ -224,6 +242,7 @@ impl SpaceElement for SurfaceTree {
}
}
#[cfg(feature = "wayland_frontend")]
impl<R> AsRenderElements<R> for SurfaceTree
where
R: Renderer + ImportAll,
@ -490,6 +509,7 @@ macro_rules! space_elements {
pub use space_elements;
#[cfg(test)]
#[cfg(feature = "wayland_frontend")]
#[allow(dead_code)]
mod tests {
use crate::desktop::{LayerSurface, Window};

View file

@ -6,24 +6,32 @@ use crate::{
damage::{
DamageTrackedRenderer, DamageTrackedRendererError, DamageTrackedRendererMode, OutputNoMode,
},
element::{surface::WaylandSurfaceRenderElement, AsRenderElements, RenderElement, Wrap},
ImportAll, Renderer, Texture,
element::{AsRenderElements, RenderElement, Wrap},
Renderer, Texture,
},
desktop::layer::{layer_map_for_output, LayerSurface},
output::Output,
utils::{IsAlive, Logical, Physical, Point, Rectangle, Scale, Transform},
};
#[cfg(feature = "wayland_frontend")]
use crate::{
backend::renderer::{element::surface::WaylandSurfaceRenderElement, ImportAll},
desktop::layer::{layer_map_for_output, LayerSurface},
};
use std::{collections::HashSet, fmt};
#[cfg(feature = "wayland_frontend")]
use wayland_server::protocol::wl_surface::WlSurface;
mod element;
#[cfg(feature = "wayland_frontend")]
mod layer;
mod output;
#[cfg(feature = "wayland_frontend")]
mod window;
pub use self::element::*;
use self::output::*;
#[cfg(feature = "wayland_frontend")]
use super::WindowSurfaceType;
crate::utils::ids::id_gen!(next_space_id, SPACE_ID, SPACE_IDS);
@ -186,6 +194,7 @@ impl<E: SpaceElement + PartialEq> Space<E> {
/// Returns the layer matching a given surface, if any
///
/// `surface_type` can be used to limit the types of surfaces queried for equality.
#[cfg(feature = "wayland_frontend")]
pub fn layer_for_surface(
&self,
surface: &WlSurface,
@ -335,12 +344,15 @@ impl<E: SpaceElement + PartialEq> Space<E> {
}
/// Retrieve the render elements for an output
pub fn elements_for_output<'a, R>(
pub fn elements_for_output<
'a,
#[cfg(feature = "wayland_frontend")] R: Renderer + ImportAll,
#[cfg(not(feature = "wayland_frontend"))] R: Renderer,
>(
&'a self,
output: &Output,
) -> Result<Vec<SpaceRenderElements<R, <E as AsRenderElements<R>>::RenderElement>>, OutputError>
where
R: Renderer + ImportAll,
<R as Renderer>::TextureId: Texture + 'static,
E: AsRenderElements<R>,
<E as AsRenderElements<R>>::RenderElement: 'a,
@ -360,15 +372,17 @@ impl<E: SpaceElement + PartialEq> Space<E> {
output_size.to_f64().to_logical(output_scale).to_i32_ceil(),
);
let layer_map = layer_map_for_output(output);
let mut space_elements: Vec<SpaceElements<'a, E>> = Vec::new();
let mut space_elements: Vec<SpaceElements<'a, E>> =
self.elements.iter().rev().map(SpaceElements::Element).collect();
space_elements.extend(self.elements.iter().rev().map(SpaceElements::Element));
space_elements.extend(layer_map.layers().rev().cloned().map(|l| SpaceElements::Layer {
surface: l,
output_location,
}));
#[cfg(feature = "wayland_frontend")]
{
let layer_map = layer_map_for_output(output);
space_elements.extend(layer_map.layers().rev().cloned().map(|l| SpaceElements::Layer {
surface: l,
output_location,
}));
}
space_elements.sort_by_key(|e| std::cmp::Reverse(e.z_index()));
@ -426,25 +440,39 @@ impl<E: SpaceElement> InnerElement<E> {
}
}
#[cfg(feature = "wayland_frontend")]
crate::backend::renderer::element::render_elements! {
/// Defines the render elements used internally by a [`Space`]
///
/// Use them in place of `E` in `space_render_elements` or
/// `render_output` if you do not need custom render elements
pub SpaceRenderElements<R, E> where
R: ImportAll;
/// A single wayland surface
Surface=WaylandSurfaceRenderElement,
/// A single texture
Element=Wrap<E>,
}
#[cfg(not(feature = "wayland_frontend"))]
crate::backend::renderer::element::render_elements! {
/// Defines the render elements used internally by a [`Space`]
///
/// Use them in place of `E` in `space_render_elements` or
/// `render_output` if you do not need custom render elements
pub SpaceRenderElements<R, E>;
/// A single wayland surface
Surface=WaylandSurfaceRenderElement,
/// A single texture
Element=Wrap<E>,
}
impl<R, E> std::fmt::Debug for SpaceRenderElements<R, E>
where
R: Renderer + ImportAll,
E: RenderElement<R> + std::fmt::Debug,
impl<
#[cfg(feature = "wayland_frontend")] R: Renderer + ImportAll,
#[cfg(not(feature = "wayland_frontend"))] R: Renderer,
E: RenderElement<R> + std::fmt::Debug,
> std::fmt::Debug for SpaceRenderElements<R, E>
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
#[cfg(feature = "wayland_frontend")]
Self::Surface(arg0) => f.debug_tuple("Surface").field(arg0).finish(),
Self::Element(arg0) => f.debug_tuple("Element").field(arg0).finish(),
Self::_GenericCatcher(_) => unreachable!(),
@ -452,6 +480,14 @@ where
}
}
#[cfg(feature = "wayland_frontend")]
crate::backend::renderer::element::render_elements! {
OutputRenderElements<'a, R, E, C> where
R: ImportAll;
Space=SpaceRenderElements<R, E>,
Custom=&'a C,
}
#[cfg(not(feature = "wayland_frontend"))]
crate::backend::renderer::element::render_elements! {
OutputRenderElements<'a, R, E, C>;
Space=SpaceRenderElements<R, E>,
@ -459,14 +495,17 @@ crate::backend::renderer::element::render_elements! {
}
/// Get the render elements for a specific output
pub fn space_render_elements<'a, R, E>(
pub fn space_render_elements<
'a,
#[cfg(feature = "wayland_frontend")] R: Renderer + ImportAll,
#[cfg(not(feature = "wayland_frontend"))] R: Renderer,
E: SpaceElement + PartialEq + AsRenderElements<R>,
>(
spaces: &[&'a Space<E>],
output: &Output,
) -> Result<Vec<SpaceRenderElements<R, <E as AsRenderElements<R>>::RenderElement>>, OutputNoMode>
where
R: Renderer + ImportAll,
<R as Renderer>::TextureId: Texture + 'static,
E: SpaceElement + PartialEq + AsRenderElements<R>,
<E as AsRenderElements<R>>::RenderElement: 'a,
SpaceRenderElements<R, <E as AsRenderElements<R>>::RenderElement>:
From<Wrap<<E as AsRenderElements<R>>::RenderElement>>,
@ -486,7 +525,13 @@ where
/// Render a output
#[allow(clippy::too_many_arguments)]
pub fn render_output<'a, R, C, E>(
pub fn render_output<
'a,
#[cfg(feature = "wayland_frontend")] R: Renderer + ImportAll,
#[cfg(not(feature = "wayland_frontend"))] R: Renderer,
C: RenderElement<R>,
E: SpaceElement + PartialEq + AsRenderElements<R>,
>(
output: &Output,
renderer: &mut R,
age: usize,
@ -497,13 +542,10 @@ pub fn render_output<'a, R, C, E>(
log: &slog::Logger,
) -> Result<Option<Vec<Rectangle<i32, Physical>>>, DamageTrackedRendererError<R>>
where
R: Renderer + ImportAll,
<R as Renderer>::TextureId: Texture + 'static,
E: SpaceElement + PartialEq + AsRenderElements<R>,
<E as AsRenderElements<R>>::RenderElement: 'a,
SpaceRenderElements<R, <E as AsRenderElements<R>>::RenderElement>:
From<Wrap<<E as AsRenderElements<R>>::RenderElement>>,
C: RenderElement<R>,
{
if let DamageTrackedRendererMode::Auto(renderer_output) = damage_tracked_renderer.mode() {
assert!(renderer_output == output);

View file

@ -6,7 +6,6 @@ pub mod signaling;
#[cfg(feature = "x11rb_event_source")]
pub mod x11rb;
#[cfg(any(feature = "desktop", feature = "wayland_frontend", feature = "renderer_gl"))]
pub(crate) mod ids;
pub mod user_data;