aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2024-06-09 11:56:51 +0300
committerIvan Molodetskikh <yalterz@gmail.com>2024-06-10 18:08:01 +0300
commit8e41568ffd31bb1bdade7f8dd31f893e6539003b (patch)
tree45c510ee8b7fca41dede218206f4a0d629666f73 /src
parentdbe810d3d8086770fa27b1b78c615f2dccd72a11 (diff)
downloadniri-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.rs1
-rw-r--r--src/render_helpers/solid_color.rs168
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
+ }
+}