cosmic-comp/src/backend/render/element.rs

396 lines
14 KiB
Rust
Raw Normal View History

2022-11-17 20:32:54 +01:00
use crate::shell::{CosmicMappedRenderElement, WorkspaceRenderElement};
use smithay::{
backend::renderer::{
element::{
2024-03-12 19:42:48 +01:00
surface::WaylandSurfaceRenderElement,
utils::{Relocate, RelocateRenderElement},
2024-03-12 19:42:48 +01:00
Element, Id, RenderElement, UnderlyingStorage,
},
glow::{GlowFrame, GlowRenderer},
2024-04-08 16:55:41 -07:00
utils::{CommitCounter, DamageSet},
Frame, ImportAll, ImportMem, Renderer,
2022-11-17 20:32:54 +01:00
},
2024-03-12 19:42:48 +01:00
utils::{Buffer as BufferCoords, Logical, Physical, Point, Rectangle, Scale},
2022-11-17 20:32:54 +01:00
};
#[cfg(feature = "debug")]
use smithay::backend::renderer::{element::texture::TextureRenderElement, gles::GlesTexture};
use super::{cursor::CursorRenderElement, GlMultiError, GlMultiFrame, GlMultiRenderer};
2022-11-17 20:32:54 +01:00
pub enum CosmicElement<R>
where
R: AsGlowRenderer + Renderer + ImportAll + ImportMem,
2022-11-17 20:32:54 +01:00
<R as Renderer>::TextureId: 'static,
CosmicMappedRenderElement<R>: RenderElement<R>,
2022-11-17 20:32:54 +01:00
{
Workspace(RelocateRenderElement<WorkspaceRenderElement<R>>),
2024-03-12 19:42:48 +01:00
Cursor(RelocateRenderElement<CursorRenderElement<R>>),
Dnd(WaylandSurfaceRenderElement<R>),
2022-11-17 20:32:54 +01:00
MoveGrab(CosmicMappedRenderElement<R>),
2024-03-12 19:42:48 +01:00
AdditionalDamage(DamageElement),
2022-11-17 20:32:54 +01:00
#[cfg(feature = "debug")]
2023-05-03 19:47:48 +02:00
Egui(TextureRenderElement<GlesTexture>),
2022-11-17 20:32:54 +01:00
}
impl<R> Element for CosmicElement<R>
where
R: AsGlowRenderer + Renderer + ImportAll + ImportMem,
2022-11-17 20:32:54 +01:00
<R as Renderer>::TextureId: 'static,
CosmicMappedRenderElement<R>: RenderElement<R>,
2022-11-17 20:32:54 +01:00
{
2024-03-12 19:42:48 +01:00
fn id(&self) -> &Id {
2022-11-17 20:32:54 +01:00
match self {
CosmicElement::Workspace(elem) => elem.id(),
CosmicElement::Cursor(elem) => elem.id(),
2024-03-12 19:42:48 +01:00
CosmicElement::Dnd(elem) => elem.id(),
2022-11-17 20:32:54 +01:00
CosmicElement::MoveGrab(elem) => elem.id(),
2024-03-12 19:42:48 +01:00
CosmicElement::AdditionalDamage(elem) => elem.id(),
2022-11-17 20:32:54 +01:00
#[cfg(feature = "debug")]
CosmicElement::Egui(elem) => elem.id(),
}
}
2024-03-12 19:42:48 +01:00
fn current_commit(&self) -> CommitCounter {
2022-11-17 20:32:54 +01:00
match self {
CosmicElement::Workspace(elem) => elem.current_commit(),
CosmicElement::Cursor(elem) => elem.current_commit(),
2024-03-12 19:42:48 +01:00
CosmicElement::Dnd(elem) => elem.current_commit(),
2022-11-17 20:32:54 +01:00
CosmicElement::MoveGrab(elem) => elem.current_commit(),
2024-03-12 19:42:48 +01:00
CosmicElement::AdditionalDamage(elem) => elem.current_commit(),
2022-11-17 20:32:54 +01:00
#[cfg(feature = "debug")]
CosmicElement::Egui(elem) => elem.current_commit(),
}
}
fn src(&self) -> Rectangle<f64, smithay::utils::Buffer> {
match self {
CosmicElement::Workspace(elem) => elem.src(),
CosmicElement::Cursor(elem) => elem.src(),
2024-03-12 19:42:48 +01:00
CosmicElement::Dnd(elem) => elem.src(),
2022-11-17 20:32:54 +01:00
CosmicElement::MoveGrab(elem) => elem.src(),
2024-03-12 19:42:48 +01:00
CosmicElement::AdditionalDamage(elem) => elem.src(),
2022-11-17 20:32:54 +01:00
#[cfg(feature = "debug")]
CosmicElement::Egui(elem) => elem.src(),
}
}
fn geometry(&self, scale: Scale<f64>) -> Rectangle<i32, Physical> {
match self {
CosmicElement::Workspace(elem) => elem.geometry(scale),
CosmicElement::Cursor(elem) => elem.geometry(scale),
2024-03-12 19:42:48 +01:00
CosmicElement::Dnd(elem) => elem.geometry(scale),
2022-11-17 20:32:54 +01:00
CosmicElement::MoveGrab(elem) => elem.geometry(scale),
2024-03-12 19:42:48 +01:00
CosmicElement::AdditionalDamage(elem) => elem.geometry(scale),
2022-11-17 20:32:54 +01:00
#[cfg(feature = "debug")]
CosmicElement::Egui(elem) => elem.geometry(scale),
}
}
fn location(&self, scale: Scale<f64>) -> Point<i32, Physical> {
match self {
CosmicElement::Workspace(elem) => elem.location(scale),
CosmicElement::Cursor(elem) => elem.location(scale),
2024-03-12 19:42:48 +01:00
CosmicElement::Dnd(elem) => elem.location(scale),
2022-11-17 20:32:54 +01:00
CosmicElement::MoveGrab(elem) => elem.location(scale),
2024-03-12 19:42:48 +01:00
CosmicElement::AdditionalDamage(elem) => elem.location(scale),
2022-11-17 20:32:54 +01:00
#[cfg(feature = "debug")]
CosmicElement::Egui(elem) => elem.location(scale),
}
}
fn transform(&self) -> smithay::utils::Transform {
match self {
CosmicElement::Workspace(elem) => elem.transform(),
CosmicElement::Cursor(elem) => elem.transform(),
2024-03-12 19:42:48 +01:00
CosmicElement::Dnd(elem) => elem.transform(),
2022-11-17 20:32:54 +01:00
CosmicElement::MoveGrab(elem) => elem.transform(),
2024-03-12 19:42:48 +01:00
CosmicElement::AdditionalDamage(elem) => elem.transform(),
2022-11-17 20:32:54 +01:00
#[cfg(feature = "debug")]
CosmicElement::Egui(elem) => elem.transform(),
}
}
fn damage_since(
&self,
scale: Scale<f64>,
2024-03-12 19:42:48 +01:00
commit: Option<CommitCounter>,
2024-04-08 16:55:41 -07:00
) -> DamageSet<i32, Physical> {
2022-11-17 20:32:54 +01:00
match self {
CosmicElement::Workspace(elem) => elem.damage_since(scale, commit),
CosmicElement::Cursor(elem) => elem.damage_since(scale, commit),
2024-03-12 19:42:48 +01:00
CosmicElement::Dnd(elem) => elem.damage_since(scale, commit),
2022-11-17 20:32:54 +01:00
CosmicElement::MoveGrab(elem) => elem.damage_since(scale, commit),
2024-03-12 19:42:48 +01:00
CosmicElement::AdditionalDamage(elem) => elem.damage_since(scale, commit),
2022-11-17 20:32:54 +01:00
#[cfg(feature = "debug")]
CosmicElement::Egui(elem) => elem.damage_since(scale, commit),
}
}
fn opaque_regions(&self, scale: Scale<f64>) -> Vec<Rectangle<i32, Physical>> {
match self {
CosmicElement::Workspace(elem) => elem.opaque_regions(scale),
CosmicElement::Cursor(elem) => elem.opaque_regions(scale),
2024-03-12 19:42:48 +01:00
CosmicElement::Dnd(elem) => elem.opaque_regions(scale),
2022-11-17 20:32:54 +01:00
CosmicElement::MoveGrab(elem) => elem.opaque_regions(scale),
2024-03-12 19:42:48 +01:00
CosmicElement::AdditionalDamage(elem) => elem.opaque_regions(scale),
2022-11-17 20:32:54 +01:00
#[cfg(feature = "debug")]
CosmicElement::Egui(elem) => elem.opaque_regions(scale),
}
}
2023-05-12 20:01:37 +02:00
fn alpha(&self) -> f32 {
match self {
CosmicElement::Workspace(elem) => elem.alpha(),
CosmicElement::Cursor(elem) => elem.alpha(),
2024-03-12 19:42:48 +01:00
CosmicElement::Dnd(elem) => elem.alpha(),
2023-05-12 20:01:37 +02:00
CosmicElement::MoveGrab(elem) => elem.alpha(),
2024-03-12 19:42:48 +01:00
CosmicElement::AdditionalDamage(elem) => elem.alpha(),
2023-05-12 20:01:37 +02:00
#[cfg(feature = "debug")]
CosmicElement::Egui(elem) => elem.alpha(),
}
}
2022-11-17 20:32:54 +01:00
}
impl RenderElement<GlowRenderer> for CosmicElement<GlowRenderer> {
fn draw<'frame>(
2022-11-17 20:32:54 +01:00
&self,
frame: &mut <GlowRenderer as Renderer>::Frame<'frame>,
2022-12-27 18:27:29 +01:00
src: Rectangle<f64, BufferCoords>,
dst: Rectangle<i32, Physical>,
2022-11-17 20:32:54 +01:00
damage: &[Rectangle<i32, Physical>],
) -> Result<(), <GlowRenderer as Renderer>::Error> {
match self {
CosmicElement::Workspace(elem) => elem.draw(frame, src, dst, damage),
CosmicElement::Cursor(elem) => elem.draw(frame, src, dst, damage),
2024-03-12 19:42:48 +01:00
CosmicElement::Dnd(elem) => elem.draw(frame, src, dst, damage),
CosmicElement::MoveGrab(elem) => elem.draw(frame, src, dst, damage),
2024-03-12 19:42:48 +01:00
CosmicElement::AdditionalDamage(elem) => {
RenderElement::<GlowRenderer>::draw(elem, frame, src, dst, damage)
}
2022-11-17 20:32:54 +01:00
#[cfg(feature = "debug")]
CosmicElement::Egui(elem) => {
RenderElement::<GlowRenderer>::draw(elem, frame, src, dst, damage)
}
2022-11-17 20:32:54 +01:00
}
}
fn underlying_storage(&self, renderer: &mut GlowRenderer) -> Option<UnderlyingStorage> {
2022-11-17 20:32:54 +01:00
match self {
CosmicElement::Workspace(elem) => elem.underlying_storage(renderer),
CosmicElement::Cursor(elem) => elem.underlying_storage(renderer),
2024-03-12 19:42:48 +01:00
CosmicElement::Dnd(elem) => elem.underlying_storage(renderer),
2022-11-17 20:32:54 +01:00
CosmicElement::MoveGrab(elem) => elem.underlying_storage(renderer),
2024-03-12 19:42:48 +01:00
CosmicElement::AdditionalDamage(elem) => elem.underlying_storage(renderer),
2022-11-17 20:32:54 +01:00
#[cfg(feature = "debug")]
CosmicElement::Egui(elem) => elem.underlying_storage(renderer),
}
}
}
2024-02-07 12:33:32 +01:00
impl<'a> RenderElement<GlMultiRenderer<'a>> for CosmicElement<GlMultiRenderer<'a>> {
fn draw<'frame>(
2022-11-17 20:32:54 +01:00
&self,
2024-02-07 12:33:32 +01:00
frame: &mut GlMultiFrame<'a, 'frame>,
2022-12-27 18:27:29 +01:00
src: Rectangle<f64, BufferCoords>,
dst: Rectangle<i32, Physical>,
2022-11-17 20:32:54 +01:00
damage: &[Rectangle<i32, Physical>],
) -> Result<(), GlMultiError> {
2022-11-17 20:32:54 +01:00
match self {
CosmicElement::Workspace(elem) => elem.draw(frame, src, dst, damage),
CosmicElement::Cursor(elem) => elem.draw(frame, src, dst, damage),
2024-03-12 19:42:48 +01:00
CosmicElement::Dnd(elem) => elem.draw(frame, src, dst, damage),
CosmicElement::MoveGrab(elem) => elem.draw(frame, src, dst, damage),
2024-03-12 19:42:48 +01:00
CosmicElement::AdditionalDamage(elem) => {
RenderElement::<GlMultiRenderer<'a>>::draw(elem, frame, src, dst, damage)
}
2022-11-17 20:32:54 +01:00
#[cfg(feature = "debug")]
CosmicElement::Egui(elem) => {
let elem = {
let glow_frame = frame.glow_frame_mut();
RenderElement::<GlowRenderer>::draw(elem, glow_frame, src, dst, damage)
.map_err(|err| GlMultiError::Render(err))
};
elem
2022-11-17 20:32:54 +01:00
}
}
}
2024-02-07 12:33:32 +01:00
fn underlying_storage(&self, renderer: &mut GlMultiRenderer<'a>) -> Option<UnderlyingStorage> {
2022-11-17 20:32:54 +01:00
match self {
CosmicElement::Workspace(elem) => elem.underlying_storage(renderer),
CosmicElement::Cursor(elem) => elem.underlying_storage(renderer),
2024-03-12 19:42:48 +01:00
CosmicElement::Dnd(elem) => elem.underlying_storage(renderer),
2022-11-17 20:32:54 +01:00
CosmicElement::MoveGrab(elem) => elem.underlying_storage(renderer),
2024-03-12 19:42:48 +01:00
CosmicElement::AdditionalDamage(elem) => elem.underlying_storage(renderer),
2022-11-17 20:32:54 +01:00
#[cfg(feature = "debug")]
CosmicElement::Egui(elem) => {
let glow_renderer = renderer.glow_renderer_mut();
2022-11-17 20:32:54 +01:00
match elem.underlying_storage(glow_renderer) {
Some(UnderlyingStorage::Wayland(buffer)) => {
Some(UnderlyingStorage::Wayland(buffer))
}
_ => None,
}
}
}
}
}
impl<R> From<WorkspaceRenderElement<R>> for CosmicElement<R>
where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
2022-11-17 20:32:54 +01:00
<R as Renderer>::TextureId: 'static,
CosmicMappedRenderElement<R>: RenderElement<R>,
2022-11-17 20:32:54 +01:00
{
fn from(elem: WorkspaceRenderElement<R>) -> Self {
Self::Workspace(RelocateRenderElement::from_element(
elem,
(0, 0),
Relocate::Relative,
))
2022-11-17 20:32:54 +01:00
}
}
2024-03-12 19:42:48 +01:00
impl<R> From<CosmicMappedRenderElement<R>> for CosmicElement<R>
2022-11-17 20:32:54 +01:00
where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
2022-11-17 20:32:54 +01:00
<R as Renderer>::TextureId: 'static,
CosmicMappedRenderElement<R>: RenderElement<R>,
2022-11-17 20:32:54 +01:00
{
2024-03-12 19:42:48 +01:00
fn from(elem: CosmicMappedRenderElement<R>) -> Self {
Self::MoveGrab(elem)
2022-11-17 20:32:54 +01:00
}
}
2024-03-12 19:42:48 +01:00
impl<R> From<DamageElement> for CosmicElement<R>
2022-11-17 20:32:54 +01:00
where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
2022-11-17 20:32:54 +01:00
<R as Renderer>::TextureId: 'static,
CosmicMappedRenderElement<R>: RenderElement<R>,
2022-11-17 20:32:54 +01:00
{
2024-03-12 19:42:48 +01:00
fn from(elem: DamageElement) -> Self {
Self::AdditionalDamage(elem)
2022-11-17 20:32:54 +01:00
}
}
#[cfg(feature = "debug")]
2023-05-03 19:47:48 +02:00
impl<R> From<TextureRenderElement<GlesTexture>> for CosmicElement<R>
2022-11-17 20:32:54 +01:00
where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
2022-11-17 20:32:54 +01:00
<R as Renderer>::TextureId: 'static,
CosmicMappedRenderElement<R>: RenderElement<R>,
2022-11-17 20:32:54 +01:00
{
2023-05-03 19:47:48 +02:00
fn from(elem: TextureRenderElement<GlesTexture>) -> Self {
2022-11-17 20:32:54 +01:00
Self::Egui(elem)
}
}
pub trait AsGlowRenderer
where
Self: Renderer,
{
fn glow_renderer(&self) -> &GlowRenderer;
fn glow_renderer_mut(&mut self) -> &mut GlowRenderer;
}
impl AsGlowRenderer for GlowRenderer {
fn glow_renderer(&self) -> &GlowRenderer {
self
}
fn glow_renderer_mut(&mut self) -> &mut GlowRenderer {
self
}
}
2024-02-07 12:33:32 +01:00
impl<'a> AsGlowRenderer for GlMultiRenderer<'a> {
2022-11-17 20:32:54 +01:00
fn glow_renderer(&self) -> &GlowRenderer {
self.as_ref()
}
fn glow_renderer_mut(&mut self) -> &mut GlowRenderer {
self.as_mut()
}
}
pub trait AsGlowFrame<'a>
2022-11-17 20:32:54 +01:00
where
Self: Frame,
{
fn glow_frame(&self) -> &GlowFrame<'a>;
fn glow_frame_mut(&mut self) -> &mut GlowFrame<'a>;
2022-11-17 20:32:54 +01:00
}
impl<'frame> AsGlowFrame<'frame> for GlowFrame<'frame> {
fn glow_frame(&self) -> &GlowFrame<'frame> {
2022-11-17 20:32:54 +01:00
self
}
fn glow_frame_mut(&mut self) -> &mut GlowFrame<'frame> {
2022-11-17 20:32:54 +01:00
self
}
}
2024-02-07 12:33:32 +01:00
impl<'renderer, 'frame> AsGlowFrame<'frame> for GlMultiFrame<'renderer, 'frame> {
fn glow_frame(&self) -> &GlowFrame<'frame> {
2022-11-17 20:32:54 +01:00
self.as_ref()
}
fn glow_frame_mut(&mut self) -> &mut GlowFrame<'frame> {
2022-11-17 20:32:54 +01:00
self.as_mut()
}
}
2024-03-12 19:42:48 +01:00
pub struct DamageElement {
id: Id,
geometry: Rectangle<i32, Logical>,
}
impl DamageElement {
pub fn new(geometry: Rectangle<i32, Logical>) -> DamageElement {
DamageElement {
id: Id::new(),
geometry,
}
}
}
impl Element for DamageElement {
fn id(&self) -> &Id {
&self.id
}
fn current_commit(&self) -> CommitCounter {
CommitCounter::default()
}
fn src(&self) -> Rectangle<f64, BufferCoords> {
Rectangle::from_loc_and_size((0.0, 0.0), (1.0, 1.0))
}
fn geometry(&self, scale: Scale<f64>) -> Rectangle<i32, Physical> {
self.geometry.to_f64().to_physical(scale).to_i32_round()
}
fn damage_since(
&self,
scale: Scale<f64>,
_commit: Option<CommitCounter>,
2024-04-08 16:55:41 -07:00
) -> DamageSet<i32, Physical> {
DamageSet::from_slice(&[Rectangle::from_loc_and_size(
2024-03-12 19:42:48 +01:00
(0, 0),
self.geometry(scale).size,
2024-04-08 16:55:41 -07:00
)])
2024-03-12 19:42:48 +01:00
}
}
impl<R: Renderer> RenderElement<R> for DamageElement {
fn draw(
&self,
_frame: &mut <R as Renderer>::Frame<'_>,
_src: Rectangle<f64, BufferCoords>,
_dst: Rectangle<i32, Physical>,
_damage: &[Rectangle<i32, Physical>],
) -> Result<(), <R as Renderer>::Error> {
Ok(())
}
}