From 8e41568ffd31bb1bdade7f8dd31f893e6539003b Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Sun, 9 Jun 2024 11:56:51 +0300 Subject: Add SolidColor{Buffer,RenderElement} --- src/render_helpers/mod.rs | 1 + src/render_helpers/solid_color.rs | 168 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 169 insertions(+) create mode 100644 src/render_helpers/solid_color.rs (limited to 'src/render_helpers') diff --git a/src/render_helpers/mod.rs b/src/render_helpers/mod.rs index db78fbe3..c1c1fea9 100644 --- a/src/render_helpers/mod.rs +++ b/src/render_helpers/mod.rs @@ -31,6 +31,7 @@ pub mod resources; pub mod shader_element; pub mod shaders; pub mod snapshot; +pub mod solid_color; pub mod surface; pub mod texture; diff --git a/src/render_helpers/solid_color.rs b/src/render_helpers/solid_color.rs new file mode 100644 index 00000000..ebc06688 --- /dev/null +++ b/src/render_helpers/solid_color.rs @@ -0,0 +1,168 @@ +use smithay::backend::renderer::element::{Element, Id, Kind, RenderElement, UnderlyingStorage}; +use smithay::backend::renderer::utils::{CommitCounter, OpaqueRegions}; +use smithay::backend::renderer::{Frame as _, Renderer}; +use smithay::utils::{Buffer, Logical, Physical, Point, Rectangle, Scale, Size}; + +/// Smithay's solid color buffer, but with fractional scale. +#[derive(Debug, Clone)] +pub struct SolidColorBuffer { + id: Id, + size: Size, + commit: CommitCounter, + color: [f32; 4], +} + +/// Render element for a [`SolidColorBuffer`]. +#[derive(Debug, Clone)] +pub struct SolidColorRenderElement { + id: Id, + geometry: Rectangle, + commit: CommitCounter, + color: [f32; 4], + kind: Kind, +} + +impl Default for SolidColorBuffer { + fn default() -> Self { + Self { + id: Id::new(), + size: Default::default(), + commit: Default::default(), + color: Default::default(), + } + } +} + +impl SolidColorBuffer { + pub fn new(size: impl Into>, color: [f32; 4]) -> Self { + SolidColorBuffer { + id: Id::new(), + color, + commit: CommitCounter::default(), + size: size.into(), + } + } + + pub fn resize(&mut self, size: impl Into>) { + let size = size.into(); + if size != self.size { + self.size = size; + self.commit.increment(); + } + } + + pub fn set_color(&mut self, color: [f32; 4]) { + if color != self.color { + self.color = color; + self.commit.increment(); + } + } + + pub fn update(&mut self, size: impl Into>, color: [f32; 4]) { + let size = size.into(); + if size != self.size || color != self.color { + self.size = size; + self.color = color; + self.commit.increment(); + } + } + + pub fn color(&self) -> [f32; 4] { + self.color + } + + pub fn size(&self) -> Size { + self.size + } +} + +impl SolidColorRenderElement { + pub fn from_buffer( + buffer: &SolidColorBuffer, + location: impl Into>, + alpha: f32, + kind: Kind, + ) -> Self { + let geo = Rectangle::from_loc_and_size(location, buffer.size()); + let color = [ + buffer.color[0] * alpha, + buffer.color[1] * alpha, + buffer.color[2] * alpha, + buffer.color[3] * alpha, + ]; + Self::new(buffer.id.clone(), geo, buffer.commit, color, kind) + } + + pub fn new( + id: Id, + geometry: Rectangle, + commit: CommitCounter, + color: [f32; 4], + kind: Kind, + ) -> Self { + SolidColorRenderElement { + id, + geometry, + commit, + color, + kind, + } + } + + pub fn color(&self) -> [f32; 4] { + self.color + } +} + +impl Element for SolidColorRenderElement { + fn id(&self) -> &Id { + &self.id + } + + fn current_commit(&self) -> CommitCounter { + self.commit + } + + fn src(&self) -> Rectangle { + Rectangle::from_loc_and_size((0., 0.), (1., 1.)) + } + + fn geometry(&self, scale: Scale) -> Rectangle { + self.geometry.to_physical_precise_round(scale) + } + + fn opaque_regions(&self, scale: Scale) -> OpaqueRegions { + if self.color[3] == 1f32 { + let rect = Rectangle::from_loc_and_size((0., 0.), self.geometry.size) + .to_physical_precise_down(scale); + OpaqueRegions::from_slice(&[rect]) + } else { + OpaqueRegions::default() + } + } + + fn alpha(&self) -> f32 { + 1.0 + } + + fn kind(&self) -> Kind { + self.kind + } +} + +impl RenderElement for SolidColorRenderElement { + fn draw( + &self, + frame: &mut ::Frame<'_>, + _src: Rectangle, + dst: Rectangle, + damage: &[Rectangle], + ) -> Result<(), ::Error> { + frame.draw_solid(dst, damage, self.color) + } + + #[inline] + fn underlying_storage(&self, _renderer: &mut R) -> Option> { + None + } +} -- cgit