Fix blurry rounded corners on high scales

This commit is contained in:
Ivan Molodetskikh 2024-06-18 12:19:23 +03:00
parent eb59b10050
commit 66202992c9
16 changed files with 49 additions and 3 deletions

View File

@ -70,6 +70,7 @@ impl TestCase for GradientAngle {
Rectangle::from_loc_and_size((0., 0.), area.size),
0.,
CornerRadius::default(),
1.,
)
.with_location(area.loc)]
.into_iter()

View File

@ -110,6 +110,7 @@ impl TestCase for GradientArea {
Rectangle::from_loc_and_size((0, 0), rect_size).to_f64(),
0.,
CornerRadius::default(),
1.,
)
.with_location(area.loc)]
.into_iter()

View File

@ -164,6 +164,7 @@ impl ClosingWindow {
ProgramType::Close,
view_rect.size,
None,
scale.x as f32,
1.,
vec![
mat3_uniform("niri_input_to_geo", input_to_geo),

View File

@ -184,6 +184,7 @@ impl FocusRing {
Rectangle::from_loc_and_size(full_rect.loc - loc, full_rect.size),
rounded_corner_border_width,
radius,
scale as f32,
);
}
} else {
@ -203,6 +204,7 @@ impl FocusRing {
Rectangle::from_loc_and_size(full_rect.loc - self.locations[0], full_rect.size),
rounded_corner_border_width,
radius,
scale as f32,
);
}

View File

