diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-06-09 11:56:51 +0300 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-06-10 18:08:01 +0300 |
| commit | 8e41568ffd31bb1bdade7f8dd31f893e6539003b (patch) | |
| tree | 45c510ee8b7fca41dede218206f4a0d629666f73 /src | |
| parent | dbe810d3d8086770fa27b1b78c615f2dccd72a11 (diff) | |
| download | niri-8e41568ffd31bb1bdade7f8dd31f893e6539003b.tar.gz niri-8e41568ffd31bb1bdade7f8dd31f893e6539003b.tar.bz2 niri-8e41568ffd31bb1bdade7f8dd31f893e6539003b.zip | |
Add SolidColor{Buffer,RenderElement}
Diffstat (limited to 'src')
| -rw-r--r-- | src/render_helpers/mod.rs | 1 | ||||
| -rw-r--r-- | src/render_helpers/solid_color.rs | 168 |
2 files changed, 169 insertions, 0 deletions
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<f64, Logical>, + commit: CommitCounter, + color: [f32; 4], +} + +/// Render element for a [`SolidColorBuffer`]. +#[derive(Debug, Clone)] +pub struct SolidColorRenderElement { + id: Id, + geometry: Rectangle<f64, Logical>, + 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<Size<f64, Logical>>, color: [f32; 4]) -> Self { + SolidColorBuffer { + id: Id::new(), + color, + commit: CommitCounter::default(), + size: size.into(), + } + } + + pub fn resize(&mut self, size: impl Into<Size<f64, Logical>>) { + 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<Size<f64, Logical>>, 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<f64, Logical> { + self.size + } +} + +impl SolidColorRenderElement { + pub fn from_buffer( + buffer: &SolidColorBuffer, + location: impl Into<Point<f64, Logical>>, + 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<f64, Logical>, + 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<f64, Buffer> { + Rectangle::from_loc_and_size((0., 0.), (1., 1.)) + } + + fn geometry(&self, scale: Scale<f64>) -> Rectangle<i32, Physical> { + self.geometry.to_physical_precise_round(scale) + } + + fn opaque_regions(&self, scale: Scale<f64>) -> OpaqueRegions<i32, Physical> { + 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<R: Renderer> RenderElement<R> for SolidColorRenderElement { + fn draw( + &self, + frame: &mut <R as Renderer>::Frame<'_>, + _src: Rectangle<f64, Buffer>, + dst: Rectangle<i32, Physical>, + damage: &[Rectangle<i32, Physical>], + ) -> Result<(), <R as Renderer>::Error> { + frame.draw_solid(dst, damage, self.color) + } + + #[inline] + fn underlying_storage(&self, _renderer: &mut R) -> Option<UnderlyingStorage<'_>> { + None + } +} |
