aboutsummaryrefslogtreecommitdiff
path: root/src/render_helpers
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2024-06-17 09:16:28 +0300
committerIvan Molodetskikh <yalterz@gmail.com>2024-06-18 14:01:28 +0300
commit1dae45c58d7eabeda21ef490d712915890bf6cff (patch)
tree62c473ab1662a1161ed522517ea57b7bd8db340c /src/render_helpers
parent997119c44338ad96a40b4a1d6e958f77062a37ef (diff)
downloadniri-1dae45c58d7eabeda21ef490d712915890bf6cff.tar.gz
niri-1dae45c58d7eabeda21ef490d712915890bf6cff.tar.bz2
niri-1dae45c58d7eabeda21ef490d712915890bf6cff.zip
Refactor layout to fractional-logical
Lets borders, gaps, and everything else stay pixel-perfect even with fractional scale. Allows setting fractional border widths, gaps, struts. See the new wiki .md for more details.
Diffstat (limited to 'src/render_helpers')
-rw-r--r--src/render_helpers/border.rs20
-rw-r--r--src/render_helpers/clipped_surface.rs16
-rw-r--r--src/render_helpers/damage.rs8
-rw-r--r--src/render_helpers/mod.rs24
-rw-r--r--src/render_helpers/resize.rs16
-rw-r--r--src/render_helpers/shader_element.rs18
-rw-r--r--src/render_helpers/snapshot.rs6
-rw-r--r--src/render_helpers/surface.rs6
8 files changed, 53 insertions, 61 deletions
diff --git a/src/render_helpers/border.rs b/src/render_helpers/border.rs
index 8e7d4b16..5a3d4e1b 100644
--- a/src/render_helpers/border.rs
+++ b/src/render_helpers/border.rs
@@ -26,12 +26,12 @@ pub struct BorderRenderElement {
#[derive(Debug, Clone, Copy, PartialEq)]
struct Parameters {
- size: Size<i32, Logical>,
- gradient_area: Rectangle<i32, Logical>,
+ size: Size<f64, Logical>,
+ gradient_area: Rectangle<f64, Logical>,
color_from: [f32; 4],
color_to: [f32; 4],
angle: f32,
- geometry: Rectangle<i32, Logical>,
+ geometry: Rectangle<f64, Logical>,
border_width: f32,
corner_radius: CornerRadius,
}
@@ -39,12 +39,12 @@ struct Parameters {
impl BorderRenderElement {
#[allow(clippy::too_many_arguments)]
pub fn new(
- size: Size<i32, Logical>,
- gradient_area: Rectangle<i32, Logical>,
+ size: Size<f64, Logical>,
+ gradient_area: Rectangle<f64, Logical>,
color_from: [f32; 4],
color_to: [f32; 4],
angle: f32,
- geometry: Rectangle<i32, Logical>,
+ geometry: Rectangle<f64, Logical>,
border_width: f32,
corner_radius: CornerRadius,
) -> Self {
@@ -90,12 +90,12 @@ impl BorderRenderElement {
#[allow(clippy::too_many_arguments)]
pub fn update(
&mut self,
- size: Size<i32, Logical>,
- gradient_area: Rectangle<i32, Logical>,
+ size: Size<f64, Logical>,
+ gradient_area: Rectangle<f64, Logical>,
color_from: [f32; 4],
color_to: [f32; 4],
angle: f32,
- geometry: Rectangle<i32, Logical>,
+ geometry: Rectangle<f64, Logical>,
border_width: f32,
corner_radius: CornerRadius,
) {
@@ -172,7 +172,7 @@ impl BorderRenderElement {
);
}
- pub fn with_location(mut self, location: Point<i32, Logical>) -> Self {
+ pub fn with_location(mut self, location: Point<f64, Logical>) -> Self {
self.inner = self.inner.with_location(location);
self
}
diff --git a/src/render_helpers/clipped_surface.rs b/src/render_helpers/clipped_surface.rs
index 7d52e410..8e5259ed 100644
--- a/src/render_helpers/clipped_surface.rs
+++ b/src/render_helpers/clipped_surface.rs
@@ -18,7 +18,7 @@ pub struct ClippedSurfaceRenderElement<R: NiriRenderer> {
inner: WaylandSurfaceRenderElement<R>,
program: GlesTexProgram,
corner_radius: CornerRadius,
- geometry: Rectangle<i32, Logical>,
+ geometry: Rectangle<f64, Logical>,
input_to_geo: Mat3,
}
@@ -32,7 +32,7 @@ impl<R: NiriRenderer> ClippedSurfaceRenderElement<R> {
pub fn new(
elem: WaylandSurfaceRenderElement<R>,
scale: Scale<f64>,
- geometry: Rectangle<i32, Logical>,
+ geometry: Rectangle<f64, Logical>,
program: GlesTexProgram,
corner_radius: CornerRadius,
) -> Self {
@@ -86,7 +86,7 @@ impl<R: NiriRenderer> ClippedSurfaceRenderElement<R> {
pub fn will_clip(
elem: &WaylandSurfaceRenderElement<R>,
scale: Scale<f64>,
- geometry: Rectangle<i32, Logical>,
+ geometry: Rectangle<f64, Logical>,
corner_radius: CornerRadius,
) -> bool {
let elem_geo = elem.geometry(scale);
@@ -95,10 +95,10 @@ impl<R: NiriRenderer> ClippedSurfaceRenderElement<R> {
if corner_radius == CornerRadius::default() {
!geo.contains_rect(elem_geo)
} else {
- let corners = Self::rounded_corners(geometry.to_f64(), corner_radius);
+ let corners = Self::rounded_corners(geometry, corner_radius);
let corners = corners
.into_iter()
- .map(|rect| rect.to_physical_precise_round(scale));
+ .map(|rect| rect.to_physical_precise_up(scale));
let geo = Rectangle::subtract_rects_many([geo], corners);
!Rectangle::subtract_rects_many([elem_geo], geo).is_empty()
}
@@ -186,11 +186,11 @@ impl<R: NiriRenderer> Element for ClippedSurfaceRenderElement<R> {
if self.corner_radius == CornerRadius::default() {
regions.collect()
} else {
- let corners = Self::rounded_corners(self.geometry.to_f64(), self.corner_radius);
+ let corners = Self::rounded_corners(self.geometry, self.corner_radius);
let elem_loc = self.geometry(scale).loc;
let corners = corners.into_iter().map(|rect| {
- let mut rect = rect.to_physical_precise_round(scale);
+ let mut rect = rect.to_physical_precise_up(scale);
rect.loc -= elem_loc;
rect
});
@@ -278,7 +278,7 @@ impl<'render> RenderElement<TtyRenderer<'render>>
}
impl RoundedCornerDamage {
- pub fn set_size(&mut self, size: Size<i32, Logical>) {
+ pub fn set_size(&mut self, size: Size<f64, Logical>) {
self.damage.set_size(size);
}
diff --git a/src/render_helpers/damage.rs b/src/render_helpers/damage.rs
index f8cd8c2d..e05ee649 100644
--- a/src/render_helpers/damage.rs
+++ b/src/render_helpers/damage.rs
@@ -7,7 +7,7 @@ use smithay::utils::{Buffer, Logical, Physical, Point, Rectangle, Scale, Size};
pub struct ExtraDamage {
id: Id,
commit: CommitCounter,
- geometry: Rectangle<i32, Logical>,
+ geometry: Rectangle<f64, Logical>,
}
impl ExtraDamage {
@@ -19,7 +19,7 @@ impl ExtraDamage {
}
}
- pub fn set_size(&mut self, size: Size<i32, Logical>) {
+ pub fn set_size(&mut self, size: Size<f64, Logical>) {
if self.geometry.size == size {
return;
}
@@ -32,7 +32,7 @@ impl ExtraDamage {
self.commit.increment();
}
- pub fn with_location(mut self, location: Point<i32, Logical>) -> Self {
+ pub fn with_location(mut self, location: Point<f64, Logical>) -> Self {
self.geometry.loc = location;
self
}
@@ -58,7 +58,7 @@ impl Element for ExtraDamage {
}
fn geometry(&self, scale: Scale<f64>) -> Rectangle<i32, Physical> {
- self.geometry.to_physical_precise_round(scale)
+ self.geometry.to_physical_precise_up(scale)
}
}
diff --git a/src/render_helpers/mod.rs b/src/render_helpers/mod.rs
index 2eb1d6df..12ebd024 100644
--- a/src/render_helpers/mod.rs
+++ b/src/render_helpers/mod.rs
@@ -3,7 +3,6 @@ use std::ptr;
use anyhow::{ensure, Context};
use niri_config::BlockOutFrom;
use smithay::backend::allocator::Fourcc;
-use smithay::backend::renderer::element::solid::{SolidColorBuffer, SolidColorRenderElement};
use smithay::backend::renderer::element::utils::{Relocate, RelocateRenderElement};
use smithay::backend::renderer::element::{Kind, RenderElement};
use smithay::backend::renderer::gles::{GlesMapping, GlesRenderer, GlesTexture};
@@ -13,6 +12,7 @@ use smithay::reexports::wayland_server::protocol::wl_buffer::WlBuffer;
use smithay::reexports::wayland_server::protocol::wl_shm;
use smithay::utils::{Logical, Physical, Point, Rectangle, Scale, Size, Transform};
use smithay::wayland::shm;
+use solid_color::{SolidColorBuffer, SolidColorRenderElement};
use self::primary_gpu_texture::PrimaryGpuTextureRenderElement;
use self::texture::{TextureBuffer, TextureRenderElement};
@@ -50,7 +50,7 @@ pub enum RenderTarget {
#[derive(Debug)]
pub struct BakedBuffer<B> {
pub buffer: B,
- pub location: Point<i32, Logical>,
+ pub location: Point<f64, Logical>,
pub src: Option<Rectangle<f64, Logical>>,
pub dst: Option<Size<i32, Logical>>,
}
@@ -67,7 +67,7 @@ pub trait ToRenderElement {
fn to_render_element(
&self,
- location: Point<i32, Logical>,
+ location: Point<f64, Logical>,
scale: Scale<f64>,
alpha: f32,
kind: Kind,
@@ -119,14 +119,14 @@ impl ToRenderElement for BakedBuffer<TextureBuffer<GlesTexture>> {
fn to_render_element(
&self,
- location: Point<i32, Logical>,
+ location: Point<f64, Logical>,
_scale: Scale<f64>,
alpha: f32,
kind: Kind,
) -> Self::RenderElement {
let elem = TextureRenderElement::from_texture_buffer(
self.buffer.clone(),
- (location + self.location).to_f64(),
+ location + self.location,
alpha,
self.src,
self.dst.map(|dst| dst.to_f64()),
@@ -141,20 +141,12 @@ impl ToRenderElement for BakedBuffer<SolidColorBuffer> {
fn to_render_element(
&self,
- location: Point<i32, Logical>,
- scale: Scale<f64>,
+ location: Point<f64, Logical>,
+ _scale: Scale<f64>,
alpha: f32,
kind: Kind,
) -> Self::RenderElement {
- SolidColorRenderElement::from_buffer(
- &self.buffer,
- (location + self.location)
- .to_physical_precise_round(scale)
- .to_i32_round(),
- scale,
- alpha,
- kind,
- )
+ SolidColorRenderElement::from_buffer(&self.buffer, location + self.location, alpha, kind)
}
}
diff --git a/src/render_helpers/resize.rs b/src/render_helpers/resize.rs
index b0fdda92..4361938d 100644
--- a/src/render_helpers/resize.rs
+++ b/src/render_helpers/resize.rs
@@ -18,12 +18,12 @@ pub struct ResizeRenderElement(ShaderRenderElement);
impl ResizeRenderElement {
#[allow(clippy::too_many_arguments)]
pub fn new(
- area: Rectangle<i32, Logical>,
+ area: Rectangle<f64, Logical>,
scale: Scale<f64>,
texture_prev: (GlesTexture, Rectangle<i32, Physical>),
- size_prev: Size<i32, Logical>,
+ size_prev: Size<f64, Logical>,
texture_next: (GlesTexture, Rectangle<i32, Physical>),
- size_next: Size<i32, Logical>,
+ size_next: Size<f64, Logical>,
progress: f32,
clamped_progress: f32,
corner_radius: CornerRadius,
@@ -35,17 +35,17 @@ impl ResizeRenderElement {
let (texture_prev, tex_prev_geo) = texture_prev;
let (texture_next, tex_next_geo) = texture_next;
- let scale_prev = area.size.to_f64() / size_prev.to_f64();
- let scale_next = area.size.to_f64() / size_next.to_f64();
+ let scale_prev = area.size / size_prev;
+ let scale_next = area.size / size_next;
// Compute the area necessary to fit a crossfade.
let tex_prev_geo_scaled = tex_prev_geo.to_f64().upscale(scale_prev);
let tex_next_geo_scaled = tex_next_geo.to_f64().upscale(scale_next);
- let combined_geo = tex_prev_geo_scaled.merge(tex_next_geo_scaled);
+ let combined_geo = tex_prev_geo_scaled.merge(tex_next_geo_scaled).to_i32_up();
let area = Rectangle::from_loc_and_size(
- area.loc + combined_geo.loc.to_logical(scale).to_i32_round(),
- combined_geo.size.to_logical(scale).to_i32_round(),
+ area.loc + combined_geo.loc.to_logical(scale),
+ combined_geo.size.to_logical(scale),
);
// Convert Smithay types into glam types.
diff --git a/src/render_helpers/shader_element.rs b/src/render_helpers/shader_element.rs
index a432ca34..ebd9b1ec 100644
--- a/src/render_helpers/shader_element.rs
+++ b/src/render_helpers/shader_element.rs
@@ -23,8 +23,8 @@ pub struct ShaderRenderElement {
program: ProgramType,
id: Id,
commit_counter: CommitCounter,
- area: Rectangle<i32, Logical>,
- opaque_regions: Vec<Rectangle<i32, Logical>>,
+ area: Rectangle<f64, Logical>,
+ opaque_regions: Vec<Rectangle<f64, Logical>>,
alpha: f32,
additional_uniforms: Vec<Uniform<'static>>,
textures: HashMap<String, GlesTexture>,
@@ -198,8 +198,8 @@ impl ShaderRenderElement {
#[allow(clippy::too_many_arguments)]
pub fn new(
program: ProgramType,
- size: Size<i32, Logical>,
- opaque_regions: Option<Vec<Rectangle<i32, Logical>>>,
+ size: Size<f64, Logical>,
+ opaque_regions: Option<Vec<Rectangle<f64, Logical>>>,
alpha: f32,
uniforms: Vec<Uniform<'_>>,
textures: HashMap<String, GlesTexture>,
@@ -209,7 +209,7 @@ impl ShaderRenderElement {
program,
id: Id::new(),
commit_counter: CommitCounter::default(),
- area: Rectangle::from_loc_and_size((0, 0), size),
+ area: Rectangle::from_loc_and_size((0., 0.), size),
opaque_regions: opaque_regions.unwrap_or_default(),
alpha,
additional_uniforms: uniforms.into_iter().map(|u| u.into_owned()).collect(),
@@ -238,8 +238,8 @@ impl ShaderRenderElement {
pub fn update(
&mut self,
- size: Size<i32, Logical>,
- opaque_regions: Option<Vec<Rectangle<i32, Logical>>>,
+ size: Size<f64, Logical>,
+ opaque_regions: Option<Vec<Rectangle<f64, Logical>>>,
uniforms: Vec<Uniform<'_>>,
textures: HashMap<String, GlesTexture>,
) {
@@ -251,7 +251,7 @@ impl ShaderRenderElement {
self.commit_counter.increment();
}
- pub fn with_location(mut self, location: Point<i32, Logical>) -> Self {
+ pub fn with_location(mut self, location: Point<f64, Logical>) -> Self {
self.area.loc = location;
self
}
@@ -277,7 +277,7 @@ impl Element for ShaderRenderElement {
fn opaque_regions(&self, scale: Scale<f64>) -> OpaqueRegions<i32, Physical> {
self.opaque_regions
.iter()
- .map(|region| region.to_physical_precise_round(scale))
+ .map(|region| region.to_physical_precise_down(scale))
.collect()
}
diff --git a/src/render_helpers/snapshot.rs b/src/render_helpers/snapshot.rs
index 62416c43..e0506829 100644
--- a/src/render_helpers/snapshot.rs
+++ b/src/render_helpers/snapshot.rs
@@ -25,7 +25,7 @@ pub struct RenderSnapshot<C, B> {
pub block_out_from: Option<BlockOutFrom>,
/// Visual size of the element at the point of the snapshot.
- pub size: Size<i32, Logical>,
+ pub size: Size<f64, Logical>,
/// Contents rendered into a texture (lazily).
pub texture: OnceCell<Option<(GlesTexture, Rectangle<i32, Physical>)>>,
@@ -55,7 +55,7 @@ where
.blocked_out_contents
.iter()
.map(|baked| {
- baked.to_render_element(Point::from((0, 0)), scale, 1., Kind::Unspecified)
+ baked.to_render_element(Point::from((0., 0.)), scale, 1., Kind::Unspecified)
})
.collect();
@@ -81,7 +81,7 @@ where
.contents
.iter()
.map(|baked| {
- baked.to_render_element(Point::from((0, 0)), scale, 1., Kind::Unspecified)
+ baked.to_render_element(Point::from((0., 0.)), scale, 1., Kind::Unspecified)
})
.collect();
diff --git a/src/render_helpers/surface.rs b/src/render_helpers/surface.rs
index 859be85f..93738673 100644
--- a/src/render_helpers/surface.rs
+++ b/src/render_helpers/surface.rs
@@ -12,7 +12,7 @@ use super::BakedBuffer;
pub fn render_snapshot_from_surface_tree(
renderer: &mut GlesRenderer,
surface: &WlSurface,
- location: Point<i32, Logical>,
+ location: Point<f64, Logical>,
storage: &mut Vec<BakedBuffer<TextureBuffer<GlesTexture>>>,
) {
let _span = tracy_client::span!("render_snapshot_from_surface_tree");
@@ -28,7 +28,7 @@ pub fn render_snapshot_from_surface_tree(
let data = &*data.borrow();
if let Some(view) = data.view() {
- location += view.offset;
+ location += view.offset.to_f64();
TraversalAction::DoChildren(location)
} else {
TraversalAction::SkipChildren
@@ -43,7 +43,7 @@ pub fn render_snapshot_from_surface_tree(
if let Some(data) = data {
if let Some(view) = data.borrow().view() {
- location += view.offset;
+ location += view.offset.to_f64();
} else {
return;
}