@ -106,6 +106,7 @@ impl OpenAnimation {
ProgramType::Open,
area.size,
None,
scale.x as f32,
1.,
vec![
mat3_uniform("niri_input_to_geo", input_to_geo),

View File

@ -763,6 +763,7 @@ impl<W: LayoutElement> Tile<W> {
Rectangle::from_loc_and_size((0., 0.), geo.size),
0.,
radius,
scale.x as f32,
)
.with_location(geo.loc)
.into();

View File

@ -34,6 +34,8 @@ struct Parameters {
geometry: Rectangle<f64, Logical>,
border_width: f32,
corner_radius: CornerRadius,
// Should only be used for visual improvements, i.e. corner radius anti-aliasing.
scale: f32,
}
impl BorderRenderElement {
@ -47,6 +49,7 @@ impl BorderRenderElement {
geometry: Rectangle<f64, Logical>,
border_width: f32,
corner_radius: CornerRadius,
scale: f32,
) -> Self {
let inner = ShaderRenderElement::empty(ProgramType::Border, Kind::Unspecified);
let mut rv = Self {
@ -60,6 +63,7 @@ impl BorderRenderElement {
geometry,
border_width,
corner_radius,
scale,
},
};
rv.update_inner();
@ -79,6 +83,7 @@ impl BorderRenderElement {
geometry: Default::default(),
border_width: 0.,
corner_radius: Default::default(),
scale: 1.,
},
}
}
@ -98,6 +103,7 @@ impl BorderRenderElement {
geometry: Rectangle<f64, Logical>,
border_width: f32,
corner_radius: CornerRadius,
scale: f32,
) {
let params = Parameters {
size,
@ -108,6 +114,7 @@ impl BorderRenderElement {
geometry,
border_width,
corner_radius,
scale,
};
if self.params == params {
return;
@ -127,6 +134,7 @@ impl BorderRenderElement {
geometry,
border_width,
corner_radius,
scale,
} = self.params;
let grad_offset = geometry.loc - gradient_area.loc;
@ -157,6 +165,7 @@ impl BorderRenderElement {
self.inner.update(
size,
None,
scale,
vec![
Uniform::new("color_from", color_from),
Uniform::new("color_to", color_to),

View File

@ -20,6 +20,8 @@ pub struct ClippedSurfaceRenderElement<R: NiriRenderer> {
corner_radius: CornerRadius,
geometry: Rectangle<f64, Logical>,
input_to_geo: Mat3,
// Should only be used for visual improvements, i.e. corner radius anti-aliasing.
scale: f32,
}
#[derive(Debug, Default, Clone)]
@ -76,6 +78,7 @@ impl<R: NiriRenderer> ClippedSurfaceRenderElement<R> {
corner_radius,
geometry,
input_to_geo,
scale: scale.x as f32,
}
}
@ -220,6 +223,7 @@ impl RenderElement<GlesRenderer> for ClippedSurfaceRenderElement<GlesRenderer> {
frame.override_default_tex_program(
self.program.clone(),
vec![
Uniform::new("niri_scale", self.scale),
Uniform::new(
"geo_size",
(self.geometry.size.w as f32, self.geometry.size.h as f32),

View File

@ -87,6 +87,7 @@ impl ResizeRenderElement {
ProgramType::Resize,
area.size,
None,
scale.x,
result_alpha,
vec![
mat3_uniform("niri_input_to_curr_geo", input_to_curr_geo),

View File

@ -25,6 +25,8 @@ pub struct ShaderRenderElement {
commit_counter: CommitCounter,
area: Rectangle<f64, Logical>,
opaque_regions: Vec<Rectangle<f64, Logical>>,
// Should only be used for visual improvements, i.e. corner radius anti-aliasing.
scale: f32,
alpha: f32,
additional_uniforms: Vec<Uniform<'static>>,
textures: HashMap<String, GlesTexture>,
@ -47,6 +49,7 @@ struct ShaderProgramInternal {
uniform_tex_matrix: ffi::types::GLint,
uniform_matrix: ffi::types::GLint,
uniform_size: ffi::types::GLint,
uniform_scale: ffi::types::GLint,
uniform_alpha: ffi::types::GLint,
attrib_vert: ffi::types::GLint,
attrib_vert_position: ffi::types::GLint,
@ -78,6 +81,7 @@ unsafe fn compile_program(
let matrix = CStr::from_bytes_with_nul(b"matrix\0").expect("NULL terminated");
let tex_matrix = CStr::from_bytes_with_nul(b"tex_matrix\0").expect("NULL terminated");
let size = CStr::from_bytes_with_nul(b"niri_size\0").expect("NULL terminated");
let scale = CStr::from_bytes_with_nul(b"niri_scale\0").expect("NULL terminated");
let alpha = CStr::from_bytes_with_nul(b"niri_alpha\0").expect("NULL terminated");
let tint = CStr::from_bytes_with_nul(b"niri_tint\0").expect("NULL terminated");
@ -90,6 +94,8 @@ unsafe fn compile_program(
.GetUniformLocation(program, tex_matrix.as_ptr() as *const ffi::types::GLchar),
uniform_size: gl
.GetUniformLocation(program, size.as_ptr() as *const ffi::types::GLchar),
uniform_scale: gl
.GetUniformLocation(program, scale.as_ptr() as *const ffi::types::GLchar),
uniform_alpha: gl
.GetUniformLocation(program, alpha.as_ptr() as *const ffi::types::GLchar),
attrib_vert: gl.GetAttribLocation(program, vert.as_ptr() as *const ffi::types::GLchar),
@ -131,6 +137,8 @@ unsafe fn compile_program(
),
uniform_size: gl
.GetUniformLocation(debug_program, size.as_ptr() as *const ffi::types::GLchar),
uniform_scale: gl
.GetUniformLocation(debug_program, scale.as_ptr() as *const ffi::types::GLchar),
uniform_alpha: gl
.GetUniformLocation(debug_program, alpha.as_ptr() as *const ffi::types::GLchar),
attrib_vert: gl
@ -200,6 +208,8 @@ impl ShaderRenderElement {
program: ProgramType,
size: Size<f64, Logical>,
opaque_regions: Option<Vec<Rectangle<f64, Logical>>>,
// Should only be used for visual improvements, i.e. corner radius anti-aliasing.
scale: f32,
alpha: f32,
uniforms: Vec<Uniform<'_>>,
textures: HashMap<String, GlesTexture>,
@ -211,6 +221,7 @@ impl ShaderRenderElement {
commit_counter: CommitCounter::default(),
area: Rectangle::from_loc_and_size((0., 0.), size),
opaque_regions: opaque_regions.unwrap_or_default(),
scale,
alpha,
additional_uniforms: uniforms.into_iter().map(|u| u.into_owned()).collect(),
textures,
@ -225,6 +236,7 @@ impl ShaderRenderElement {
commit_counter: CommitCounter::default(),
area: Rectangle::default(),
opaque_regions: vec![],
scale: 1.,
alpha: 1.,
additional_uniforms: vec![],
textures: HashMap::new(),
@ -240,11 +252,13 @@ impl ShaderRenderElement {
&mut self,
size: Size<f64, Logical>,
opaque_regions: Option<Vec<Rectangle<f64, Logical>>>,
scale: f32,
uniforms: Vec<Uniform<'_>>,
textures: HashMap<String, GlesTexture>,
) {
self.area.size = size;
self.opaque_regions = opaque_regions.unwrap_or_default();
self.scale = scale;
self.additional_uniforms = uniforms.into_iter().map(|u| u.into_owned()).collect();
self.textures = textures;
@ -422,6 +436,7 @@ impl RenderElement<GlesRenderer> for ShaderRenderElement {
tex_matrix.as_ref().as_ptr(),
);
gl.Uniform2f(program.uniform_size, dest.size.w as f32, dest.size.h as f32);
gl.Uniform1f(program.uniform_scale, self.scale);
gl.Uniform1f(program.uniform_alpha, self.alpha);
let tint = if has_tint { 1.0f32 } else { 0.0f32 };

View File

@ -5,6 +5,7 @@ uniform float niri_tint;
#endif
uniform float niri_alpha;
uniform float niri_scale;
uniform vec2 niri_size;
varying vec2 niri_v_coords;
@ -56,7 +57,8 @@ float rounding_alpha(vec2 coords, vec2 size, vec4 corner_radius) {
}
float dist = distance(coords, center);
return 1.0 - smoothstep(radius - 0.5, radius + 0.5, dist);
float half_px = 0.5 / niri_scale;
return 1.0 - smoothstep(radius - half_px, radius + half_px, dist);
}
void main() {

View File

@ -20,6 +20,8 @@ varying vec2 v_coords;
uniform float tint;
#endif
uniform float niri_scale;
uniform vec2 geo_size;
uniform vec4 corner_radius;
uniform mat3 input_to_geo;
@ -45,7 +47,8 @@ float rounding_alpha(vec2 coords, vec2 size) {
}
float dist = distance(coords, center);
return 1.0 - smoothstep(radius - 0.5, radius + 0.5, dist);
float half_px = 0.5 / niri_scale;
return 1.0 - smoothstep(radius - half_px, radius + half_px, dist);
}
void main() {

View File

@ -18,4 +18,5 @@ uniform float niri_clamped_progress;
uniform float niri_random_seed;
uniform float niri_alpha;
uniform float niri_scale;

View File

@ -55,6 +55,7 @@ impl Shaders {
.compile_custom_texture_shader(
include_str!("clipped_surface.frag"),
&[
UniformName::new("niri_scale", UniformType::_1f),
UniformName::new("geo_size", UniformType::_2f),
UniformName::new("corner_radius", UniformType::_4f),
UniformName::new("input_to_geo", UniformType::Matrix3x3),

View File

@ -18,4 +18,5 @@ uniform float niri_clamped_progress;
uniform float niri_random_seed;
uniform float niri_alpha;
uniform float niri_scale;

View File

@ -25,6 +25,7 @@ uniform vec4 niri_corner_radius;
uniform float niri_clip_to_geometry;
uniform float niri_alpha;
uniform float niri_scale;
float niri_rounding_alpha(vec2 coords, vec2 size) {
vec2 center;
@ -47,5 +48,6 @@ float niri_rounding_alpha(vec2 coords, vec2 size) {
}
float dist = distance(coords, center);
return 1.0 - smoothstep(radius - 0.5, radius + 0.5, dist);
float half_px = 0.5 / niri_scale;
return 1.0 - smoothstep(radius - half_px, radius + half_px, dist);
}