element: Introduce SurfaceRenderElement
This commit is contained in:
parent
8b990e5658
commit
178c6593dc
12 changed files with 254 additions and 213 deletions
111
src/backend/render/wayland/mod.rs
Normal file
111
src/backend/render/wayland/mod.rs
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
use smithay::{
|
||||
backend::renderer::{
|
||||
ImportAll, Renderer,
|
||||
element::surface::{KindEvaluation, WaylandSurfaceRenderElement},
|
||||
utils::RendererSurfaceStateUserData,
|
||||
},
|
||||
reexports::wayland_server::protocol::wl_surface,
|
||||
render_elements,
|
||||
utils::{Logical, Physical, Point, Rectangle, Scale},
|
||||
wayland::compositor::{self, TraversalAction},
|
||||
};
|
||||
use tracing::warn;
|
||||
|
||||
use crate::backend::render::{
|
||||
element::AsGlowRenderer, wayland::clipped_surface::ClippedSurfaceRenderElement,
|
||||
};
|
||||
|
||||
pub mod clipped_surface;
|
||||
|
||||
render_elements! {
|
||||
pub SurfaceRenderElement<R> where R: AsGlowRenderer + ImportAll;
|
||||
Clipped=ClippedSurfaceRenderElement<R>,
|
||||
Wayland=WaylandSurfaceRenderElement<R>,
|
||||
}
|
||||
|
||||
pub fn render_elements_from_surface_tree<R, E>(
|
||||
renderer: &mut R,
|
||||
main_surface: &wl_surface::WlSurface,
|
||||
location: impl Into<Point<i32, Physical>>,
|
||||
geometry: impl Into<Rectangle<f64, Logical>>,
|
||||
scale: impl Into<Scale<f64>>,
|
||||
alpha: f32,
|
||||
should_clip: bool,
|
||||
radii: [u8; 4],
|
||||
kind: impl Into<KindEvaluation>,
|
||||
) -> Vec<E>
|
||||
where
|
||||
R: Renderer + ImportAll + AsGlowRenderer,
|
||||
R::TextureId: Clone + 'static,
|
||||
E: From<SurfaceRenderElement<R>>,
|
||||
{
|
||||
let location = location.into().to_f64();
|
||||
let geometry = geometry.into().to_f64();
|
||||
let scale = scale.into();
|
||||
let kind = kind.into();
|
||||
let mut surfaces: Vec<E> = Vec::new();
|
||||
|
||||
compositor::with_surface_tree_downward(
|
||||
main_surface,
|
||||
location,
|
||||
|_, states, location| {
|
||||
let mut location = *location;
|
||||
let data = states.data_map.get::<RendererSurfaceStateUserData>();
|
||||
|
||||
if let Some(data) = data {
|
||||
if let Some(view) = data.lock().unwrap().view() {
|
||||
location += view.offset.to_f64().to_physical(scale);
|
||||
TraversalAction::DoChildren(location)
|
||||
} else {
|
||||
TraversalAction::SkipChildren
|
||||
}
|
||||
} else {
|
||||
TraversalAction::SkipChildren
|
||||
}
|
||||
},
|
||||
|surface, states, location| {
|
||||
let mut location = *location;
|
||||
let kind = kind.eval(states);
|
||||
let data = states.data_map.get::<RendererSurfaceStateUserData>();
|
||||
|
||||
if let Some(data) = data {
|
||||
let has_view = if let Some(view) = data.lock().unwrap().view() {
|
||||
location += view.offset.to_f64().to_physical(scale);
|
||||
|
||||
true
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
if has_view {
|
||||
match WaylandSurfaceRenderElement::from_surface(
|
||||
renderer, surface, states, location, alpha, kind,
|
||||
) {
|
||||
Ok(Some(surface)) => {
|
||||
let elem: SurfaceRenderElement<R> = if radii.iter().any(|r| *r != 0)
|
||||
&& should_clip
|
||||
&& ClippedSurfaceRenderElement::will_clip(
|
||||
&surface, scale, geometry, radii,
|
||||
) {
|
||||
ClippedSurfaceRenderElement::new(
|
||||
renderer, surface, scale, geometry, radii,
|
||||
)
|
||||
.into()
|
||||
} else {
|
||||
surface.into()
|
||||
};
|
||||
surfaces.push(elem.into());
|
||||
}
|
||||
Ok(None) => {} // surface is not mapped
|
||||
Err(err) => {
|
||||
warn!("Failed to import surface: {}", err);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
|_, _, _| true,
|
||||
);
|
||||
|
||||
surfaces
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue