From 249335b146989b34d03ce26c7d6572bf48f82d53 Mon Sep 17 00:00:00 2001 From: K's Thinkpad Date: Tue, 2 Jul 2024 17:47:09 +0200 Subject: [PATCH 01/34] Added the better color averaging code (tested & functional) --- src/render_helpers/shaders/border.frag | 31 ++++++++++++++++++++++++- src/render_helpers/shaders/resize.frag | 32 +++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/render_helpers/shaders/border.frag b/src/render_helpers/shaders/border.frag index fe12103..a79835a 100644 --- a/src/render_helpers/shaders/border.frag +++ b/src/render_helpers/shaders/border.frag @@ -21,6 +21,35 @@ uniform vec2 geo_size; uniform vec4 outer_radius; uniform float border_width; + +vec4 linear_color_mix(vec4 color1, vec4 color2, float color_ratio) { + vec4 lin_color1 = vec4( + pow(color1.r, 2.0), + pow(color1.g, 2.0), + pow(color1.b, 2.0), + color1.a + ); + + vec4 lin_color2 = vec4( + pow(color2.r, 2.0), + pow(color2.g, 2.0), + pow(color2.b, 2.0), + color2.a + ); + + vec4 color_out = mix( + lin_color1, + lin_color2, + color_ratio + ); + + return vec4(sqrt(color_out.r), + sqrt(color_out.g), + sqrt(color_out.b), + color_out.a + ); +} + vec4 gradient_color(vec2 coords) { coords = coords + grad_offset; @@ -33,7 +62,7 @@ vec4 gradient_color(vec2 coords) { frac += 1.0; frac = clamp(frac, 0.0, 1.0); - return mix(color_from, color_to, frac); + return linear_color_mix(color_from, color_to, frac); } float rounding_alpha(vec2 coords, vec2 size, vec4 corner_radius) { diff --git a/src/render_helpers/shaders/resize.frag b/src/render_helpers/shaders/resize.frag index d1ed30f..94f250d 100644 --- a/src/render_helpers/shaders/resize.frag +++ b/src/render_helpers/shaders/resize.frag @@ -1,3 +1,33 @@ + +vec4 linear_color_mix(vec4 color1, vec4 color2, float color_ratio) { + vec4 lin_color1 = vec4( + pow(color1.r, 2.0), + pow(color1.g, 2.0), + pow(color1.b, 2.0), + color1.a + ); + + vec4 lin_color2 = vec4( + pow(color2.r, 2.0), + pow(color2.g, 2.0), + pow(color2.b, 2.0), + color2.a + ); + + vec4 color_out = mix( + lin_color1, + lin_color2, + color_ratio + ); + + return vec4(sqrt(color_out.r), + sqrt(color_out.g), + sqrt(color_out.b), + color_out.a + ); +} + + vec4 resize_color(vec3 coords_curr_geo, vec3 size_curr_geo) { vec3 coords_tex_prev = niri_geo_to_tex_prev * coords_curr_geo; vec4 color_prev = texture2D(niri_tex_prev, coords_tex_prev.st); @@ -5,6 +35,6 @@ vec4 resize_color(vec3 coords_curr_geo, vec3 size_curr_geo) { vec3 coords_tex_next = niri_geo_to_tex_next * coords_curr_geo; vec4 color_next = texture2D(niri_tex_next, coords_tex_next.st); - vec4 color = mix(color_prev, color_next, niri_clamped_progress); + vec4 color = linear_color_mix(color_prev, color_next, niri_clamped_progress); return color; } From 3c2f33dcd1a03eae8af059fc4589732e595dda69 Mon Sep 17 00:00:00 2001 From: K's Thinkpad Date: Thu, 4 Jul 2024 21:45:08 +0200 Subject: [PATCH 02/34] will soon have working gradient selection --- niri-config/src/lib.rs | 11 ++++ src/layout/focus_ring.rs | 12 ++++- src/layout/tile.rs | 1 + src/render_helpers/border.rs | 8 +++ src/render_helpers/shaders/border.frag | 54 +------------------ src/render_helpers/shaders/mod.rs | 16 +++++- src/render_helpers/shaders/resize.frag | 32 +---------- .../shaders/resize_prelude.frag | 1 + src/window/mapped.rs | 1 + 9 files changed, 49 insertions(+), 87 deletions(-) diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs index f1bd0af..b833677 100644 --- a/niri-config/src/lib.rs +++ b/niri-config/src/lib.rs @@ -410,6 +410,8 @@ pub struct Gradient { pub angle: i16, #[knuffel(property, default)] pub relative_to: GradientRelativeTo, + #[knuffel(property, default)] + pub gradient_type: GradientType, } #[derive(knuffel::DecodeScalar, Debug, Default, Clone, Copy, PartialEq, Eq)] @@ -419,6 +421,15 @@ pub enum GradientRelativeTo { WorkspaceView, } +#[derive(knuffel::DecodeScalar, Debug, Default, Clone, Copy, PartialEq, Eq)] +pub enum GradientType { + #[default] + CssLinear, + Linear, + Oklab, + Lch, +} + #[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)] pub struct Border { #[knuffel(child)] diff --git a/src/layout/focus_ring.rs b/src/layout/focus_ring.rs index 97a1b75..7160362 100644 --- a/src/layout/focus_ring.rs +++ b/src/layout/focus_ring.rs @@ -1,7 +1,7 @@ use std::iter::zip; use arrayvec::ArrayVec; -use niri_config::{CornerRadius, Gradient, GradientRelativeTo}; +use niri_config::{CornerRadius, Gradient, GradientRelativeTo, GradientType}; use smithay::backend::renderer::element::Kind; use smithay::utils::{Logical, Point, Rectangle, Size}; @@ -91,6 +91,7 @@ impl FocusRing { to: color, angle: 0, relative_to: GradientRelativeTo::Window, + gradient_type: GradientType::CssLinear, }); let full_rect = Rectangle::from_loc_and_size((-width, -width), self.full_size); @@ -99,6 +100,13 @@ impl FocusRing { GradientRelativeTo::WorkspaceView => view_rect, }; + let gradient_format = match gradient.gradient_type { + GradientType::CssLinear => 0., + GradientType::Linear => 1., + GradientType::Oklab => 2., + GradientType::Lch => 3., + }; + let rounded_corner_border_width = if self.is_border { // HACK: increase the border width used for the inner rounded corners a tiny bit to // reduce background bleed. @@ -178,6 +186,7 @@ impl FocusRing { border.update( size, Rectangle::from_loc_and_size(gradient_area.loc - loc, gradient_area.size), + gradient_format, gradient.from.into(), gradient.to.into(), ((gradient.angle as f32) - 90.).to_radians(), @@ -198,6 +207,7 @@ impl FocusRing { gradient_area.loc - self.locations[0], gradient_area.size, ), + gradient_format, gradient.from.into(), gradient.to.into(), ((gradient.angle as f32) - 90.).to_radians(), diff --git a/src/layout/tile.rs b/src/layout/tile.rs index 710add8..68cb669 100644 --- a/src/layout/tile.rs +++ b/src/layout/tile.rs @@ -757,6 +757,7 @@ impl Tile { return BorderRenderElement::new( geo.size, Rectangle::from_loc_and_size((0., 0.), geo.size), + 0., elem.color(), elem.color(), 0., diff --git a/src/render_helpers/border.rs b/src/render_helpers/border.rs index 7e36c44..0b650f1 100644 --- a/src/render_helpers/border.rs +++ b/src/render_helpers/border.rs @@ -28,6 +28,7 @@ pub struct BorderRenderElement { struct Parameters { size: Size, gradient_area: Rectangle, + gradient_format: f32, color_from: [f32; 4], color_to: [f32; 4], angle: f32, @@ -43,6 +44,7 @@ impl BorderRenderElement { pub fn new( size: Size, gradient_area: Rectangle, + gradient_format: f32, color_from: [f32; 4], color_to: [f32; 4], angle: f32, @@ -57,6 +59,7 @@ impl BorderRenderElement { params: Parameters { size, gradient_area, + gradient_format, color_from, color_to, angle, @@ -77,6 +80,7 @@ impl BorderRenderElement { params: Parameters { size: Default::default(), gradient_area: Default::default(), + gradient_format: 0., color_from: Default::default(), color_to: Default::default(), angle: 0., @@ -97,6 +101,7 @@ impl BorderRenderElement { &mut self, size: Size, gradient_area: Rectangle, + gradient_format: f32, color_from: [f32; 4], color_to: [f32; 4], angle: f32, @@ -108,6 +113,7 @@ impl BorderRenderElement { let params = Parameters { size, gradient_area, + gradient_format, color_from, color_to, angle, @@ -128,6 +134,7 @@ impl BorderRenderElement { let Parameters { size, gradient_area, + gradient_format, color_from, color_to, angle, @@ -167,6 +174,7 @@ impl BorderRenderElement { None, scale, vec![ + Uniform::new("grad_format", gradient_format), Uniform::new("color_from", color_from), Uniform::new("color_to", color_to), Uniform::new("grad_offset", grad_offset.to_array()), diff --git a/src/render_helpers/shaders/border.frag b/src/render_helpers/shaders/border.frag index a79835a..52d2a04 100644 --- a/src/render_helpers/shaders/border.frag +++ b/src/render_helpers/shaders/border.frag @@ -1,55 +1,3 @@ -precision mediump float; - -#if defined(DEBUG_FLAGS) -uniform float niri_tint; -#endif - -uniform float niri_alpha; -uniform float niri_scale; - -uniform vec2 niri_size; -varying vec2 niri_v_coords; - -uniform vec4 color_from; -uniform vec4 color_to; -uniform vec2 grad_offset; -uniform float grad_width; -uniform vec2 grad_vec; - -uniform mat3 input_to_geo; -uniform vec2 geo_size; -uniform vec4 outer_radius; -uniform float border_width; - - -vec4 linear_color_mix(vec4 color1, vec4 color2, float color_ratio) { - vec4 lin_color1 = vec4( - pow(color1.r, 2.0), - pow(color1.g, 2.0), - pow(color1.b, 2.0), - color1.a - ); - - vec4 lin_color2 = vec4( - pow(color2.r, 2.0), - pow(color2.g, 2.0), - pow(color2.b, 2.0), - color2.a - ); - - vec4 color_out = mix( - lin_color1, - lin_color2, - color_ratio - ); - - return vec4(sqrt(color_out.r), - sqrt(color_out.g), - sqrt(color_out.b), - color_out.a - ); -} - vec4 gradient_color(vec2 coords) { coords = coords + grad_offset; @@ -62,7 +10,7 @@ vec4 gradient_color(vec2 coords) { frac += 1.0; frac = clamp(frac, 0.0, 1.0); - return linear_color_mix(color_from, color_to, frac); + return color_mix(color_from, color_to, frac); } float rounding_alpha(vec2 coords, vec2 size, vec4 corner_radius) { diff --git a/src/render_helpers/shaders/mod.rs b/src/render_helpers/shaders/mod.rs index b482493..d371f07 100644 --- a/src/render_helpers/shaders/mod.rs +++ b/src/render_helpers/shaders/mod.rs @@ -32,8 +32,13 @@ impl Shaders { let border = ShaderProgram::compile( renderer, - include_str!("border.frag"), + concat!( + include_str!("border_head.frag"), + include_str!("color_interpol.frag"), + include_str!("border.frag") + ), &[ + UniformName::new("grad_format", UniformType::_1f), UniformName::new("color_from", UniformType::_4f), UniformName::new("color_to", UniformType::_4f), UniformName::new("grad_offset", UniformType::_2f), @@ -66,7 +71,13 @@ impl Shaders { }) .ok(); - let resize = compile_resize_program(renderer, include_str!("resize.frag")) + let resize = compile_resize_program( + renderer, + concat!( + include_str!("color_interpol.frag"), + include_str!("resize.frag") + ) + ) .map_err(|err| { warn!("error compiling resize shader: {err:?}"); }) @@ -150,6 +161,7 @@ fn compile_resize_program( renderer, &program, &[ + UniformName::new("grad_format", UniformType::_1f), UniformName::new("niri_input_to_curr_geo", UniformType::Matrix3x3), UniformName::new("niri_curr_geo_to_prev_geo", UniformType::Matrix3x3), UniformName::new("niri_curr_geo_to_next_geo", UniformType::Matrix3x3), diff --git a/src/render_helpers/shaders/resize.frag b/src/render_helpers/shaders/resize.frag index 94f250d..de39625 100644 --- a/src/render_helpers/shaders/resize.frag +++ b/src/render_helpers/shaders/resize.frag @@ -1,33 +1,3 @@ - -vec4 linear_color_mix(vec4 color1, vec4 color2, float color_ratio) { - vec4 lin_color1 = vec4( - pow(color1.r, 2.0), - pow(color1.g, 2.0), - pow(color1.b, 2.0), - color1.a - ); - - vec4 lin_color2 = vec4( - pow(color2.r, 2.0), - pow(color2.g, 2.0), - pow(color2.b, 2.0), - color2.a - ); - - vec4 color_out = mix( - lin_color1, - lin_color2, - color_ratio - ); - - return vec4(sqrt(color_out.r), - sqrt(color_out.g), - sqrt(color_out.b), - color_out.a - ); -} - - vec4 resize_color(vec3 coords_curr_geo, vec3 size_curr_geo) { vec3 coords_tex_prev = niri_geo_to_tex_prev * coords_curr_geo; vec4 color_prev = texture2D(niri_tex_prev, coords_tex_prev.st); @@ -35,6 +5,6 @@ vec4 resize_color(vec3 coords_curr_geo, vec3 size_curr_geo) { vec3 coords_tex_next = niri_geo_to_tex_next * coords_curr_geo; vec4 color_next = texture2D(niri_tex_next, coords_tex_next.st); - vec4 color = linear_color_mix(color_prev, color_next, niri_clamped_progress); + vec4 color = color_mix(color_prev, color_next, niri_clamped_progress); return color; } diff --git a/src/render_helpers/shaders/resize_prelude.frag b/src/render_helpers/shaders/resize_prelude.frag index 519b1ee..34a1f87 100644 --- a/src/render_helpers/shaders/resize_prelude.frag +++ b/src/render_helpers/shaders/resize_prelude.frag @@ -7,6 +7,7 @@ uniform float niri_tint; varying vec2 niri_v_coords; uniform vec2 niri_size; +uniform float grad_format; uniform mat3 niri_input_to_curr_geo; uniform mat3 niri_curr_geo_to_prev_geo; uniform mat3 niri_curr_geo_to_next_geo; diff --git a/src/window/mapped.rs b/src/window/mapped.rs index 8b6b8e6..b66a513 100644 --- a/src/window/mapped.rs +++ b/src/window/mapped.rs @@ -289,6 +289,7 @@ impl Mapped { return BorderRenderElement::new( geo.size, Rectangle::from_loc_and_size((0., 0.), geo.size), + 0., elem.color(), elem.color(), 0., From e5e0cc449f689ebd170a93520ac0a225e869dccf Mon Sep 17 00:00:00 2001 From: K's Thinkpad Date: Thu, 4 Jul 2024 21:46:08 +0200 Subject: [PATCH 03/34] has functioning optional gradient change --- src/render_helpers/shaders/border_head.frag | 30 +++++++++++++ .../shaders/color_interpol.frag | 44 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 src/render_helpers/shaders/border_head.frag create mode 100644 src/render_helpers/shaders/color_interpol.frag diff --git a/src/render_helpers/shaders/border_head.frag b/src/render_helpers/shaders/border_head.frag new file mode 100644 index 0000000..8a9fe60 --- /dev/null +++ b/src/render_helpers/shaders/border_head.frag @@ -0,0 +1,30 @@ +precision mediump float; + +#if defined(DEBUG_FLAGS) +uniform float niri_tint; +#endif + +uniform float niri_alpha; +uniform float niri_scale; + +uniform vec2 niri_size; +varying vec2 niri_v_coords; + +uniform float grad_format; +uniform vec4 color_from; +uniform vec4 color_to; +uniform vec2 grad_offset; +uniform float grad_width; +uniform vec2 grad_vec; + +uniform mat3 input_to_geo; +uniform vec2 geo_size; +uniform vec4 outer_radius; +uniform float border_width; + + +// FIXME this is a terrible solution however, +// I need to insert a different file with +// functions after this part as adding them ahead will cause errors at runtime +// and havent found a clean way to do this +// this is prob super simple and im just too stupid diff --git a/src/render_helpers/shaders/color_interpol.frag b/src/render_helpers/shaders/color_interpol.frag new file mode 100644 index 0000000..70621e4 --- /dev/null +++ b/src/render_helpers/shaders/color_interpol.frag @@ -0,0 +1,44 @@ + +vec4 color_linear(vec4 color) { + return vec4( + pow(color.r, 2.0), + pow(color.g, 2.0), + pow(color.b, 2.0), + color.a + ); +} + +vec4 color_root(vec4 color) { + return vec4( + sqrt(color.r), + sqrt(color.g), + sqrt(color.b), + color.a + ); +} + +vec4 color_mix(vec4 color1, vec4 color2, float color_ratio) { + + float gradient_type = grad_format; + + if(gradient_type == 0.0) { // CssLinear + return mix(color1, color2, color_ratio); + } + + vec4 color_out; + + color1 = color_linear(color1); + color2 = color_linear(color2); + + if (gradient_type == 1.0) { + color_out = mix( + color1, + color2, + color_ratio + ); + }else{ + color_out = vec4(255.0,0.0,0.0,1.0); + } + + return color_root(color_out); +} From f3dbb0297598e13a6e9bb356d9140ab43416a3b7 Mon Sep 17 00:00:00 2001 From: K's Thinkpad Date: Fri, 5 Jul 2024 00:09:51 +0200 Subject: [PATCH 04/34] updated the config and the wiki to reflect current state --- resources/default-config.kdl | 1 + src/render_helpers/shaders/color_interpol.frag | 6 ++---- wiki/Configuration:-Layout.md | 13 ++++++++++--- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/resources/default-config.kdl b/resources/default-config.kdl index 469517d..a4b1cbd 100644 --- a/resources/default-config.kdl +++ b/resources/default-config.kdl @@ -152,6 +152,7 @@ layout { // The angle is the same as in linear-gradient, and is optional, // defaulting to 180 (top-to-bottom gradient). // You can use any CSS linear-gradient tool on the web to set these up. + // for gradient types visit the wiki // // active-gradient from="#80c8ff" to="#bbddff" angle=45 diff --git a/src/render_helpers/shaders/color_interpol.frag b/src/render_helpers/shaders/color_interpol.frag index 70621e4..00ed120 100644 --- a/src/render_helpers/shaders/color_interpol.frag +++ b/src/render_helpers/shaders/color_interpol.frag @@ -18,10 +18,8 @@ vec4 color_root(vec4 color) { } vec4 color_mix(vec4 color1, vec4 color2, float color_ratio) { - - float gradient_type = grad_format; - if(gradient_type == 0.0) { // CssLinear + if(grad_format == 0.0) { // CssLinear return mix(color1, color2, color_ratio); } @@ -30,7 +28,7 @@ vec4 color_mix(vec4 color1, vec4 color2, float color_ratio) { color1 = color_linear(color1); color2 = color_linear(color2); - if (gradient_type == 1.0) { + if (grad_format == 1.0) { // rgb linear color_out = mix( color1, color2, diff --git a/wiki/Configuration:-Layout.md b/wiki/Configuration:-Layout.md index e27d0ef..7e3d096 100644 --- a/wiki/Configuration:-Layout.md +++ b/wiki/Configuration:-Layout.md @@ -32,7 +32,7 @@ layout { active-color "#ffc87f" inactive-color "#505050" // active-gradient from="#ffbb66" to="#ffc880" angle=45 relative-to="workspace-view" - // inactive-gradient from="#505050" to="#808080" angle=45 relative-to="workspace-view" + // inactive-gradient from="#505050" to="#808080" angle=45 relative-to="workspace-view" gradient-type="linear" } struts { @@ -169,7 +169,7 @@ layout { inactive-color "#505050" // active-gradient from="#ffbb66" to="#ffc880" angle=45 relative-to="workspace-view" - // inactive-gradient from="#505050" to="#808080" angle=45 relative-to="workspace-view" + // inactive-gradient from="#505050" to="#808080" angle=45 relative-to="workspace-view" gradient-type="linear" } } ``` @@ -209,7 +209,7 @@ There's also a *deprecated* syntax for setting colors with four numbers represen Similarly to colors, you can set `active-gradient` and `inactive-gradient`, which will take precedence. -Gradients are rendered the same as CSS [`linear-gradient(angle, from, to)`](https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/linear-gradient). +Gradients can be rendered the same as CSS [`linear-gradient(angle, from, to)`](https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/linear-gradient). The angle works the same as in `linear-gradient`, and is optional, defaulting to `180` (top-to-bottom gradient). You can use any CSS linear-gradient tool on the web to set these up, like [this one](https://www.css-gradient.com/). @@ -221,6 +221,13 @@ layout { } ``` +Gradients can be rendered with different kinds of color interpolation, this doesen't mean that the arguments the gradient takes +are any different. Except for an optional `gradient-type` argument which can currently be: +`gradient-type="css-linear"`(Default), +`gradient-type="linear"`, +`gradient-type="Oklab"`(Unimplemented), +`gradient-type="Lch"` + Gradients can be colored relative to windows individually (the default), or to the whole view of the workspace. To do that, set `relative-to="workspace-view"`. Here's a visual example: From 6c263d59c3d2fc6f9b3ac8996d25ccf723c9a950 Mon Sep 17 00:00:00 2001 From: Kiko Date: Thu, 4 Jul 2024 22:12:03 +0000 Subject: [PATCH 05/34] Update Configuration:-Layout.md --- wiki/Configuration:-Layout.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/wiki/Configuration:-Layout.md b/wiki/Configuration:-Layout.md index 7e3d096..fcf3d8f 100644 --- a/wiki/Configuration:-Layout.md +++ b/wiki/Configuration:-Layout.md @@ -223,11 +223,16 @@ layout { Gradients can be rendered with different kinds of color interpolation, this doesen't mean that the arguments the gradient takes are any different. Except for an optional `gradient-type` argument which can currently be: + `gradient-type="css-linear"`(Default), + `gradient-type="linear"`, + `gradient-type="Oklab"`(Unimplemented), + `gradient-type="Lch"` + Gradients can be colored relative to windows individually (the default), or to the whole view of the workspace. To do that, set `relative-to="workspace-view"`. Here's a visual example: From 3aedbf723238383df8a5b9099a371f43f7d7080c Mon Sep 17 00:00:00 2001 From: K's Thinkpad Date: Sat, 6 Jul 2024 13:30:19 +0200 Subject: [PATCH 06/34] reconfiguring fro css in --- niri-config/src/lib.rs | 29 ++++++-- src/layout/focus_ring.rs | 15 ++-- src/layout/tile.rs | 7 +- src/render_helpers/border.rs | 30 ++++++-- src/render_helpers/shaders/border.frag | 72 +++++++++++++++++++ src/render_helpers/shaders/border_head.frag | 30 -------- .../shaders/color_interpol.frag | 42 ----------- src/render_helpers/shaders/mod.rs | 15 ++-- src/render_helpers/shaders/resize.frag | 2 +- .../shaders/resize_prelude.frag | 1 - src/window/mapped.rs | 7 +- 11 files changed, 141 insertions(+), 109 deletions(-) delete mode 100644 src/render_helpers/shaders/border_head.frag delete mode 100644 src/render_helpers/shaders/color_interpol.frag diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs index abc03a9..b0a5bd8 100644 --- a/niri-config/src/lib.rs +++ b/niri-config/src/lib.rs @@ -413,8 +413,8 @@ pub struct Gradient { pub angle: i16, #[knuffel(property, default)] pub relative_to: GradientRelativeTo, - #[knuffel(property, default)] - pub gradient_type: GradientType, + #[knuffel(child)] + pub _in: GradientInterpolation, } #[derive(knuffel::DecodeScalar, Debug, Default, Clone, Copy, PartialEq, Eq)] @@ -424,13 +424,30 @@ pub enum GradientRelativeTo { WorkspaceView, } +#[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)] +pub struct GradientInterpolation { + #[knuffel(property, default)] + pub color_space: GradientColorSpace, + #[knuffel(property, default)] + pub hue_interpol: HueInterpolation +} + #[derive(knuffel::DecodeScalar, Debug, Default, Clone, Copy, PartialEq, Eq)] -pub enum GradientType { +pub enum GradientColorSpace { #[default] - CssLinear, - Linear, + Srgb, + SrgbLinear, Oklab, - Lch, + XyzD50, +} + +#[derive(knuffel::DecodeScalar, Debug, Default, Clone, Copy, PartialEq, Eq)] +pub enum HueInterpolation { + #[default] + Shorter, + Longer, + Increasing, + Decreasing, } #[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)] diff --git a/src/layout/focus_ring.rs b/src/layout/focus_ring.rs index 7160362..7d3dd29 100644 --- a/src/layout/focus_ring.rs +++ b/src/layout/focus_ring.rs @@ -1,7 +1,7 @@ use std::iter::zip; use arrayvec::ArrayVec; -use niri_config::{CornerRadius, Gradient, GradientRelativeTo, GradientType}; +use niri_config::{CornerRadius, Gradient, GradientRelativeTo, GradientInterpolation, GradientColorSpace, HueInterpolation}; use smithay::backend::renderer::element::Kind; use smithay::utils::{Logical, Point, Rectangle, Size}; @@ -91,7 +91,10 @@ impl FocusRing { to: color, angle: 0, relative_to: GradientRelativeTo::Window, - gradient_type: GradientType::CssLinear, + _in: GradientInterpolation { + color_space: GradientColorSpace::Srgb, + hue_interpol: HueInterpolation::Shorter + } }); let full_rect = Rectangle::from_loc_and_size((-width, -width), self.full_size); @@ -100,12 +103,8 @@ impl FocusRing { GradientRelativeTo::WorkspaceView => view_rect, }; - let gradient_format = match gradient.gradient_type { - GradientType::CssLinear => 0., - GradientType::Linear => 1., - GradientType::Oklab => 2., - GradientType::Lch => 3., - }; + let gradient_format = gradient._in; + let rounded_corner_border_width = if self.is_border { // HACK: increase the border width used for the inner rounded corners a tiny bit to diff --git a/src/layout/tile.rs b/src/layout/tile.rs index 68cb669..8c563bd 100644 --- a/src/layout/tile.rs +++ b/src/layout/tile.rs @@ -1,7 +1,7 @@ use std::rc::Rc; use std::time::Duration; -use niri_config::CornerRadius; +use niri_config::{CornerRadius, GradientInterpolation, GradientColorSpace, HueInterpolation}; use smithay::backend::allocator::Fourcc; use smithay::backend::renderer::element::{Element, Kind}; use smithay::backend::renderer::gles::GlesRenderer; @@ -757,7 +757,10 @@ impl Tile { return BorderRenderElement::new( geo.size, Rectangle::from_loc_and_size((0., 0.), geo.size), - 0., + GradientInterpolation{ + color_space: GradientColorSpace::Srgb, + hue_interpol: HueInterpolation::Shorter + }, elem.color(), elem.color(), 0., diff --git a/src/render_helpers/border.rs b/src/render_helpers/border.rs index 0b650f1..41fc1b2 100644 --- a/src/render_helpers/border.rs +++ b/src/render_helpers/border.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use glam::{Mat3, Vec2}; -use niri_config::CornerRadius; +use niri_config::{CornerRadius, GradientInterpolation, GradientColorSpace, HueInterpolation}; use smithay::backend::renderer::element::{Element, Id, Kind, RenderElement, UnderlyingStorage}; use smithay::backend::renderer::gles::{GlesError, GlesFrame, GlesRenderer, Uniform}; use smithay::backend::renderer::utils::{CommitCounter, DamageSet, OpaqueRegions}; @@ -28,7 +28,7 @@ pub struct BorderRenderElement { struct Parameters { size: Size, gradient_area: Rectangle, - gradient_format: f32, + gradient_format: GradientInterpolation, color_from: [f32; 4], color_to: [f32; 4], angle: f32, @@ -44,7 +44,7 @@ impl BorderRenderElement { pub fn new( size: Size, gradient_area: Rectangle, - gradient_format: f32, + gradient_format: GradientInterpolation, color_from: [f32; 4], color_to: [f32; 4], angle: f32, @@ -80,7 +80,10 @@ impl BorderRenderElement { params: Parameters { size: Default::default(), gradient_area: Default::default(), - gradient_format: 0., + gradient_format: GradientInterpolation { + color_space: GradientColorSpace::Srgb, + hue_interpol: HueInterpolation::Shorter + }, color_from: Default::default(), color_to: Default::default(), angle: 0., @@ -101,7 +104,7 @@ impl BorderRenderElement { &mut self, size: Size, gradient_area: Rectangle, - gradient_format: f32, + gradient_format: GradientInterpolation, color_from: [f32; 4], color_to: [f32; 4], angle: f32, @@ -169,12 +172,27 @@ impl BorderRenderElement { let input_to_geo = Mat3::from_scale(area_size) * Mat3::from_translation(-geo_loc / area_size); + let colorspace = match gradient_format.color_space { + GradientColorSpace::Srgb => 0., + GradientColorSpace::SrgbLinear => 1., + GradientColorSpace::Oklab => 2., + GradientColorSpace::XyzD50 => 3. + }; + + let hue_interpolation = match gradient_format.hue_interpol { + HueInterpolation::Shorter => 0., + HueInterpolation::Longer => 1., + HueInterpolation::Increasing => 2., + HueInterpolation::Decreasing => 3. + }; + self.inner.update( size, None, scale, vec![ - Uniform::new("grad_format", gradient_format), + Uniform::new("colorspace", colorspace), + Uniform::new("hue_interpolation", hue_interpolation), Uniform::new("color_from", color_from), Uniform::new("color_to", color_to), Uniform::new("grad_offset", grad_offset.to_array()), diff --git a/src/render_helpers/shaders/border.frag b/src/render_helpers/shaders/border.frag index 52d2a04..ccfe376 100644 --- a/src/render_helpers/shaders/border.frag +++ b/src/render_helpers/shaders/border.frag @@ -1,3 +1,75 @@ +precision mediump float; + +#if defined(DEBUG_FLAGS) +uniform float niri_tint; +#endif + +uniform float niri_alpha; +uniform float niri_scale; + +uniform vec2 niri_size; +varying vec2 niri_v_coords; + +uniform float colorspace; +uniform float hue_interpolation; +uniform vec4 color_from; +uniform vec4 color_to; +uniform vec2 grad_offset; +uniform float grad_width; +uniform vec2 grad_vec; + +uniform mat3 input_to_geo; +uniform vec2 geo_size; +uniform vec4 outer_radius; +uniform float border_width; + +vec4 srgb_to_linear(vec4 color) { + return vec4( + (color.rgb / color.aaa) * (color.rgb / color.aaa), + color.a + ); +} + +vec4 linear_to_srgb(vec4 color) { + return vec4( + sqrt(color.r) * color.a, + sqrt(color.g) * color.a, + sqrt(color.b) * color.a, + color.a + ); +} + +vec4 color_mix(vec4 color1, vec4 color2, float color_ratio) { + + if (colorspace == 0.0) // srgb + return mix(color1, color2, color_ratio); + + vec4 color_out; + + color1 = srgb_to_linear(color1); + color2 = srgb_to_linear(color2); + + if (colorspace == 1.0) { // srgb-linear + color_out = mix( + color1, + color2, + color_ratio + ); + } else if (colorspace == 2.0) { // oklab + color1 = xyz_to_oklab(linear_to_xyz(color1)); + color2 = xyz_to_oklab(linear_to_xyz(color2)); + color_out = + } else { + color_out = vec4( + 255.0, + 0.0, + 0.0, + 1.0 + ); + } + return linear_to_srgb(color_out); +} + vec4 gradient_color(vec2 coords) { coords = coords + grad_offset; diff --git a/src/render_helpers/shaders/border_head.frag b/src/render_helpers/shaders/border_head.frag deleted file mode 100644 index 8a9fe60..0000000 --- a/src/render_helpers/shaders/border_head.frag +++ /dev/null @@ -1,30 +0,0 @@ -precision mediump float; - -#if defined(DEBUG_FLAGS) -uniform float niri_tint; -#endif - -uniform float niri_alpha; -uniform float niri_scale; - -uniform vec2 niri_size; -varying vec2 niri_v_coords; - -uniform float grad_format; -uniform vec4 color_from; -uniform vec4 color_to; -uniform vec2 grad_offset; -uniform float grad_width; -uniform vec2 grad_vec; - -uniform mat3 input_to_geo; -uniform vec2 geo_size; -uniform vec4 outer_radius; -uniform float border_width; - - -// FIXME this is a terrible solution however, -// I need to insert a different file with -// functions after this part as adding them ahead will cause errors at runtime -// and havent found a clean way to do this -// this is prob super simple and im just too stupid diff --git a/src/render_helpers/shaders/color_interpol.frag b/src/render_helpers/shaders/color_interpol.frag deleted file mode 100644 index 00ed120..0000000 --- a/src/render_helpers/shaders/color_interpol.frag +++ /dev/null @@ -1,42 +0,0 @@ - -vec4 color_linear(vec4 color) { - return vec4( - pow(color.r, 2.0), - pow(color.g, 2.0), - pow(color.b, 2.0), - color.a - ); -} - -vec4 color_root(vec4 color) { - return vec4( - sqrt(color.r), - sqrt(color.g), - sqrt(color.b), - color.a - ); -} - -vec4 color_mix(vec4 color1, vec4 color2, float color_ratio) { - - if(grad_format == 0.0) { // CssLinear - return mix(color1, color2, color_ratio); - } - - vec4 color_out; - - color1 = color_linear(color1); - color2 = color_linear(color2); - - if (grad_format == 1.0) { // rgb linear - color_out = mix( - color1, - color2, - color_ratio - ); - }else{ - color_out = vec4(255.0,0.0,0.0,1.0); - } - - return color_root(color_out); -} diff --git a/src/render_helpers/shaders/mod.rs b/src/render_helpers/shaders/mod.rs index d371f07..7896c0a 100644 --- a/src/render_helpers/shaders/mod.rs +++ b/src/render_helpers/shaders/mod.rs @@ -32,13 +32,10 @@ impl Shaders { let border = ShaderProgram::compile( renderer, - concat!( - include_str!("border_head.frag"), - include_str!("color_interpol.frag"), - include_str!("border.frag") - ), + include_str!("border.frag"), &[ - UniformName::new("grad_format", UniformType::_1f), + UniformName::new("colorspace", UniformType::_1f), + UniformName::new("hue_interpolation", UniformType::_1f), UniformName::new("color_from", UniformType::_4f), UniformName::new("color_to", UniformType::_4f), UniformName::new("grad_offset", UniformType::_2f), @@ -73,10 +70,7 @@ impl Shaders { let resize = compile_resize_program( renderer, - concat!( - include_str!("color_interpol.frag"), - include_str!("resize.frag") - ) + include_str!("resize.frag") ) .map_err(|err| { warn!("error compiling resize shader: {err:?}"); @@ -161,7 +155,6 @@ fn compile_resize_program( renderer, &program, &[ - UniformName::new("grad_format", UniformType::_1f), UniformName::new("niri_input_to_curr_geo", UniformType::Matrix3x3), UniformName::new("niri_curr_geo_to_prev_geo", UniformType::Matrix3x3), UniformName::new("niri_curr_geo_to_next_geo", UniformType::Matrix3x3), diff --git a/src/render_helpers/shaders/resize.frag b/src/render_helpers/shaders/resize.frag index de39625..d1ed30f 100644 --- a/src/render_helpers/shaders/resize.frag +++ b/src/render_helpers/shaders/resize.frag @@ -5,6 +5,6 @@ vec4 resize_color(vec3 coords_curr_geo, vec3 size_curr_geo) { vec3 coords_tex_next = niri_geo_to_tex_next * coords_curr_geo; vec4 color_next = texture2D(niri_tex_next, coords_tex_next.st); - vec4 color = color_mix(color_prev, color_next, niri_clamped_progress); + vec4 color = mix(color_prev, color_next, niri_clamped_progress); return color; } diff --git a/src/render_helpers/shaders/resize_prelude.frag b/src/render_helpers/shaders/resize_prelude.frag index 34a1f87..519b1ee 100644 --- a/src/render_helpers/shaders/resize_prelude.frag +++ b/src/render_helpers/shaders/resize_prelude.frag @@ -7,7 +7,6 @@ uniform float niri_tint; varying vec2 niri_v_coords; uniform vec2 niri_size; -uniform float grad_format; uniform mat3 niri_input_to_curr_geo; uniform mat3 niri_curr_geo_to_prev_geo; uniform mat3 niri_curr_geo_to_next_geo; diff --git a/src/window/mapped.rs b/src/window/mapped.rs index b66a513..2aa1202 100644 --- a/src/window/mapped.rs +++ b/src/window/mapped.rs @@ -2,7 +2,7 @@ use std::cell::{Cell, RefCell}; use std::cmp::{max, min}; use std::time::Duration; -use niri_config::{CornerRadius, WindowRule}; +use niri_config::{CornerRadius, GradientColorSpace, GradientInterpolation, HueInterpolation, WindowRule}; use smithay::backend::renderer::element::surface::render_elements_from_surface_tree; use smithay::backend::renderer::element::{Id, Kind}; use smithay::backend::renderer::gles::GlesRenderer; @@ -289,7 +289,10 @@ impl Mapped { return BorderRenderElement::new( geo.size, Rectangle::from_loc_and_size((0., 0.), geo.size), - 0., + GradientInterpolation{ + color_space: GradientColorSpace::Srgb, + hue_interpol: HueInterpolation::Shorter + }, elem.color(), elem.color(), 0., From a1fe75c1e58c1ff7646597afcfce311d3a57c149 Mon Sep 17 00:00:00 2001 From: K's Thinkpad Date: Sun, 7 Jul 2024 11:59:55 +0200 Subject: [PATCH 07/34] chnaging gradient interpolation to be more css like --- niri-config/src/lib.rs | 56 +++++++++++++++++++++++++- src/render_helpers/border.rs | 15 ++++++- src/render_helpers/shaders/border.frag | 7 +--- 3 files changed, 69 insertions(+), 9 deletions(-) diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs index 9931265..7ff1d42 100644 --- a/niri-config/src/lib.rs +++ b/niri-config/src/lib.rs @@ -10,7 +10,7 @@ use std::time::Duration; use bitflags::bitflags; use knuffel::errors::DecodeError; use knuffel::Decode as _; -use miette::{miette, Context, IntoDiagnostic, NarratableReportHandler}; +use miette::{miette, Context, IntoDiagnostic, MietteError, NarratableReportHandler}; use niri_ipc::{ConfiguredMode, LayoutSwitchTarget, SizeChange, Transform, WorkspaceReferenceArg}; use regex::Regex; use smithay::input::keyboard::keysyms::KEY_NoSymbol; @@ -422,7 +422,7 @@ pub struct Gradient { pub angle: i16, #[knuffel(property, default)] pub relative_to: GradientRelativeTo, - #[knuffel(child)] + #[knuffel(property, str)] pub _in: GradientInterpolation, } @@ -441,13 +441,65 @@ pub struct GradientInterpolation { pub hue_interpol: HueInterpolation } +impl FromStr for GradientInterpolation { + + type Err = miette::Error; + + fn from_str(s: &str) -> Result { + // Vec<&str> = text.split_whitespace().collect(); + let mut iter = s.split_whitespace(); + let in_part1 = iter.next().unwrap(); + let in_part2 = iter.next().unwrap(); + + let color = match in_part1 { + "srgb" => GradientColorSpace::Srgb, + "srgb-linear" => GradientColorSpace::SrgbLinear, + "display-p3" => GradientColorSpace::DisplayP3, + "a98-rgb" => GradientColorSpace::A98Rgb, + "prophoto-rgb" => GradientColorSpace::ProphotoRgb, + "rec2020" => GradientColorSpace::Rec2020, + "lab" => GradientColorSpace::Lab, + "oklab" => GradientColorSpace::Oklab, + "xyz" => GradientColorSpace::Xyz, + "xyz-d50" => GradientColorSpace::XyzD50, + "xyz-d65" => GradientColorSpace::XyzD65, + "hsl" => GradientColorSpace::Hsl, + "hwb" => GradientColorSpace::Hwb, + "lch" => GradientColorSpace::Lch, + "oklch" => GradientColorSpace::Oklch, + _ => GradientColorSpace::Srgb, + }; + + let interpolation = match in_part2 { + "shorter" => HueInterpolation::Shorter, + "longer" => HueInterpolation::Longer, + "increasing" => HueInterpolation::Increasing, + "decreasing" => HueInterpolation::Decreasing, + _ => HueInterpolation::Shorter + }; + + Ok( Self { color_space: color, hue_interpol: interpolation } ) + } +} + #[derive(knuffel::DecodeScalar, Debug, Default, Clone, Copy, PartialEq, Eq)] pub enum GradientColorSpace { #[default] Srgb, SrgbLinear, + DisplayP3, + A98Rgb, + ProphotoRgb, + Rec2020, + Lab, Oklab, + Xyz, XyzD50, + XyzD65, + Hsl, + Hwb, + Lch, + Oklch } #[derive(knuffel::DecodeScalar, Debug, Default, Clone, Copy, PartialEq, Eq)] diff --git a/src/render_helpers/border.rs b/src/render_helpers/border.rs index 41fc1b2..5bb645f 100644 --- a/src/render_helpers/border.rs +++ b/src/render_helpers/border.rs @@ -175,8 +175,19 @@ impl BorderRenderElement { let colorspace = match gradient_format.color_space { GradientColorSpace::Srgb => 0., GradientColorSpace::SrgbLinear => 1., - GradientColorSpace::Oklab => 2., - GradientColorSpace::XyzD50 => 3. + GradientColorSpace::DisplayP3 => 2., + GradientColorSpace::A98Rgb => 3., + GradientColorSpace::ProphotoRgb => 4., + GradientColorSpace::Rec2020 => 5., + GradientColorSpace::Lab => 6., + GradientColorSpace::Oklab => 7., + GradientColorSpace::Xyz => 8., + GradientColorSpace::XyzD50 => 9., + GradientColorSpace::XyzD65 => 10., + GradientColorSpace::Hsl => 11., + GradientColorSpace::Hwb => 12., + GradientColorSpace::Lch => 13., + GradientColorSpace::Oklch => 14., }; let hue_interpolation = match gradient_format.hue_interpol { diff --git a/src/render_helpers/shaders/border.frag b/src/render_helpers/shaders/border.frag index ccfe376..a3b9684 100644 --- a/src/render_helpers/shaders/border.frag +++ b/src/render_helpers/shaders/border.frag @@ -41,8 +41,9 @@ vec4 linear_to_srgb(vec4 color) { vec4 color_mix(vec4 color1, vec4 color2, float color_ratio) { - if (colorspace == 0.0) // srgb + if (colorspace == 0.0) { // srgb return mix(color1, color2, color_ratio); + } vec4 color_out; @@ -55,10 +56,6 @@ vec4 color_mix(vec4 color1, vec4 color2, float color_ratio) { color2, color_ratio ); - } else if (colorspace == 2.0) { // oklab - color1 = xyz_to_oklab(linear_to_xyz(color1)); - color2 = xyz_to_oklab(linear_to_xyz(color2)); - color_out = } else { color_out = vec4( 255.0, From 3f51f7d300ba62e3e4c1245a023182208451a643 Mon Sep 17 00:00:00 2001 From: K's Thinkpad Date: Sun, 7 Jul 2024 16:56:47 +0200 Subject: [PATCH 08/34] finishing its on fromstr --- niri-config/src/lib.rs | 63 +++++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs index 09a9930..ee6a7a1 100644 --- a/niri-config/src/lib.rs +++ b/niri-config/src/lib.rs @@ -8,6 +8,7 @@ use std::str::FromStr; use std::time::Duration; use bitflags::bitflags; +use bitflags::parser::ParseError; use knuffel::errors::DecodeError; use knuffel::Decode as _; use miette::{miette, Context, IntoDiagnostic, MietteError, NarratableReportHandler}; @@ -17,6 +18,7 @@ use smithay::input::keyboard::keysyms::KEY_NoSymbol; use smithay::input::keyboard::xkb::{keysym_from_name, KEYSYM_CASE_INSENSITIVE}; use smithay::input::keyboard::{Keysym, XkbConfig}; use smithay::reexports::input; +use smithay::reexports::winit::window::CursorIconParseError; #[derive(knuffel::Decode, Debug, PartialEq)] pub struct Config { @@ -446,36 +448,45 @@ impl FromStr for GradientInterpolation { type Err = miette::Error; fn from_str(s: &str) -> Result { - // Vec<&str> = text.split_whitespace().collect(); let mut iter = s.split_whitespace(); - let in_part1 = iter.next().unwrap(); - let in_part2 = iter.next().unwrap(); + let in_part1 = iter.next(); + let in_part2 = iter.next(); - let color = match in_part1 { - "srgb" => GradientColorSpace::Srgb, - "srgb-linear" => GradientColorSpace::SrgbLinear, - "display-p3" => GradientColorSpace::DisplayP3, - "a98-rgb" => GradientColorSpace::A98Rgb, - "prophoto-rgb" => GradientColorSpace::ProphotoRgb, - "rec2020" => GradientColorSpace::Rec2020, - "lab" => GradientColorSpace::Lab, - "oklab" => GradientColorSpace::Oklab, - "xyz" => GradientColorSpace::Xyz, - "xyz-d50" => GradientColorSpace::XyzD50, - "xyz-d65" => GradientColorSpace::XyzD65, - "hsl" => GradientColorSpace::Hsl, - "hwb" => GradientColorSpace::Hwb, - "lch" => GradientColorSpace::Lch, - "oklch" => GradientColorSpace::Oklch, - _ => GradientColorSpace::Srgb, + let color = if in_part1 != None { + let in_str = in_part1.unwrap(); + match in_str { + "srgb" => GradientColorSpace::Srgb, + "srgb-linear" => GradientColorSpace::SrgbLinear, + "display-p3" => GradientColorSpace::DisplayP3, + "a98-rgb" => GradientColorSpace::A98Rgb, + "prophoto-rgb" => GradientColorSpace::ProphotoRgb, + "rec2020" => GradientColorSpace::Rec2020, + "lab" => GradientColorSpace::Lab, + "oklab" => GradientColorSpace::Oklab, + "xyz" => GradientColorSpace::Xyz, + "xyz-d50" => GradientColorSpace::XyzD50, + "xyz-d65" => GradientColorSpace::XyzD65, + "hsl" => GradientColorSpace::Hsl, + "hwb" => GradientColorSpace::Hwb, + "lch" => GradientColorSpace::Lch, + "oklch" => GradientColorSpace::Oklch, + &_ => return Err(miette!("Invalid color-space: {in_str}")) + } + } else { + GradientColorSpace::Srgb }; - let interpolation = match in_part2 { - "shorter" => HueInterpolation::Shorter, - "longer" => HueInterpolation::Longer, - "increasing" => HueInterpolation::Increasing, - "decreasing" => HueInterpolation::Decreasing, - _ => HueInterpolation::Shorter + let interpolation = if in_part2 != None { + let in_str = in_part2.unwrap(); + match in_str { + "shorter" => HueInterpolation::Shorter, + "longer" => HueInterpolation::Longer, + "increasing" => HueInterpolation::Increasing, + "decreasing" => HueInterpolation::Decreasing, + &_ => return Err(miette!("Invalid hue-interpolation: {in_str}")) + } + } else { + HueInterpolation::Shorter }; Ok( Self { color_space: color, hue_interpol: interpolation } ) From 51930227accbe24533de526a6bda61fbacbd592e Mon Sep 17 00:00:00 2001 From: K's Thinkpad Date: Sun, 7 Jul 2024 17:20:55 +0200 Subject: [PATCH 09/34] FindStr finally finished (i put it ahead of FindStr for colors for overviewability) --- niri-config/src/lib.rs | 103 ++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 53 deletions(-) diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs index ee6a7a1..648e59d 100644 --- a/niri-config/src/lib.rs +++ b/niri-config/src/lib.rs @@ -8,17 +8,15 @@ use std::str::FromStr; use std::time::Duration; use bitflags::bitflags; -use bitflags::parser::ParseError; use knuffel::errors::DecodeError; use knuffel::Decode as _; -use miette::{miette, Context, IntoDiagnostic, MietteError, NarratableReportHandler}; +use miette::{miette, Context, IntoDiagnostic, NarratableReportHandler}; use niri_ipc::{ConfiguredMode, LayoutSwitchTarget, SizeChange, Transform, WorkspaceReferenceArg}; use regex::Regex; use smithay::input::keyboard::keysyms::KEY_NoSymbol; use smithay::input::keyboard::xkb::{keysym_from_name, KEYSYM_CASE_INSENSITIVE}; use smithay::input::keyboard::{Keysym, XkbConfig}; use smithay::reexports::input; -use smithay::reexports::winit::window::CursorIconParseError; #[derive(knuffel::Decode, Debug, PartialEq)] pub struct Config { @@ -443,56 +441,6 @@ pub struct GradientInterpolation { pub hue_interpol: HueInterpolation } -impl FromStr for GradientInterpolation { - - type Err = miette::Error; - - fn from_str(s: &str) -> Result { - let mut iter = s.split_whitespace(); - let in_part1 = iter.next(); - let in_part2 = iter.next(); - - let color = if in_part1 != None { - let in_str = in_part1.unwrap(); - match in_str { - "srgb" => GradientColorSpace::Srgb, - "srgb-linear" => GradientColorSpace::SrgbLinear, - "display-p3" => GradientColorSpace::DisplayP3, - "a98-rgb" => GradientColorSpace::A98Rgb, - "prophoto-rgb" => GradientColorSpace::ProphotoRgb, - "rec2020" => GradientColorSpace::Rec2020, - "lab" => GradientColorSpace::Lab, - "oklab" => GradientColorSpace::Oklab, - "xyz" => GradientColorSpace::Xyz, - "xyz-d50" => GradientColorSpace::XyzD50, - "xyz-d65" => GradientColorSpace::XyzD65, - "hsl" => GradientColorSpace::Hsl, - "hwb" => GradientColorSpace::Hwb, - "lch" => GradientColorSpace::Lch, - "oklch" => GradientColorSpace::Oklch, - &_ => return Err(miette!("Invalid color-space: {in_str}")) - } - } else { - GradientColorSpace::Srgb - }; - - let interpolation = if in_part2 != None { - let in_str = in_part2.unwrap(); - match in_str { - "shorter" => HueInterpolation::Shorter, - "longer" => HueInterpolation::Longer, - "increasing" => HueInterpolation::Increasing, - "decreasing" => HueInterpolation::Decreasing, - &_ => return Err(miette!("Invalid hue-interpolation: {in_str}")) - } - } else { - HueInterpolation::Shorter - }; - - Ok( Self { color_space: color, hue_interpol: interpolation } ) - } -} - #[derive(knuffel::DecodeScalar, Debug, Default, Clone, Copy, PartialEq, Eq)] pub enum GradientColorSpace { #[default] @@ -1492,6 +1440,55 @@ impl CornerRadius { } } +impl FromStr for GradientInterpolation { + type Err = miette::Error; + + fn from_str(s: &str) -> Result { + let mut iter = s.split_whitespace(); + let in_part1 = iter.next(); + let in_part2 = iter.next(); + + let color = if in_part1 != None { + let in_str = in_part1.unwrap(); + match in_str { + "srgb" => GradientColorSpace::Srgb, + "srgb-linear" => GradientColorSpace::SrgbLinear, + "display-p3" => GradientColorSpace::DisplayP3, + "a98-rgb" => GradientColorSpace::A98Rgb, + "prophoto-rgb" => GradientColorSpace::ProphotoRgb, + "rec2020" => GradientColorSpace::Rec2020, + "lab" => GradientColorSpace::Lab, + "oklab" => GradientColorSpace::Oklab, + "xyz" => GradientColorSpace::Xyz, + "xyz-d50" => GradientColorSpace::XyzD50, + "xyz-d65" => GradientColorSpace::XyzD65, + "hsl" => GradientColorSpace::Hsl, + "hwb" => GradientColorSpace::Hwb, + "lch" => GradientColorSpace::Lch, + "oklch" => GradientColorSpace::Oklch, + &_ => return Err(miette!("Invalid color-space: {in_str}")) + } + } else { + GradientColorSpace::Srgb + }; + + let interpolation = if in_part2 != None { + let in_str = in_part2.unwrap(); + match in_str { + "shorter" => HueInterpolation::Shorter, + "longer" => HueInterpolation::Longer, + "increasing" => HueInterpolation::Increasing, + "decreasing" => HueInterpolation::Decreasing, + &_ => return Err(miette!("Invalid hue-interpolation: {in_str}")) + } + } else { + HueInterpolation::Shorter + }; + + Ok( Self { color_space: color, hue_interpol: interpolation } ) + } +} + impl FromStr for Color { type Err = miette::Error; From 56d2e59720a0ded45bd2e82a92bde18c06b03bb8 Mon Sep 17 00:00:00 2001 From: Kiko Date: Sun, 7 Jul 2024 16:01:01 +0000 Subject: [PATCH 10/34] Update wiki/Configuration:-Layout.md Co-authored-by: Ivan Molodetskikh --- wiki/Configuration:-Layout.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiki/Configuration:-Layout.md b/wiki/Configuration:-Layout.md index fcf3d8f..0cea732 100644 --- a/wiki/Configuration:-Layout.md +++ b/wiki/Configuration:-Layout.md @@ -209,7 +209,7 @@ There's also a *deprecated* syntax for setting colors with four numbers represen Similarly to colors, you can set `active-gradient` and `inactive-gradient`, which will take precedence. -Gradients can be rendered the same as CSS [`linear-gradient(angle, from, to)`](https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/linear-gradient). +Gradients are rendered the same as CSS [`linear-gradient(angle, from, to)`](https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/linear-gradient). The angle works the same as in `linear-gradient`, and is optional, defaulting to `180` (top-to-bottom gradient). You can use any CSS linear-gradient tool on the web to set these up, like [this one](https://www.css-gradient.com/). From fc9ae7200a8555c76afc83eefb7dec06aacb7521 Mon Sep 17 00:00:00 2001 From: Kiko Date: Sun, 7 Jul 2024 16:22:32 +0000 Subject: [PATCH 11/34] Update Configuration:-Layout.md --- wiki/Configuration:-Layout.md | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/wiki/Configuration:-Layout.md b/wiki/Configuration:-Layout.md index 0cea732..f1010e5 100644 --- a/wiki/Configuration:-Layout.md +++ b/wiki/Configuration:-Layout.md @@ -222,16 +222,7 @@ layout { ``` Gradients can be rendered with different kinds of color interpolation, this doesen't mean that the arguments the gradient takes -are any different. Except for an optional `gradient-type` argument which can currently be: - -`gradient-type="css-linear"`(Default), - -`gradient-type="linear"`, - -`gradient-type="Oklab"`(Unimplemented), - -`gradient-type="Lch"` - +are any different. Except for an optional `in` argument which can take both a colorspace and a hue interpolation method if the color space is polar Gradients can be colored relative to windows individually (the default), or to the whole view of the workspace. To do that, set `relative-to="workspace-view"`. From 587df8e84f94edb8ec509afc91c11659a761f1f3 Mon Sep 17 00:00:00 2001 From: Kiko Date: Sun, 7 Jul 2024 16:42:15 +0000 Subject: [PATCH 12/34] Update Configuration:-Layout.md --- wiki/Configuration:-Layout.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wiki/Configuration:-Layout.md b/wiki/Configuration:-Layout.md index f1010e5..4cf3a56 100644 --- a/wiki/Configuration:-Layout.md +++ b/wiki/Configuration:-Layout.md @@ -221,8 +221,8 @@ layout { } ``` -Gradients can be rendered with different kinds of color interpolation, this doesen't mean that the arguments the gradient takes -are any different. Except for an optional `in` argument which can take both a colorspace and a hue interpolation method if the color space is polar +Gradients can be rendered with different kinds of color interpolation, this doesen't mean that the arguments the gradient takes are any different. +Except for an optional `in` argument which can take both a colorspace and a hue interpolation method if the color space is polar. Gradients can be colored relative to windows individually (the default), or to the whole view of the workspace. To do that, set `relative-to="workspace-view"`. From 2ba656509df9d10e97dc276361191904fe3d2bea Mon Sep 17 00:00:00 2001 From: K's Thinkpad Date: Mon, 8 Jul 2024 13:24:02 +0200 Subject: [PATCH 13/34] modified for better testing and errors --- niri-config/src/lib.rs | 57 +++++++------------ niri-visual-tests/src/cases/gradient_angle.rs | 3 +- niri-visual-tests/src/cases/gradient_area.rs | 3 +- niri-visual-tests/src/cases/mod.rs | 4 ++ niri-visual-tests/src/main.rs | 9 +++ src/layout/focus_ring.rs | 14 ++--- src/layout/tile.rs | 7 +-- src/render_helpers/border.rs | 20 +------ src/render_helpers/shaders/mod.rs | 5 +- src/window/mapped.rs | 7 +-- 10 files changed, 50 insertions(+), 79 deletions(-) diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs index 648e59d..98150b6 100644 --- a/niri-config/src/lib.rs +++ b/niri-config/src/lib.rs @@ -422,8 +422,8 @@ pub struct Gradient { pub angle: i16, #[knuffel(property, default)] pub relative_to: GradientRelativeTo, - #[knuffel(property, str)] - pub _in: GradientInterpolation, + #[knuffel(property(name="in"), str)] + pub in_: GradientInterpolation, } #[derive(knuffel::DecodeScalar, Debug, Default, Clone, Copy, PartialEq, Eq)] @@ -433,35 +433,22 @@ pub enum GradientRelativeTo { WorkspaceView, } -#[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)] +#[derive(Default, Debug, Clone, Copy, PartialEq)] pub struct GradientInterpolation { - #[knuffel(property, default)] pub color_space: GradientColorSpace, - #[knuffel(property, default)] pub hue_interpol: HueInterpolation } -#[derive(knuffel::DecodeScalar, Debug, Default, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] pub enum GradientColorSpace { #[default] Srgb, SrgbLinear, - DisplayP3, - A98Rgb, - ProphotoRgb, - Rec2020, - Lab, Oklab, - Xyz, - XyzD50, - XyzD65, - Hsl, - Hwb, - Lch, Oklch } -#[derive(knuffel::DecodeScalar, Debug, Default, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] pub enum HueInterpolation { #[default] Shorter, @@ -1447,24 +1434,14 @@ impl FromStr for GradientInterpolation { let mut iter = s.split_whitespace(); let in_part1 = iter.next(); let in_part2 = iter.next(); + let in_part3 = iter.next(); let color = if in_part1 != None { let in_str = in_part1.unwrap(); match in_str { "srgb" => GradientColorSpace::Srgb, "srgb-linear" => GradientColorSpace::SrgbLinear, - "display-p3" => GradientColorSpace::DisplayP3, - "a98-rgb" => GradientColorSpace::A98Rgb, - "prophoto-rgb" => GradientColorSpace::ProphotoRgb, - "rec2020" => GradientColorSpace::Rec2020, - "lab" => GradientColorSpace::Lab, "oklab" => GradientColorSpace::Oklab, - "xyz" => GradientColorSpace::Xyz, - "xyz-d50" => GradientColorSpace::XyzD50, - "xyz-d65" => GradientColorSpace::XyzD65, - "hsl" => GradientColorSpace::Hsl, - "hwb" => GradientColorSpace::Hwb, - "lch" => GradientColorSpace::Lch, "oklch" => GradientColorSpace::Oklch, &_ => return Err(miette!("Invalid color-space: {in_str}")) } @@ -1472,14 +1449,22 @@ impl FromStr for GradientInterpolation { GradientColorSpace::Srgb }; - let interpolation = if in_part2 != None { + let interpolation = if color == GradientColorSpace::Oklch && in_part2 != None { let in_str = in_part2.unwrap(); - match in_str { - "shorter" => HueInterpolation::Shorter, - "longer" => HueInterpolation::Longer, - "increasing" => HueInterpolation::Increasing, - "decreasing" => HueInterpolation::Decreasing, - &_ => return Err(miette!("Invalid hue-interpolation: {in_str}")) + if in_part3 == None || in_part3.unwrap() != "hue" { + return Err(miette!("Invalid hue-interpolation: {in_str} you may be missing 'hue' at the end.")) + } else if iter.next() == None { + match in_str { + "shorter" => HueInterpolation::Shorter, + "longer" => HueInterpolation::Longer, + "increasing" => HueInterpolation::Increasing, + "decreasing" => HueInterpolation::Decreasing, + &_ => return Err(miette!("Invalid hue-interpolation: {in_str}")) + } + } else { + // this is a placeholder and should be changed if anything is added to in for + // gradients + return Err(miette!("there seems to be a value after ’hue’ at ’in’ ")) } } else { HueInterpolation::Shorter diff --git a/niri-visual-tests/src/cases/gradient_angle.rs b/niri-visual-tests/src/cases/gradient_angle.rs index 7d0b754..08a7f4d 100644 --- a/niri-visual-tests/src/cases/gradient_angle.rs +++ b/niri-visual-tests/src/cases/gradient_angle.rs @@ -4,7 +4,7 @@ use std::time::Duration; use niri::animation::ANIMATION_SLOWDOWN; use niri::render_helpers::border::BorderRenderElement; -use niri_config::CornerRadius; +use niri_config::{CornerRadius, GradientInterpolation}; use smithay::backend::renderer::element::RenderElement; use smithay::backend::renderer::gles::GlesRenderer; use smithay::utils::{Logical, Physical, Rectangle, Size}; @@ -64,6 +64,7 @@ impl TestCase for GradientAngle { [BorderRenderElement::new( area.size, Rectangle::from_loc_and_size((0., 0.), area.size), + GradientInterpolation::default(), [1., 0., 0., 1.], [0., 1., 0., 1.], self.angle - FRAC_PI_2, diff --git a/niri-visual-tests/src/cases/gradient_area.rs b/niri-visual-tests/src/cases/gradient_area.rs index 13f50d4..1c8a457 100644 --- a/niri-visual-tests/src/cases/gradient_area.rs +++ b/niri-visual-tests/src/cases/gradient_area.rs @@ -5,7 +5,7 @@ use std::time::Duration; use niri::animation::ANIMATION_SLOWDOWN; use niri::layout::focus_ring::FocusRing; use niri::render_helpers::border::BorderRenderElement; -use niri_config::{Color, CornerRadius, FloatOrInt}; +use niri_config::{Color, CornerRadius, FloatOrInt, GradientInterpolation}; use smithay::backend::renderer::element::RenderElement; use smithay::backend::renderer::gles::GlesRenderer; use smithay::utils::{Logical, Physical, Point, Rectangle, Size}; @@ -104,6 +104,7 @@ impl TestCase for GradientArea { [BorderRenderElement::new( area.size, g_area, + GradientInterpolation::default(), [1., 0., 0., 1.], [0., 1., 0., 1.], FRAC_PI_4, diff --git a/niri-visual-tests/src/cases/mod.rs b/niri-visual-tests/src/cases/mod.rs index 25aa1e3..8e3962f 100644 --- a/niri-visual-tests/src/cases/mod.rs +++ b/niri-visual-tests/src/cases/mod.rs @@ -6,6 +6,10 @@ use smithay::utils::{Physical, Size}; pub mod gradient_angle; pub mod gradient_area; +pub mod gradient_srgb; +pub mod gradient_srgblinear; +pub mod gradient_oklab; +pub mod gradient_oklch_shorter; pub mod layout; pub mod tile; pub mod window; diff --git a/niri-visual-tests/src/main.rs b/niri-visual-tests/src/main.rs index 771c501..b442be7 100644 --- a/niri-visual-tests/src/main.rs +++ b/niri-visual-tests/src/main.rs @@ -18,6 +18,10 @@ use tracing_subscriber::EnvFilter; use crate::cases::gradient_angle::GradientAngle; use crate::cases::gradient_area::GradientArea; +use crate::cases::gradient_srgb::GradientSrgb; +use crate::cases::gradient_srgblinear::GradientSrgbLinear; +use crate::cases::gradient_oklab::GradientOklab; +use crate::cases::gradient_oklch_shorter::GradientOklch; use crate::cases::layout::Layout; use crate::cases::TestCase; @@ -112,6 +116,11 @@ fn build_ui(app: &adw::Application) { s.add(GradientAngle::new, "Gradient - Angle"); s.add(GradientArea::new, "Gradient - Area"); + s.add(GradientSrgb::new, "Gradient - Srgb"); + s.add(GradientSrgbLinear::new, "Gradient - SrgbLinear"); + s.add(GradientOklab::new, "Gradient - Oklab"); + s.add(GradientOklch::new, "Gradient - Oklch"); + let content_headerbar = adw::HeaderBar::new(); diff --git a/src/layout/focus_ring.rs b/src/layout/focus_ring.rs index 7d3dd29..af1af21 100644 --- a/src/layout/focus_ring.rs +++ b/src/layout/focus_ring.rs @@ -1,7 +1,7 @@ use std::iter::zip; use arrayvec::ArrayVec; -use niri_config::{CornerRadius, Gradient, GradientRelativeTo, GradientInterpolation, GradientColorSpace, HueInterpolation}; +use niri_config::{CornerRadius, Gradient, GradientRelativeTo, GradientInterpolation}; use smithay::backend::renderer::element::Kind; use smithay::utils::{Logical, Point, Rectangle, Size}; @@ -91,10 +91,7 @@ impl FocusRing { to: color, angle: 0, relative_to: GradientRelativeTo::Window, - _in: GradientInterpolation { - color_space: GradientColorSpace::Srgb, - hue_interpol: HueInterpolation::Shorter - } + in_: GradientInterpolation::default() }); let full_rect = Rectangle::from_loc_and_size((-width, -width), self.full_size); @@ -103,9 +100,6 @@ impl FocusRing { GradientRelativeTo::WorkspaceView => view_rect, }; - let gradient_format = gradient._in; - - let rounded_corner_border_width = if self.is_border { // HACK: increase the border width used for the inner rounded corners a tiny bit to // reduce background bleed. @@ -185,7 +179,7 @@ impl FocusRing { border.update( size, Rectangle::from_loc_and_size(gradient_area.loc - loc, gradient_area.size), - gradient_format, + gradient.in_, gradient.from.into(), gradient.to.into(), ((gradient.angle as f32) - 90.).to_radians(), @@ -206,7 +200,7 @@ impl FocusRing { gradient_area.loc - self.locations[0], gradient_area.size, ), - gradient_format, + gradient.in_, gradient.from.into(), gradient.to.into(), ((gradient.angle as f32) - 90.).to_radians(), diff --git a/src/layout/tile.rs b/src/layout/tile.rs index 8c563bd..ec98525 100644 --- a/src/layout/tile.rs +++ b/src/layout/tile.rs @@ -1,7 +1,7 @@ use std::rc::Rc; use std::time::Duration; -use niri_config::{CornerRadius, GradientInterpolation, GradientColorSpace, HueInterpolation}; +use niri_config::{CornerRadius, GradientInterpolation}; use smithay::backend::allocator::Fourcc; use smithay::backend::renderer::element::{Element, Kind}; use smithay::backend::renderer::gles::GlesRenderer; @@ -757,10 +757,7 @@ impl Tile { return BorderRenderElement::new( geo.size, Rectangle::from_loc_and_size((0., 0.), geo.size), - GradientInterpolation{ - color_space: GradientColorSpace::Srgb, - hue_interpol: HueInterpolation::Shorter - }, + GradientInterpolation::default(), elem.color(), elem.color(), 0., diff --git a/src/render_helpers/border.rs b/src/render_helpers/border.rs index 5bb645f..94388fe 100644 --- a/src/render_helpers/border.rs +++ b/src/render_helpers/border.rs @@ -80,10 +80,7 @@ impl BorderRenderElement { params: Parameters { size: Default::default(), gradient_area: Default::default(), - gradient_format: GradientInterpolation { - color_space: GradientColorSpace::Srgb, - hue_interpol: HueInterpolation::Shorter - }, + gradient_format: GradientInterpolation::default(), color_from: Default::default(), color_to: Default::default(), angle: 0., @@ -175,19 +172,8 @@ impl BorderRenderElement { let colorspace = match gradient_format.color_space { GradientColorSpace::Srgb => 0., GradientColorSpace::SrgbLinear => 1., - GradientColorSpace::DisplayP3 => 2., - GradientColorSpace::A98Rgb => 3., - GradientColorSpace::ProphotoRgb => 4., - GradientColorSpace::Rec2020 => 5., - GradientColorSpace::Lab => 6., - GradientColorSpace::Oklab => 7., - GradientColorSpace::Xyz => 8., - GradientColorSpace::XyzD50 => 9., - GradientColorSpace::XyzD65 => 10., - GradientColorSpace::Hsl => 11., - GradientColorSpace::Hwb => 12., - GradientColorSpace::Lch => 13., - GradientColorSpace::Oklch => 14., + GradientColorSpace::Oklab => 2., + GradientColorSpace::Oklch => 3., }; let hue_interpolation = match gradient_format.hue_interpol { diff --git a/src/render_helpers/shaders/mod.rs b/src/render_helpers/shaders/mod.rs index 7896c0a..91ba32d 100644 --- a/src/render_helpers/shaders/mod.rs +++ b/src/render_helpers/shaders/mod.rs @@ -68,10 +68,7 @@ impl Shaders { }) .ok(); - let resize = compile_resize_program( - renderer, - include_str!("resize.frag") - ) + let resize = compile_resize_program(renderer, include_str!("resize.frag")) .map_err(|err| { warn!("error compiling resize shader: {err:?}"); }) diff --git a/src/window/mapped.rs b/src/window/mapped.rs index 2aa1202..74cd258 100644 --- a/src/window/mapped.rs +++ b/src/window/mapped.rs @@ -2,7 +2,7 @@ use std::cell::{Cell, RefCell}; use std::cmp::{max, min}; use std::time::Duration; -use niri_config::{CornerRadius, GradientColorSpace, GradientInterpolation, HueInterpolation, WindowRule}; +use niri_config::{CornerRadius, GradientInterpolation, WindowRule}; use smithay::backend::renderer::element::surface::render_elements_from_surface_tree; use smithay::backend::renderer::element::{Id, Kind}; use smithay::backend::renderer::gles::GlesRenderer; @@ -289,10 +289,7 @@ impl Mapped { return BorderRenderElement::new( geo.size, Rectangle::from_loc_and_size((0., 0.), geo.size), - GradientInterpolation{ - color_space: GradientColorSpace::Srgb, - hue_interpol: HueInterpolation::Shorter - }, + GradientInterpolation::default(), elem.color(), elem.color(), 0., From f3ebb1e458e6193676230986048970951c3c53c4 Mon Sep 17 00:00:00 2001 From: K's Thinkpad Date: Mon, 8 Jul 2024 13:24:56 +0200 Subject: [PATCH 14/34] added the testing files for different colorspaces --- niri-visual-tests/src/cases/gradient_oklab.rs | 86 +++++++++++++++++++ .../src/cases/gradient_oklch_shorter.rs | 86 +++++++++++++++++++ niri-visual-tests/src/cases/gradient_srgb.rs | 85 ++++++++++++++++++ .../src/cases/gradient_srgblinear.rs | 86 +++++++++++++++++++ 4 files changed, 343 insertions(+) create mode 100644 niri-visual-tests/src/cases/gradient_oklab.rs create mode 100644 niri-visual-tests/src/cases/gradient_oklch_shorter.rs create mode 100644 niri-visual-tests/src/cases/gradient_srgb.rs create mode 100644 niri-visual-tests/src/cases/gradient_srgblinear.rs diff --git a/niri-visual-tests/src/cases/gradient_oklab.rs b/niri-visual-tests/src/cases/gradient_oklab.rs new file mode 100644 index 0000000..cc19326 --- /dev/null +++ b/niri-visual-tests/src/cases/gradient_oklab.rs @@ -0,0 +1,86 @@ + +use std::sync::atomic::Ordering; +use std::time::Duration; + +use niri::animation::ANIMATION_SLOWDOWN; +use niri::render_helpers::border::BorderRenderElement; +use niri_config::{CornerRadius, GradientInterpolation, HueInterpolation, GradientColorSpace}; +use smithay::backend::renderer::element::RenderElement; +use smithay::backend::renderer::gles::GlesRenderer; +use smithay::utils::{Logical, Physical, Rectangle, Size}; + +use super::TestCase; + +pub struct GradientOklab { + time: f32, + prev_time: Duration, + gradient_format: GradientInterpolation, +} + +impl GradientOklab { + pub fn new(_size: Size) -> Self { + Self { + time: 0., + prev_time: Duration::ZERO, + gradient_format: GradientInterpolation{ + color_space: GradientColorSpace::Oklab, + hue_interpol: HueInterpolation::Shorter + } + } + } +} + +impl TestCase for GradientOklab { + fn are_animations_ongoing(&self) -> bool { + true + } + + fn advance_animations(&mut self, current_time: Duration) { + let mut delta = if self.prev_time.is_zero() { + Duration::ZERO + } else { + current_time.saturating_sub(self.prev_time) + }; + self.prev_time = current_time; + + let slowdown = ANIMATION_SLOWDOWN.load(Ordering::SeqCst); + if slowdown == 0. { + delta = Duration::ZERO; + } else { + delta = delta.div_f64(slowdown); + } + + self.time = delta.as_secs_f32() ; + + if self.time >= 26.9 { + self.time = 0.0 + } + } + + fn render( + &mut self, + _renderer: &mut GlesRenderer, + size: Size, + ) -> Vec>> { + let (a, b) = (size.w / 6, size.h / 3); + let size = (size.w - a * 2, size.h - b * 2); + let area = Rectangle::from_loc_and_size((a, b), size).to_f64(); + + [BorderRenderElement::new( + area.size, + Rectangle::from_loc_and_size((0., 0.), area.size), + self.gradient_format, + [1., 0., 0., 1.], + [0., 1., 0., 1.], + 0., + Rectangle::from_loc_and_size((0., 0.), area.size), + 0., + CornerRadius::default(), + 1., + ) + .with_location(area.loc)] + .into_iter() + .map(|elem| Box::new(elem) as _) + .collect() + } +} diff --git a/niri-visual-tests/src/cases/gradient_oklch_shorter.rs b/niri-visual-tests/src/cases/gradient_oklch_shorter.rs new file mode 100644 index 0000000..95f763c --- /dev/null +++ b/niri-visual-tests/src/cases/gradient_oklch_shorter.rs @@ -0,0 +1,86 @@ + +use std::sync::atomic::Ordering; +use std::time::Duration; + +use niri::animation::ANIMATION_SLOWDOWN; +use niri::render_helpers::border::BorderRenderElement; +use niri_config::{CornerRadius, GradientInterpolation, HueInterpolation, GradientColorSpace}; +use smithay::backend::renderer::element::RenderElement; +use smithay::backend::renderer::gles::GlesRenderer; +use smithay::utils::{Logical, Physical, Rectangle, Size}; + +use super::TestCase; + +pub struct GradientOklch { + time: f32, + prev_time: Duration, + gradient_format: GradientInterpolation, +} + +impl GradientOklch { + pub fn new(_size: Size) -> Self { + Self { + time: 0., + prev_time: Duration::ZERO, + gradient_format: GradientInterpolation{ + color_space: GradientColorSpace::Oklch, + hue_interpol: HueInterpolation::Shorter + } + } + } +} + +impl TestCase for GradientOklch { + fn are_animations_ongoing(&self) -> bool { + true + } + + fn advance_animations(&mut self, current_time: Duration) { + let mut delta = if self.prev_time.is_zero() { + Duration::ZERO + } else { + current_time.saturating_sub(self.prev_time) + }; + self.prev_time = current_time; + + let slowdown = ANIMATION_SLOWDOWN.load(Ordering::SeqCst); + if slowdown == 0. { + delta = Duration::ZERO; + } else { + delta = delta.div_f64(slowdown); + } + + self.time = delta.as_secs_f32() ; + + if self.time >= 26.9 { + self.time = 0.0 + } + } + + fn render( + &mut self, + _renderer: &mut GlesRenderer, + size: Size, + ) -> Vec>> { + let (a, b) = (size.w / 6, size.h / 3); + let size = (size.w - a * 2, size.h - b * 2); + let area = Rectangle::from_loc_and_size((a, b), size).to_f64(); + + [BorderRenderElement::new( + area.size, + Rectangle::from_loc_and_size((0., 0.), area.size), + self.gradient_format, + [1., 0., 0., 1.], + [0., 1., 0., 1.], + 0., + Rectangle::from_loc_and_size((0., 0.), area.size), + 0., + CornerRadius::default(), + 1., + ) + .with_location(area.loc)] + .into_iter() + .map(|elem| Box::new(elem) as _) + .collect() + } +} diff --git a/niri-visual-tests/src/cases/gradient_srgb.rs b/niri-visual-tests/src/cases/gradient_srgb.rs new file mode 100644 index 0000000..7e8a1ed --- /dev/null +++ b/niri-visual-tests/src/cases/gradient_srgb.rs @@ -0,0 +1,85 @@ +use std::sync::atomic::Ordering; +use std::time::Duration; + +use niri::animation::ANIMATION_SLOWDOWN; +use niri::render_helpers::border::BorderRenderElement; +use niri_config::{CornerRadius, GradientInterpolation, HueInterpolation, GradientColorSpace}; +use smithay::backend::renderer::element::RenderElement; +use smithay::backend::renderer::gles::GlesRenderer; +use smithay::utils::{Logical, Physical, Rectangle, Size}; + +use super::TestCase; + +pub struct GradientSrgb { + time: f32, + prev_time: Duration, + gradient_format: GradientInterpolation, +} + +impl GradientSrgb { + pub fn new(_size: Size) -> Self { + Self { + time: 0., + prev_time: Duration::ZERO, + gradient_format: GradientInterpolation{ + color_space: GradientColorSpace::Srgb, + hue_interpol: HueInterpolation::Shorter + } + } + } +} + +impl TestCase for GradientSrgb { + fn are_animations_ongoing(&self) -> bool { + true + } + + fn advance_animations(&mut self, current_time: Duration) { + let mut delta = if self.prev_time.is_zero() { + Duration::ZERO + } else { + current_time.saturating_sub(self.prev_time) + }; + self.prev_time = current_time; + + let slowdown = ANIMATION_SLOWDOWN.load(Ordering::SeqCst); + if slowdown == 0. { + delta = Duration::ZERO; + } else { + delta = delta.div_f64(slowdown); + } + + self.time = delta.as_secs_f32() ; + + if self.time >= 26.9 { + self.time = 0.0 + } + } + + fn render( + &mut self, + _renderer: &mut GlesRenderer, + size: Size, + ) -> Vec>> { + let (a, b) = (size.w / 6, size.h / 3); + let size = (size.w - a * 2, size.h - b * 2); + let area = Rectangle::from_loc_and_size((a, b), size).to_f64(); + + [BorderRenderElement::new( + area.size, + Rectangle::from_loc_and_size((0., 0.), area.size), + self.gradient_format, + [1., 0., 0., 1.], + [0., 1., 0., 1.], + 0., + Rectangle::from_loc_and_size((0., 0.), area.size), + 0., + CornerRadius::default(), + 1., + ) + .with_location(area.loc)] + .into_iter() + .map(|elem| Box::new(elem) as _) + .collect() + } +} diff --git a/niri-visual-tests/src/cases/gradient_srgblinear.rs b/niri-visual-tests/src/cases/gradient_srgblinear.rs new file mode 100644 index 0000000..f7d2145 --- /dev/null +++ b/niri-visual-tests/src/cases/gradient_srgblinear.rs @@ -0,0 +1,86 @@ + +use std::sync::atomic::Ordering; +use std::time::Duration; + +use niri::animation::ANIMATION_SLOWDOWN; +use niri::render_helpers::border::BorderRenderElement; +use niri_config::{CornerRadius, GradientInterpolation, HueInterpolation, GradientColorSpace}; +use smithay::backend::renderer::element::RenderElement; +use smithay::backend::renderer::gles::GlesRenderer; +use smithay::utils::{Logical, Physical, Rectangle, Size}; + +use super::TestCase; + +pub struct GradientSrgbLinear { + time: f32, + prev_time: Duration, + gradient_format: GradientInterpolation, +} + +impl GradientSrgbLinear { + pub fn new(_size: Size) -> Self { + Self { + time: 0., + prev_time: Duration::ZERO, + gradient_format: GradientInterpolation{ + color_space: GradientColorSpace::SrgbLinear, + hue_interpol: HueInterpolation::Shorter + } + } + } +} + +impl TestCase for GradientSrgbLinear { + fn are_animations_ongoing(&self) -> bool { + true + } + + fn advance_animations(&mut self, current_time: Duration) { + let mut delta = if self.prev_time.is_zero() { + Duration::ZERO + } else { + current_time.saturating_sub(self.prev_time) + }; + self.prev_time = current_time; + + let slowdown = ANIMATION_SLOWDOWN.load(Ordering::SeqCst); + if slowdown == 0. { + delta = Duration::ZERO; + } else { + delta = delta.div_f64(slowdown); + } + + self.time = delta.as_secs_f32() ; + + if self.time >= 26.9 { + self.time = 0.0 + } + } + + fn render( + &mut self, + _renderer: &mut GlesRenderer, + size: Size, + ) -> Vec>> { + let (a, b) = (size.w / 6, size.h / 3); + let size = (size.w - a * 2, size.h - b * 2); + let area = Rectangle::from_loc_and_size((a, b), size).to_f64(); + + [BorderRenderElement::new( + area.size, + Rectangle::from_loc_and_size((0., 0.), area.size), + self.gradient_format, + [1., 0., 0., 1.], + [0., 1., 0., 1.], + 0., + Rectangle::from_loc_and_size((0., 0.), area.size), + 0., + CornerRadius::default(), + 1., + ) + .with_location(area.loc)] + .into_iter() + .map(|elem| Box::new(elem) as _) + .collect() + } +} From b93bde2fb6af4205096196aa3f3dea0d3f3f3a33 Mon Sep 17 00:00:00 2001 From: K's Thinkpad Date: Mon, 8 Jul 2024 14:06:23 +0200 Subject: [PATCH 15/34] better error msg --- niri-config/src/lib.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs index 29a405b..b07db58 100644 --- a/niri-config/src/lib.rs +++ b/niri-config/src/lib.rs @@ -1465,8 +1465,11 @@ impl FromStr for GradientInterpolation { GradientColorSpace::Srgb }; - let interpolation = if color == GradientColorSpace::Oklch && in_part2 != None { + let interpolation = if in_part2 != None { let in_str = in_part2.unwrap(); + if color != GradientColorSpace::Oklch { + return Err(miette!("There's a value: {in_str} after a non polar colorspace")) + } if in_part3 == None || in_part3.unwrap() != "hue" { return Err(miette!("Invalid hue-interpolation: {in_str} you may be missing 'hue' at the end.")) } else if iter.next() == None { @@ -1480,7 +1483,7 @@ impl FromStr for GradientInterpolation { } else { // this is a placeholder and should be changed if anything is added to in for // gradients - return Err(miette!("there seems to be a value after ’hue’ at ’in’ ")) + return Err(miette!("Theres a missing indicator ’hue’ from ’in’ ")) } } else { HueInterpolation::Shorter From 85f3169b56a652a8d24d517b181b8933d87523a7 Mon Sep 17 00:00:00 2001 From: K's Thinkpad Date: Mon, 8 Jul 2024 14:28:21 +0200 Subject: [PATCH 16/34] more tests for polare colorspace --- niri-visual-tests/src/cases/gradient_oklch_shorter.rs | 6 +++--- niri-visual-tests/src/cases/mod.rs | 3 +++ niri-visual-tests/src/main.rs | 11 ++++++++--- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/niri-visual-tests/src/cases/gradient_oklch_shorter.rs b/niri-visual-tests/src/cases/gradient_oklch_shorter.rs index 95f763c..c54386d 100644 --- a/niri-visual-tests/src/cases/gradient_oklch_shorter.rs +++ b/niri-visual-tests/src/cases/gradient_oklch_shorter.rs @@ -11,13 +11,13 @@ use smithay::utils::{Logical, Physical, Rectangle, Size}; use super::TestCase; -pub struct GradientOklch { +pub struct GradientOklchShorter { time: f32, prev_time: Duration, gradient_format: GradientInterpolation, } -impl GradientOklch { +impl GradientOklchShorter { pub fn new(_size: Size) -> Self { Self { time: 0., @@ -30,7 +30,7 @@ impl GradientOklch { } } -impl TestCase for GradientOklch { +impl TestCase for GradientOklchShorter { fn are_animations_ongoing(&self) -> bool { true } diff --git a/niri-visual-tests/src/cases/mod.rs b/niri-visual-tests/src/cases/mod.rs index 8e3962f..27fba10 100644 --- a/niri-visual-tests/src/cases/mod.rs +++ b/niri-visual-tests/src/cases/mod.rs @@ -10,6 +10,9 @@ pub mod gradient_srgb; pub mod gradient_srgblinear; pub mod gradient_oklab; pub mod gradient_oklch_shorter; +pub mod gradient_oklch_longer; +pub mod gradient_oklch_increasing; +pub mod gradient_oklch_decreasing; pub mod layout; pub mod tile; pub mod window; diff --git a/niri-visual-tests/src/main.rs b/niri-visual-tests/src/main.rs index b442be7..5aca63f 100644 --- a/niri-visual-tests/src/main.rs +++ b/niri-visual-tests/src/main.rs @@ -21,7 +21,10 @@ use crate::cases::gradient_area::GradientArea; use crate::cases::gradient_srgb::GradientSrgb; use crate::cases::gradient_srgblinear::GradientSrgbLinear; use crate::cases::gradient_oklab::GradientOklab; -use crate::cases::gradient_oklch_shorter::GradientOklch; +use crate::cases::gradient_oklch_shorter::GradientOklchShorter; +use crate::cases::gradient_oklch_longer::GradientOklchLonger; +use crate::cases::gradient_oklch_increasing::GradientOklchIncreasing; +use crate::cases::gradient_oklch_decreasing::GradientOklchDecreasing; use crate::cases::layout::Layout; use crate::cases::TestCase; @@ -119,8 +122,10 @@ fn build_ui(app: &adw::Application) { s.add(GradientSrgb::new, "Gradient - Srgb"); s.add(GradientSrgbLinear::new, "Gradient - SrgbLinear"); s.add(GradientOklab::new, "Gradient - Oklab"); - s.add(GradientOklch::new, "Gradient - Oklch"); - + s.add(GradientOklchShorter::new, "Gradient - Oklch Shorter"); + s.add(GradientOklchLonger::new, "Gradient - Oklch Longer"); + s.add(GradientOklchIncreasing::new, "Gradient - Oklch Increasing"); + s.add(GradientOklchDecreasing::new, "Gradient - Oklch Decreasing"); let content_headerbar = adw::HeaderBar::new(); From 71ab2894787d6df42c0d2e76ea12abd35cc14797 Mon Sep 17 00:00:00 2001 From: K's Thinkpad Date: Mon, 8 Jul 2024 14:28:49 +0200 Subject: [PATCH 17/34] =?UTF-8?q?weeeeeeeeeeeeeeeeeeeeeeeeeeee=20(jk=20its?= =?UTF-8?q?=20just=20more=20tests=20and=20a=2039=C2=B0=20fever)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/cases/gradient_oklch_decreasing.rs | 86 +++++++++++++++++++ .../src/cases/gradient_oklch_increasing.rs | 86 +++++++++++++++++++ .../src/cases/gradient_oklch_longer.rs | 86 +++++++++++++++++++ 3 files changed, 258 insertions(+) create mode 100644 niri-visual-tests/src/cases/gradient_oklch_decreasing.rs create mode 100644 niri-visual-tests/src/cases/gradient_oklch_increasing.rs create mode 100644 niri-visual-tests/src/cases/gradient_oklch_longer.rs diff --git a/niri-visual-tests/src/cases/gradient_oklch_decreasing.rs b/niri-visual-tests/src/cases/gradient_oklch_decreasing.rs new file mode 100644 index 0000000..398fa86 --- /dev/null +++ b/niri-visual-tests/src/cases/gradient_oklch_decreasing.rs @@ -0,0 +1,86 @@ + +use std::sync::atomic::Ordering; +use std::time::Duration; + +use niri::animation::ANIMATION_SLOWDOWN; +use niri::render_helpers::border::BorderRenderElement; +use niri_config::{CornerRadius, GradientInterpolation, HueInterpolation, GradientColorSpace}; +use smithay::backend::renderer::element::RenderElement; +use smithay::backend::renderer::gles::GlesRenderer; +use smithay::utils::{Logical, Physical, Rectangle, Size}; + +use super::TestCase; + +pub struct GradientOklchDecreasing { + time: f32, + prev_time: Duration, + gradient_format: GradientInterpolation, +} + +impl GradientOklchDecreasing { + pub fn new(_size: Size) -> Self { + Self { + time: 0., + prev_time: Duration::ZERO, + gradient_format: GradientInterpolation{ + color_space: GradientColorSpace::Oklch, + hue_interpol: HueInterpolation::Decreasing + } + } + } +} + +impl TestCase for GradientOklchDecreasing { + fn are_animations_ongoing(&self) -> bool { + true + } + + fn advance_animations(&mut self, current_time: Duration) { + let mut delta = if self.prev_time.is_zero() { + Duration::ZERO + } else { + current_time.saturating_sub(self.prev_time) + }; + self.prev_time = current_time; + + let slowdown = ANIMATION_SLOWDOWN.load(Ordering::SeqCst); + if slowdown == 0. { + delta = Duration::ZERO; + } else { + delta = delta.div_f64(slowdown); + } + + self.time = delta.as_secs_f32() ; + + if self.time >= 26.9 { + self.time = 0.0 + } + } + + fn render( + &mut self, + _renderer: &mut GlesRenderer, + size: Size, + ) -> Vec>> { + let (a, b) = (size.w / 6, size.h / 3); + let size = (size.w - a * 2, size.h - b * 2); + let area = Rectangle::from_loc_and_size((a, b), size).to_f64(); + + [BorderRenderElement::new( + area.size, + Rectangle::from_loc_and_size((0., 0.), area.size), + self.gradient_format, + [1., 0., 0., 1.], + [0., 1., 0., 1.], + 0., + Rectangle::from_loc_and_size((0., 0.), area.size), + 0., + CornerRadius::default(), + 1., + ) + .with_location(area.loc)] + .into_iter() + .map(|elem| Box::new(elem) as _) + .collect() + } +} diff --git a/niri-visual-tests/src/cases/gradient_oklch_increasing.rs b/niri-visual-tests/src/cases/gradient_oklch_increasing.rs new file mode 100644 index 0000000..4e5114f --- /dev/null +++ b/niri-visual-tests/src/cases/gradient_oklch_increasing.rs @@ -0,0 +1,86 @@ + +use std::sync::atomic::Ordering; +use std::time::Duration; + +use niri::animation::ANIMATION_SLOWDOWN; +use niri::render_helpers::border::BorderRenderElement; +use niri_config::{CornerRadius, GradientInterpolation, HueInterpolation, GradientColorSpace}; +use smithay::backend::renderer::element::RenderElement; +use smithay::backend::renderer::gles::GlesRenderer; +use smithay::utils::{Logical, Physical, Rectangle, Size}; + +use super::TestCase; + +pub struct GradientOklchIncreasing { + time: f32, + prev_time: Duration, + gradient_format: GradientInterpolation, +} + +impl GradientOklchIncreasing { + pub fn new(_size: Size) -> Self { + Self { + time: 0., + prev_time: Duration::ZERO, + gradient_format: GradientInterpolation{ + color_space: GradientColorSpace::Oklch, + hue_interpol: HueInterpolation::Increasing + } + } + } +} + +impl TestCase for GradientOklchIncreasing { + fn are_animations_ongoing(&self) -> bool { + true + } + + fn advance_animations(&mut self, current_time: Duration) { + let mut delta = if self.prev_time.is_zero() { + Duration::ZERO + } else { + current_time.saturating_sub(self.prev_time) + }; + self.prev_time = current_time; + + let slowdown = ANIMATION_SLOWDOWN.load(Ordering::SeqCst); + if slowdown == 0. { + delta = Duration::ZERO; + } else { + delta = delta.div_f64(slowdown); + } + + self.time = delta.as_secs_f32() ; + + if self.time >= 26.9 { + self.time = 0.0 + } + } + + fn render( + &mut self, + _renderer: &mut GlesRenderer, + size: Size, + ) -> Vec>> { + let (a, b) = (size.w / 6, size.h / 3); + let size = (size.w - a * 2, size.h - b * 2); + let area = Rectangle::from_loc_and_size((a, b), size).to_f64(); + + [BorderRenderElement::new( + area.size, + Rectangle::from_loc_and_size((0., 0.), area.size), + self.gradient_format, + [1., 0., 0., 1.], + [0., 1., 0., 1.], + 0., + Rectangle::from_loc_and_size((0., 0.), area.size), + 0., + CornerRadius::default(), + 1., + ) + .with_location(area.loc)] + .into_iter() + .map(|elem| Box::new(elem) as _) + .collect() + } +} diff --git a/niri-visual-tests/src/cases/gradient_oklch_longer.rs b/niri-visual-tests/src/cases/gradient_oklch_longer.rs new file mode 100644 index 0000000..2243a5e --- /dev/null +++ b/niri-visual-tests/src/cases/gradient_oklch_longer.rs @@ -0,0 +1,86 @@ + +use std::sync::atomic::Ordering; +use std::time::Duration; + +use niri::animation::ANIMATION_SLOWDOWN; +use niri::render_helpers::border::BorderRenderElement; +use niri_config::{CornerRadius, GradientInterpolation, HueInterpolation, GradientColorSpace}; +use smithay::backend::renderer::element::RenderElement; +use smithay::backend::renderer::gles::GlesRenderer; +use smithay::utils::{Logical, Physical, Rectangle, Size}; + +use super::TestCase; + +pub struct GradientOklchLonger { + time: f32, + prev_time: Duration, + gradient_format: GradientInterpolation, +} + +impl GradientOklchLonger { + pub fn new(_size: Size) -> Self { + Self { + time: 0., + prev_time: Duration::ZERO, + gradient_format: GradientInterpolation{ + color_space: GradientColorSpace::Oklch, + hue_interpol: HueInterpolation::Longer + } + } + } +} + +impl TestCase for GradientOklchLonger { + fn are_animations_ongoing(&self) -> bool { + true + } + + fn advance_animations(&mut self, current_time: Duration) { + let mut delta = if self.prev_time.is_zero() { + Duration::ZERO + } else { + current_time.saturating_sub(self.prev_time) + }; + self.prev_time = current_time; + + let slowdown = ANIMATION_SLOWDOWN.load(Ordering::SeqCst); + if slowdown == 0. { + delta = Duration::ZERO; + } else { + delta = delta.div_f64(slowdown); + } + + self.time = delta.as_secs_f32() ; + + if self.time >= 26.9 { + self.time = 0.0 + } + } + + fn render( + &mut self, + _renderer: &mut GlesRenderer, + size: Size, + ) -> Vec>> { + let (a, b) = (size.w / 6, size.h / 3); + let size = (size.w - a * 2, size.h - b * 2); + let area = Rectangle::from_loc_and_size((a, b), size).to_f64(); + + [BorderRenderElement::new( + area.size, + Rectangle::from_loc_and_size((0., 0.), area.size), + self.gradient_format, + [1., 0., 0., 1.], + [0., 1., 0., 1.], + 0., + Rectangle::from_loc_and_size((0., 0.), area.size), + 0., + CornerRadius::default(), + 1., + ) + .with_location(area.loc)] + .into_iter() + .map(|elem| Box::new(elem) as _) + .collect() + } +} From daf134883449bda7188dd664981ab1ddc2a128b2 Mon Sep 17 00:00:00 2001 From: K's Thinkpad Date: Mon, 8 Jul 2024 17:26:17 +0200 Subject: [PATCH 18/34] srgb-linear gradient was bad i made it good (call me rgbeesus) --- src/render_helpers/shaders/border.frag | 48 +++++++++++++++++--------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/src/render_helpers/shaders/border.frag b/src/render_helpers/shaders/border.frag index a3b9684..598012a 100644 --- a/src/render_helpers/shaders/border.frag +++ b/src/render_helpers/shaders/border.frag @@ -23,21 +23,19 @@ uniform vec2 geo_size; uniform vec4 outer_radius; uniform float border_width; -vec4 srgb_to_linear(vec4 color) { - return vec4( - (color.rgb / color.aaa) * (color.rgb / color.aaa), - color.a - ); +float srgb_to_linear(float color) { + return + color <= 0.04045 ? + color / 12.92 : + pow((color + 0.055) / 1.055, 2.4) ; } -vec4 linear_to_srgb(vec4 color) { - return vec4( - sqrt(color.r) * color.a, - sqrt(color.g) * color.a, - sqrt(color.b) * color.a, - color.a - ); -} +float linear_to_srgb(float color) { + return + color <= 0.0031308 ? + color * 12.92 : + pow(color * 1.055, 1.0 / 2.4) - 0.055 ; +} vec4 color_mix(vec4 color1, vec4 color2, float color_ratio) { @@ -47,8 +45,18 @@ vec4 color_mix(vec4 color1, vec4 color2, float color_ratio) { vec4 color_out; - color1 = srgb_to_linear(color1); - color2 = srgb_to_linear(color2); + color1.rgb = color1.rgb / color1.a; + color2.rgb = color2.rgb / color2.a; + + color1.rgb = vec3( + srgb_to_linear(color1.r), + srgb_to_linear(color1.g), + srgb_to_linear(color1.b)); + + color2.rgb = vec3( + srgb_to_linear(color2.r), + srgb_to_linear(color2.g), + srgb_to_linear(color2.b)); if (colorspace == 1.0) { // srgb-linear color_out = mix( @@ -58,13 +66,19 @@ vec4 color_mix(vec4 color1, vec4 color2, float color_ratio) { ); } else { color_out = vec4( - 255.0, + 1.0, 0.0, 0.0, 1.0 ); } - return linear_to_srgb(color_out); + + return vec4( + linear_to_srgb(color_out.r) * color_out.a, + linear_to_srgb(color_out.g) * color_out.a, + linear_to_srgb(color_out.b) * color_out.a, + color_out.a + ); } vec4 gradient_color(vec2 coords) { From 99b1bec3e609744518d0751352e22d77087d0c39 Mon Sep 17 00:00:00 2001 From: K's Thinkpad Date: Mon, 8 Jul 2024 18:52:00 +0200 Subject: [PATCH 19/34] added oklab --- src/render_helpers/shaders/border.frag | 40 ++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/render_helpers/shaders/border.frag b/src/render_helpers/shaders/border.frag index 598012a..15eb171 100644 --- a/src/render_helpers/shaders/border.frag +++ b/src/render_helpers/shaders/border.frag @@ -37,6 +37,40 @@ float linear_to_srgb(float color) { pow(color * 1.055, 1.0 / 2.4) - 0.055 ; } +vec4 linear_to_oklab(vec4 color){ + float l = color.r * 0.4122214708 + color.g * 0.5363325363 + color.b * 0.0514459929; + float m = color.r * 0.2119034982 + color.g * 0.6806995451 + color.b * 0.1073969566; + float s = color.r * 0.0883024619 + color.g * 0.2817188376 + color.b * 0.6299787005; + + l = pow(l, 1.0 / 3.0); + m = pow(m, 1.0 / 3.0); + s = pow(s, 1.0 / 3.0); + + return vec4( + l * 0.2104542553 + m * 0.7936177850 + s * -0.0040720468, + l * 1.9779984951 + m * -2.4285922050 + s * 0.4505937099, + l * 0.0259040371 + m * 0.7827717662 + s * -0.8086757660, + color.a + ); +} + +vec4 oklab_to_linear(vec4 color){ + float l = color.x + color.y * 0.3963377774 + color.z * 0.2158037573; + float m = color.x + color.y * -0.1055613458 + color.z * -0.0638541728; + float s = color.x + color.y * -0.0894841775 + color.z * -1.2914855480; + + l = pow(l, 3.0); + m = pow(m, 3.0); + s = pow(s, 3.0); + + return vec4( + l * 4.0767416621 + m * -3.3077115913 + s * 0.2309699292, + l * -1.2684380046 + m * 2.6097574011 + s * -0.3413193965, + l * -0.0041960863 + m * -0.7034186147 + s * 1.7076147010, + color.a + ); +} + vec4 color_mix(vec4 color1, vec4 color2, float color_ratio) { if (colorspace == 0.0) { // srgb @@ -64,6 +98,12 @@ vec4 color_mix(vec4 color1, vec4 color2, float color_ratio) { color2, color_ratio ); + } else if (colorspace == 2.0) { + color_out = oklab_to_linear(mix( + linear_to_oklab(color1), + linear_to_oklab(color2), + color_ratio + )); } else { color_out = vec4( 1.0, From 536abcf1cb09a736aec6a31e8613b52a9fce5d32 Mon Sep 17 00:00:00 2001 From: K's Thinkpad Date: Mon, 8 Jul 2024 19:22:30 +0200 Subject: [PATCH 20/34] added help to future devs --- src/render_helpers/shaders/border.frag | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/render_helpers/shaders/border.frag b/src/render_helpers/shaders/border.frag index 15eb171..9bc44e9 100644 --- a/src/render_helpers/shaders/border.frag +++ b/src/render_helpers/shaders/border.frag @@ -23,6 +23,10 @@ uniform vec2 geo_size; uniform vec4 outer_radius; uniform float border_width; +// for anyone who work on this in the future: +// https://github.com/color-js/color.js +// this is the github that includes all color conversions used in css + float srgb_to_linear(float color) { return color <= 0.04045 ? From 1373c1aea636378014c89c4f120a8126dd080a86 Mon Sep 17 00:00:00 2001 From: K's Thinkpad Date: Tue, 9 Jul 2024 17:38:19 +0200 Subject: [PATCH 21/34] added oklch functionality --- src/render_helpers/border.rs | 2 +- src/render_helpers/shaders/border.frag | 107 +++++++++++++++++++++---- 2 files changed, 93 insertions(+), 16 deletions(-) diff --git a/src/render_helpers/border.rs b/src/render_helpers/border.rs index 94388fe..6f49aa2 100644 --- a/src/render_helpers/border.rs +++ b/src/render_helpers/border.rs @@ -180,7 +180,7 @@ impl BorderRenderElement { HueInterpolation::Shorter => 0., HueInterpolation::Longer => 1., HueInterpolation::Increasing => 2., - HueInterpolation::Decreasing => 3. + HueInterpolation::Decreasing => 3., }; self.inner.update( diff --git a/src/render_helpers/shaders/border.frag b/src/render_helpers/shaders/border.frag index 9bc44e9..ee9bd0f 100644 --- a/src/render_helpers/shaders/border.frag +++ b/src/render_helpers/shaders/border.frag @@ -25,7 +25,7 @@ uniform float border_width; // for anyone who work on this in the future: // https://github.com/color-js/color.js -// this is the github that includes all color conversions used in css +// https://bottosson.github.io/posts/oklab/ float srgb_to_linear(float color) { return @@ -39,7 +39,42 @@ float linear_to_srgb(float color) { color <= 0.0031308 ? color * 12.92 : pow(color * 1.055, 1.0 / 2.4) - 0.055 ; -} +} + +vec4 lab_to_lch(vec4 color) { + float c = sqrt(pow(color.y, 2.0) + pow(color.z, 2.0)); + float h = degrees(atan(color.z, color.y)) ; + h += h <= 0.0 ? + 360.0 : + 0.0 ; + return vec4( + color.x, + c, + h, + color.a + ); +} + +vec4 lch_to_lab(vec4 color) { + // gpus can't do trig + float a = color.y * clamp(cos(radians(color.z)), -1.0, 1.0); + float b = color.y * clamp(sin(radians(color.z)), -1.0, 1.0); + return vec4( + color.x, + a, + b, + color.a + ); +} + +vec4 scaling(vec4 color){ + float divisor = + max(max(color.r, color.g), color.b) > 1.0 ? + max(max(color.r, color.g), color.b) : + 1.0 ; + color.rgb /= divisor; + return color; +} vec4 linear_to_oklab(vec4 color){ float l = color.r * 0.4122214708 + color.g * 0.5363325363 + color.b * 0.0514459929; @@ -75,9 +110,11 @@ vec4 oklab_to_linear(vec4 color){ ); } -vec4 color_mix(vec4 color1, vec4 color2, float color_ratio) { - if (colorspace == 0.0) { // srgb + +vec4 color_mix(vec4 color1, vec4 color2, float color_ratio) { + // srgb + if (colorspace == 0.0) { return mix(color1, color2, color_ratio); } @@ -95,30 +132,70 @@ vec4 color_mix(vec4 color1, vec4 color2, float color_ratio) { srgb_to_linear(color2.r), srgb_to_linear(color2.g), srgb_to_linear(color2.b)); - - if (colorspace == 1.0) { // srgb-linear + // srgb-linear + if (colorspace == 1.0) { color_out = mix( color1, color2, color_ratio ); + // oklab } else if (colorspace == 2.0) { color_out = oklab_to_linear(mix( linear_to_oklab(color1), linear_to_oklab(color2), color_ratio - )); - } else { - color_out = vec4( - 1.0, - 0.0, - 0.0, - 1.0 - ); + )); + // oklch + } else if (colorspace == 3.0) { + color1 = lab_to_lch(linear_to_oklab(color1)); + color2 = lab_to_lch(linear_to_oklab(color2)); + color_out = mix(color1, color2, color_ratio); + + float min_hue = min(color1.z, color2.z); + float max_hue = max(color1.z, color2.z); + float path_direct_distance = (max_hue - min_hue) * color_ratio; + float path_mod_distance = (360.0 - max_hue + min_hue) * color_ratio; + + float path_mod = + color1.z == min_hue ? + mod(color1.z - path_mod_distance, 360.0) : + mod(color1.z + path_mod_distance, 360.0) ; + + float path_direct = + color1.z == min_hue ? + color1.z + path_direct_distance : + color1.z - path_direct_distance ; + // shorter + if (hue_interpolation == 0.0) { + color_out.z = + max_hue - min_hue > 360.0 - max_hue + min_hue ? + path_mod : + path_direct ; + // longer + } else if (hue_interpolation == 1.0) { + color_out.z = + max_hue - min_hue <= 360.0 - max_hue + min_hue ? + path_mod : + path_direct ; + // increasing + } else if (hue_interpolation == 2.0) { + color_out.z = + color1.z > color2.z ? + path_mod : + path_direct ; + // decreasing + } else if (hue_interpolation == 3.0) { + color_out.z = + color1.z <= color2.z ? + path_mod : + path_direct ; + } + color_out = scaling(oklab_to_linear(lch_to_lab(color_out))); } return vec4( - linear_to_srgb(color_out.r) * color_out.a, + linear_to_srgb(color_out.r) * color_out.a , linear_to_srgb(color_out.g) * color_out.a, linear_to_srgb(color_out.b) * color_out.a, color_out.a From 061052d21b410cd860768d71e92c34eb06ced965 Mon Sep 17 00:00:00 2001 From: K's Thinkpad Date: Tue, 9 Jul 2024 17:40:14 +0200 Subject: [PATCH 22/34] removed unnecesary comments --- src/render_helpers/shaders/border.frag | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/render_helpers/shaders/border.frag b/src/render_helpers/shaders/border.frag index ee9bd0f..edd1226 100644 --- a/src/render_helpers/shaders/border.frag +++ b/src/render_helpers/shaders/border.frag @@ -23,10 +23,6 @@ uniform vec2 geo_size; uniform vec4 outer_radius; uniform float border_width; -// for anyone who work on this in the future: -// https://github.com/color-js/color.js -// https://bottosson.github.io/posts/oklab/ - float srgb_to_linear(float color) { return color <= 0.04045 ? From eb6b8da35a195f2c4e3208de5b65926ff836505c Mon Sep 17 00:00:00 2001 From: K's Thinkpad Date: Tue, 9 Jul 2024 17:47:34 +0200 Subject: [PATCH 23/34] cleaned up the codebase --- src/render_helpers/shaders/border.frag | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/render_helpers/shaders/border.frag b/src/render_helpers/shaders/border.frag index edd1226..65b59a7 100644 --- a/src/render_helpers/shaders/border.frag +++ b/src/render_helpers/shaders/border.frag @@ -52,7 +52,6 @@ vec4 lab_to_lch(vec4 color) { } vec4 lch_to_lab(vec4 color) { - // gpus can't do trig float a = color.y * clamp(cos(radians(color.z)), -1.0, 1.0); float b = color.y * clamp(sin(radians(color.z)), -1.0, 1.0); return vec4( @@ -106,8 +105,6 @@ vec4 oklab_to_linear(vec4 color){ ); } - - vec4 color_mix(vec4 color1, vec4 color2, float color_ratio) { // srgb if (colorspace == 0.0) { From 2c001968e2e2c0c47efef44d5cfbc594ea0b8968 Mon Sep 17 00:00:00 2001 From: K's Thinkpad Date: Tue, 9 Jul 2024 17:51:38 +0200 Subject: [PATCH 24/34] cleaned up code --- niri-config/src/lib.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs index b07db58..981cc37 100644 --- a/niri-config/src/lib.rs +++ b/niri-config/src/lib.rs @@ -445,7 +445,7 @@ pub enum GradientColorSpace { Srgb, SrgbLinear, Oklab, - Oklch + Oklch, } #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] @@ -1481,8 +1481,7 @@ impl FromStr for GradientInterpolation { &_ => return Err(miette!("Invalid hue-interpolation: {in_str}")) } } else { - // this is a placeholder and should be changed if anything is added to in for - // gradients + // this is a placeholder and should be changed if anything is added to in return Err(miette!("Theres a missing indicator ’hue’ from ’in’ ")) } } else { From c331cd6fe4476b22af221075b67a8acb62e5af8e Mon Sep 17 00:00:00 2001 From: Kiko Date: Tue, 9 Jul 2024 15:52:41 +0000 Subject: [PATCH 25/34] Update src/render_helpers/shaders/border.frag Co-authored-by: Ivan Molodetskikh --- src/render_helpers/shaders/border.frag | 1 - 1 file changed, 1 deletion(-) diff --git a/src/render_helpers/shaders/border.frag b/src/render_helpers/shaders/border.frag index 65b59a7..1c2e46a 100644 --- a/src/render_helpers/shaders/border.frag +++ b/src/render_helpers/shaders/border.frag @@ -104,7 +104,6 @@ vec4 oklab_to_linear(vec4 color){ color.a ); } - vec4 color_mix(vec4 color1, vec4 color2, float color_ratio) { // srgb if (colorspace == 0.0) { From 95ac2da21b707f2b95605fd35842dd5ff65aabf8 Mon Sep 17 00:00:00 2001 From: K's Thinkpad Date: Tue, 9 Jul 2024 23:25:47 +0200 Subject: [PATCH 26/34] added missing newline --- src/render_helpers/shaders/border.frag | 1 + 1 file changed, 1 insertion(+) diff --git a/src/render_helpers/shaders/border.frag b/src/render_helpers/shaders/border.frag index 1c2e46a..65b59a7 100644 --- a/src/render_helpers/shaders/border.frag +++ b/src/render_helpers/shaders/border.frag @@ -104,6 +104,7 @@ vec4 oklab_to_linear(vec4 color){ color.a ); } + vec4 color_mix(vec4 color1, vec4 color2, float color_ratio) { // srgb if (colorspace == 0.0) { From 63c75b4d6a04e73f91110d96c97b54addaae41ca Mon Sep 17 00:00:00 2001 From: K's Thinkpad Date: Wed, 10 Jul 2024 16:56:23 +0200 Subject: [PATCH 27/34] cleaned up fixed srgb to linear added matrix math --- src/render_helpers/shaders/border.frag | 127 ++++++++++++------------- 1 file changed, 61 insertions(+), 66 deletions(-) diff --git a/src/render_helpers/shaders/border.frag b/src/render_helpers/shaders/border.frag index 65b59a7..6358bd4 100644 --- a/src/render_helpers/shaders/border.frag +++ b/src/render_helpers/shaders/border.frag @@ -24,85 +24,76 @@ uniform vec4 outer_radius; uniform float border_width; float srgb_to_linear(float color) { - return - color <= 0.04045 ? - color / 12.92 : - pow((color + 0.055) / 1.055, 2.4) ; + return pow(color, 2.2) ; } float linear_to_srgb(float color) { - return - color <= 0.0031308 ? - color * 12.92 : - pow(color * 1.055, 1.0 / 2.4) - 0.055 ; + return pow(color, 1.0 / 2.2) ; } -vec4 lab_to_lch(vec4 color) { +vec3 lab_to_lch(vec3 color) { float c = sqrt(pow(color.y, 2.0) + pow(color.z, 2.0)); float h = degrees(atan(color.z, color.y)) ; h += h <= 0.0 ? 360.0 : 0.0 ; - return vec4( + return vec3( color.x, c, - h, - color.a + h ); } -vec4 lch_to_lab(vec4 color) { +vec3 lch_to_lab(vec3 color) { float a = color.y * clamp(cos(radians(color.z)), -1.0, 1.0); float b = color.y * clamp(sin(radians(color.z)), -1.0, 1.0); - return vec4( + return vec3( color.x, a, - b, - color.a + b ); } -vec4 scaling(vec4 color){ - float divisor = - max(max(color.r, color.g), color.b) > 1.0 ? - max(max(color.r, color.g), color.b) : - 1.0 ; - color.rgb /= divisor; - return color; +vec3 linear_to_oklab(vec3 color){ + mat3 rgb_to_lms = mat3( + vec3(0.4122214708, 0.5363325363, 0.0514459929), + vec3(0.2119034982, 0.6806995451, 0.1073969566), + vec3(0.0883024619, 0.2817188376, 0.6299787005) + ); + mat3 lms_to_oklab = mat3( + vec3(0.2104542553, 0.7936177850, -0.0040720468), + vec3(1.9779984951, -2.4285922050, 0.4505937099), + vec3(0.0259040371, 0.7827717662, -0.8086757660) + ); + vec3 lms = color * rgb_to_lms; + + lms = vec3( + pow(lms.x, 1.0 / 3.0), + pow(lms.y, 1.0 / 3.0), + pow(lms.z, 1.0 / 3.0) + ); + return lms * lms_to_oklab; } -vec4 linear_to_oklab(vec4 color){ - float l = color.r * 0.4122214708 + color.g * 0.5363325363 + color.b * 0.0514459929; - float m = color.r * 0.2119034982 + color.g * 0.6806995451 + color.b * 0.1073969566; - float s = color.r * 0.0883024619 + color.g * 0.2817188376 + color.b * 0.6299787005; - - l = pow(l, 1.0 / 3.0); - m = pow(m, 1.0 / 3.0); - s = pow(s, 1.0 / 3.0); - - return vec4( - l * 0.2104542553 + m * 0.7936177850 + s * -0.0040720468, - l * 1.9779984951 + m * -2.4285922050 + s * 0.4505937099, - l * 0.0259040371 + m * 0.7827717662 + s * -0.8086757660, - color.a +vec3 oklab_to_linear(vec3 color){ + mat3 oklab_to_lms = mat3( + vec3(1.0, 0.3963377774, 0.2158037573), + vec3(1.0, -0.1055613458, -0.0638541728), + vec3(1.0, -0.0894841775, -1.2914855480) ); -} - -vec4 oklab_to_linear(vec4 color){ - float l = color.x + color.y * 0.3963377774 + color.z * 0.2158037573; - float m = color.x + color.y * -0.1055613458 + color.z * -0.0638541728; - float s = color.x + color.y * -0.0894841775 + color.z * -1.2914855480; - - l = pow(l, 3.0); - m = pow(m, 3.0); - s = pow(s, 3.0); - - return vec4( - l * 4.0767416621 + m * -3.3077115913 + s * 0.2309699292, - l * -1.2684380046 + m * 2.6097574011 + s * -0.3413193965, - l * -0.0041960863 + m * -0.7034186147 + s * 1.7076147010, - color.a + mat3 lms_to_rgb = mat3( + vec3(4.0767416621, -3.3077115913, 0.2309699292), + vec3(-1.2684380046, 2.6097574011, -0.3413193965), + vec3(-0.0041960863, -0.7034186147, 1.7076147010) ); + vec3 lms = color * oklab_to_lms; + + lms = vec3( + pow(lms.x, 3.0), + pow(lms.y, 3.0), + pow(lms.z, 3.0) + ); + return lms * lms_to_rgb; } vec4 color_mix(vec4 color1, vec4 color2, float color_ratio) { @@ -113,18 +104,19 @@ vec4 color_mix(vec4 color1, vec4 color2, float color_ratio) { vec4 color_out; - color1.rgb = color1.rgb / color1.a; - color2.rgb = color2.rgb / color2.a; + color1.rgb /= color1.a; + color2.rgb /= color2.a; color1.rgb = vec3( srgb_to_linear(color1.r), srgb_to_linear(color1.g), - srgb_to_linear(color1.b)); - + srgb_to_linear(color1.b) + ); color2.rgb = vec3( srgb_to_linear(color2.r), srgb_to_linear(color2.g), - srgb_to_linear(color2.b)); + srgb_to_linear(color2.b) + ); // srgb-linear if (colorspace == 1.0) { color_out = mix( @@ -134,15 +126,18 @@ vec4 color_mix(vec4 color1, vec4 color2, float color_ratio) { ); // oklab } else if (colorspace == 2.0) { - color_out = oklab_to_linear(mix( - linear_to_oklab(color1), - linear_to_oklab(color2), + color1.xyz = linear_to_oklab(color1.rgb); + color2.xyz = linear_to_oklab(color2.rgb); + color_out = mix( + color1, + color2, color_ratio - )); + ); + color_out.rgb = oklab_to_linear(color_out.xyz); // oklch } else if (colorspace == 3.0) { - color1 = lab_to_lch(linear_to_oklab(color1)); - color2 = lab_to_lch(linear_to_oklab(color2)); + color1.xyz = lab_to_lch(linear_to_oklab(color1.rgb)); + color2.xyz = lab_to_lch(linear_to_oklab(color2.rgb)); color_out = mix(color1, color2, color_ratio); float min_hue = min(color1.z, color2.z); @@ -179,12 +174,12 @@ vec4 color_mix(vec4 color1, vec4 color2, float color_ratio) { path_direct ; // decreasing } else if (hue_interpolation == 3.0) { - color_out.z = + color_out.z = color1.z <= color2.z ? path_mod : path_direct ; } - color_out = scaling(oklab_to_linear(lch_to_lab(color_out))); + color_out.rgb = clamp(oklab_to_linear(lch_to_lab(color_out.xyz)), 0.0, 1.0); } return vec4( From e874213618888c7a35eff6511a462b6afd8de74f Mon Sep 17 00:00:00 2001 From: Kiko Date: Wed, 10 Jul 2024 15:00:00 +0000 Subject: [PATCH 28/34] Update resources/default-config.kdl Co-authored-by: Ivan Molodetskikh --- resources/default-config.kdl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/default-config.kdl b/resources/default-config.kdl index e795f20..ed2d4f0 100644 --- a/resources/default-config.kdl +++ b/resources/default-config.kdl @@ -153,7 +153,7 @@ layout { // The angle is the same as in linear-gradient, and is optional, // defaulting to 180 (top-to-bottom gradient). // You can use any CSS linear-gradient tool on the web to set these up. - // for gradient types visit the wiki + // Changing the color space is also supported, check the wiki for more info. // // active-gradient from="#80c8ff" to="#bbddff" angle=45 From b1a667025f01de76ebd641bbfceeab5242ee02fb Mon Sep 17 00:00:00 2001 From: Kiko Date: Wed, 10 Jul 2024 15:00:14 +0000 Subject: [PATCH 29/34] Update niri-config/src/lib.rs Co-authored-by: Ivan Molodetskikh --- niri-config/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs index 50c18cd..80612ff 100644 --- a/niri-config/src/lib.rs +++ b/niri-config/src/lib.rs @@ -422,7 +422,7 @@ pub struct Gradient { pub angle: i16, #[knuffel(property, default)] pub relative_to: GradientRelativeTo, - #[knuffel(property(name="in"), str)] + #[knuffel(property(name="in"), str, default)] pub in_: GradientInterpolation, } From 777fed53255f0247b52842477dbf51f832364d3d Mon Sep 17 00:00:00 2001 From: K's Thinkpad Date: Wed, 10 Jul 2024 17:28:28 +0200 Subject: [PATCH 30/34] cleaned up test cases for lch gradients --- .../src/cases/gradient_oklch_decreasing.rs | 35 ------------------- .../src/cases/gradient_oklch_increasing.rs | 35 ------------------- .../src/cases/gradient_oklch_longer.rs | 35 ------------------- .../src/cases/gradient_oklch_shorter.rs | 35 ------------------- 4 files changed, 140 deletions(-) diff --git a/niri-visual-tests/src/cases/gradient_oklch_decreasing.rs b/niri-visual-tests/src/cases/gradient_oklch_decreasing.rs index 398fa86..a3a734d 100644 --- a/niri-visual-tests/src/cases/gradient_oklch_decreasing.rs +++ b/niri-visual-tests/src/cases/gradient_oklch_decreasing.rs @@ -1,8 +1,3 @@ - -use std::sync::atomic::Ordering; -use std::time::Duration; - -use niri::animation::ANIMATION_SLOWDOWN; use niri::render_helpers::border::BorderRenderElement; use niri_config::{CornerRadius, GradientInterpolation, HueInterpolation, GradientColorSpace}; use smithay::backend::renderer::element::RenderElement; @@ -12,16 +7,12 @@ use smithay::utils::{Logical, Physical, Rectangle, Size}; use super::TestCase; pub struct GradientOklchDecreasing { - time: f32, - prev_time: Duration, gradient_format: GradientInterpolation, } impl GradientOklchDecreasing { pub fn new(_size: Size) -> Self { Self { - time: 0., - prev_time: Duration::ZERO, gradient_format: GradientInterpolation{ color_space: GradientColorSpace::Oklch, hue_interpol: HueInterpolation::Decreasing @@ -31,32 +22,6 @@ impl GradientOklchDecreasing { } impl TestCase for GradientOklchDecreasing { - fn are_animations_ongoing(&self) -> bool { - true - } - - fn advance_animations(&mut self, current_time: Duration) { - let mut delta = if self.prev_time.is_zero() { - Duration::ZERO - } else { - current_time.saturating_sub(self.prev_time) - }; - self.prev_time = current_time; - - let slowdown = ANIMATION_SLOWDOWN.load(Ordering::SeqCst); - if slowdown == 0. { - delta = Duration::ZERO; - } else { - delta = delta.div_f64(slowdown); - } - - self.time = delta.as_secs_f32() ; - - if self.time >= 26.9 { - self.time = 0.0 - } - } - fn render( &mut self, _renderer: &mut GlesRenderer, diff --git a/niri-visual-tests/src/cases/gradient_oklch_increasing.rs b/niri-visual-tests/src/cases/gradient_oklch_increasing.rs index 4e5114f..89a75cb 100644 --- a/niri-visual-tests/src/cases/gradient_oklch_increasing.rs +++ b/niri-visual-tests/src/cases/gradient_oklch_increasing.rs @@ -1,8 +1,3 @@ - -use std::sync::atomic::Ordering; -use std::time::Duration; - -use niri::animation::ANIMATION_SLOWDOWN; use niri::render_helpers::border::BorderRenderElement; use niri_config::{CornerRadius, GradientInterpolation, HueInterpolation, GradientColorSpace}; use smithay::backend::renderer::element::RenderElement; @@ -12,16 +7,12 @@ use smithay::utils::{Logical, Physical, Rectangle, Size}; use super::TestCase; pub struct GradientOklchIncreasing { - time: f32, - prev_time: Duration, gradient_format: GradientInterpolation, } impl GradientOklchIncreasing { pub fn new(_size: Size) -> Self { Self { - time: 0., - prev_time: Duration::ZERO, gradient_format: GradientInterpolation{ color_space: GradientColorSpace::Oklch, hue_interpol: HueInterpolation::Increasing @@ -31,32 +22,6 @@ impl GradientOklchIncreasing { } impl TestCase for GradientOklchIncreasing { - fn are_animations_ongoing(&self) -> bool { - true - } - - fn advance_animations(&mut self, current_time: Duration) { - let mut delta = if self.prev_time.is_zero() { - Duration::ZERO - } else { - current_time.saturating_sub(self.prev_time) - }; - self.prev_time = current_time; - - let slowdown = ANIMATION_SLOWDOWN.load(Ordering::SeqCst); - if slowdown == 0. { - delta = Duration::ZERO; - } else { - delta = delta.div_f64(slowdown); - } - - self.time = delta.as_secs_f32() ; - - if self.time >= 26.9 { - self.time = 0.0 - } - } - fn render( &mut self, _renderer: &mut GlesRenderer, diff --git a/niri-visual-tests/src/cases/gradient_oklch_longer.rs b/niri-visual-tests/src/cases/gradient_oklch_longer.rs index 2243a5e..46c9f2b 100644 --- a/niri-visual-tests/src/cases/gradient_oklch_longer.rs +++ b/niri-visual-tests/src/cases/gradient_oklch_longer.rs @@ -1,8 +1,3 @@ - -use std::sync::atomic::Ordering; -use std::time::Duration; - -use niri::animation::ANIMATION_SLOWDOWN; use niri::render_helpers::border::BorderRenderElement; use niri_config::{CornerRadius, GradientInterpolation, HueInterpolation, GradientColorSpace}; use smithay::backend::renderer::element::RenderElement; @@ -12,16 +7,12 @@ use smithay::utils::{Logical, Physical, Rectangle, Size}; use super::TestCase; pub struct GradientOklchLonger { - time: f32, - prev_time: Duration, gradient_format: GradientInterpolation, } impl GradientOklchLonger { pub fn new(_size: Size) -> Self { Self { - time: 0., - prev_time: Duration::ZERO, gradient_format: GradientInterpolation{ color_space: GradientColorSpace::Oklch, hue_interpol: HueInterpolation::Longer @@ -31,32 +22,6 @@ impl GradientOklchLonger { } impl TestCase for GradientOklchLonger { - fn are_animations_ongoing(&self) -> bool { - true - } - - fn advance_animations(&mut self, current_time: Duration) { - let mut delta = if self.prev_time.is_zero() { - Duration::ZERO - } else { - current_time.saturating_sub(self.prev_time) - }; - self.prev_time = current_time; - - let slowdown = ANIMATION_SLOWDOWN.load(Ordering::SeqCst); - if slowdown == 0. { - delta = Duration::ZERO; - } else { - delta = delta.div_f64(slowdown); - } - - self.time = delta.as_secs_f32() ; - - if self.time >= 26.9 { - self.time = 0.0 - } - } - fn render( &mut self, _renderer: &mut GlesRenderer, diff --git a/niri-visual-tests/src/cases/gradient_oklch_shorter.rs b/niri-visual-tests/src/cases/gradient_oklch_shorter.rs index c54386d..f9d2636 100644 --- a/niri-visual-tests/src/cases/gradient_oklch_shorter.rs +++ b/niri-visual-tests/src/cases/gradient_oklch_shorter.rs @@ -1,8 +1,3 @@ - -use std::sync::atomic::Ordering; -use std::time::Duration; - -use niri::animation::ANIMATION_SLOWDOWN; use niri::render_helpers::border::BorderRenderElement; use niri_config::{CornerRadius, GradientInterpolation, HueInterpolation, GradientColorSpace}; use smithay::backend::renderer::element::RenderElement; @@ -12,16 +7,12 @@ use smithay::utils::{Logical, Physical, Rectangle, Size}; use super::TestCase; pub struct GradientOklchShorter { - time: f32, - prev_time: Duration, gradient_format: GradientInterpolation, } impl GradientOklchShorter { pub fn new(_size: Size) -> Self { Self { - time: 0., - prev_time: Duration::ZERO, gradient_format: GradientInterpolation{ color_space: GradientColorSpace::Oklch, hue_interpol: HueInterpolation::Shorter @@ -31,32 +22,6 @@ impl GradientOklchShorter { } impl TestCase for GradientOklchShorter { - fn are_animations_ongoing(&self) -> bool { - true - } - - fn advance_animations(&mut self, current_time: Duration) { - let mut delta = if self.prev_time.is_zero() { - Duration::ZERO - } else { - current_time.saturating_sub(self.prev_time) - }; - self.prev_time = current_time; - - let slowdown = ANIMATION_SLOWDOWN.load(Ordering::SeqCst); - if slowdown == 0. { - delta = Duration::ZERO; - } else { - delta = delta.div_f64(slowdown); - } - - self.time = delta.as_secs_f32() ; - - if self.time >= 26.9 { - self.time = 0.0 - } - } - fn render( &mut self, _renderer: &mut GlesRenderer, From dfcc881db26986ab0b64bcc99657338671878f59 Mon Sep 17 00:00:00 2001 From: K's Thinkpad Date: Wed, 10 Jul 2024 17:32:13 +0200 Subject: [PATCH 31/34] fixed the rest of the static gradient tests --- niri-visual-tests/src/cases/gradient_oklab.rs | 35 ------------------- niri-visual-tests/src/cases/gradient_srgb.rs | 34 ------------------ .../src/cases/gradient_srgblinear.rs | 35 ------------------- 3 files changed, 104 deletions(-) diff --git a/niri-visual-tests/src/cases/gradient_oklab.rs b/niri-visual-tests/src/cases/gradient_oklab.rs index cc19326..bd8014f 100644 --- a/niri-visual-tests/src/cases/gradient_oklab.rs +++ b/niri-visual-tests/src/cases/gradient_oklab.rs @@ -1,8 +1,3 @@ - -use std::sync::atomic::Ordering; -use std::time::Duration; - -use niri::animation::ANIMATION_SLOWDOWN; use niri::render_helpers::border::BorderRenderElement; use niri_config::{CornerRadius, GradientInterpolation, HueInterpolation, GradientColorSpace}; use smithay::backend::renderer::element::RenderElement; @@ -12,16 +7,12 @@ use smithay::utils::{Logical, Physical, Rectangle, Size}; use super::TestCase; pub struct GradientOklab { - time: f32, - prev_time: Duration, gradient_format: GradientInterpolation, } impl GradientOklab { pub fn new(_size: Size) -> Self { Self { - time: 0., - prev_time: Duration::ZERO, gradient_format: GradientInterpolation{ color_space: GradientColorSpace::Oklab, hue_interpol: HueInterpolation::Shorter @@ -31,32 +22,6 @@ impl GradientOklab { } impl TestCase for GradientOklab { - fn are_animations_ongoing(&self) -> bool { - true - } - - fn advance_animations(&mut self, current_time: Duration) { - let mut delta = if self.prev_time.is_zero() { - Duration::ZERO - } else { - current_time.saturating_sub(self.prev_time) - }; - self.prev_time = current_time; - - let slowdown = ANIMATION_SLOWDOWN.load(Ordering::SeqCst); - if slowdown == 0. { - delta = Duration::ZERO; - } else { - delta = delta.div_f64(slowdown); - } - - self.time = delta.as_secs_f32() ; - - if self.time >= 26.9 { - self.time = 0.0 - } - } - fn render( &mut self, _renderer: &mut GlesRenderer, diff --git a/niri-visual-tests/src/cases/gradient_srgb.rs b/niri-visual-tests/src/cases/gradient_srgb.rs index 7e8a1ed..9b80124 100644 --- a/niri-visual-tests/src/cases/gradient_srgb.rs +++ b/niri-visual-tests/src/cases/gradient_srgb.rs @@ -1,7 +1,3 @@ -use std::sync::atomic::Ordering; -use std::time::Duration; - -use niri::animation::ANIMATION_SLOWDOWN; use niri::render_helpers::border::BorderRenderElement; use niri_config::{CornerRadius, GradientInterpolation, HueInterpolation, GradientColorSpace}; use smithay::backend::renderer::element::RenderElement; @@ -11,16 +7,12 @@ use smithay::utils::{Logical, Physical, Rectangle, Size}; use super::TestCase; pub struct GradientSrgb { - time: f32, - prev_time: Duration, gradient_format: GradientInterpolation, } impl GradientSrgb { pub fn new(_size: Size) -> Self { Self { - time: 0., - prev_time: Duration::ZERO, gradient_format: GradientInterpolation{ color_space: GradientColorSpace::Srgb, hue_interpol: HueInterpolation::Shorter @@ -30,32 +22,6 @@ impl GradientSrgb { } impl TestCase for GradientSrgb { - fn are_animations_ongoing(&self) -> bool { - true - } - - fn advance_animations(&mut self, current_time: Duration) { - let mut delta = if self.prev_time.is_zero() { - Duration::ZERO - } else { - current_time.saturating_sub(self.prev_time) - }; - self.prev_time = current_time; - - let slowdown = ANIMATION_SLOWDOWN.load(Ordering::SeqCst); - if slowdown == 0. { - delta = Duration::ZERO; - } else { - delta = delta.div_f64(slowdown); - } - - self.time = delta.as_secs_f32() ; - - if self.time >= 26.9 { - self.time = 0.0 - } - } - fn render( &mut self, _renderer: &mut GlesRenderer, diff --git a/niri-visual-tests/src/cases/gradient_srgblinear.rs b/niri-visual-tests/src/cases/gradient_srgblinear.rs index f7d2145..225ce64 100644 --- a/niri-visual-tests/src/cases/gradient_srgblinear.rs +++ b/niri-visual-tests/src/cases/gradient_srgblinear.rs @@ -1,8 +1,3 @@ - -use std::sync::atomic::Ordering; -use std::time::Duration; - -use niri::animation::ANIMATION_SLOWDOWN; use niri::render_helpers::border::BorderRenderElement; use niri_config::{CornerRadius, GradientInterpolation, HueInterpolation, GradientColorSpace}; use smithay::backend::renderer::element::RenderElement; @@ -12,16 +7,12 @@ use smithay::utils::{Logical, Physical, Rectangle, Size}; use super::TestCase; pub struct GradientSrgbLinear { - time: f32, - prev_time: Duration, gradient_format: GradientInterpolation, } impl GradientSrgbLinear { pub fn new(_size: Size) -> Self { Self { - time: 0., - prev_time: Duration::ZERO, gradient_format: GradientInterpolation{ color_space: GradientColorSpace::SrgbLinear, hue_interpol: HueInterpolation::Shorter @@ -31,32 +22,6 @@ impl GradientSrgbLinear { } impl TestCase for GradientSrgbLinear { - fn are_animations_ongoing(&self) -> bool { - true - } - - fn advance_animations(&mut self, current_time: Duration) { - let mut delta = if self.prev_time.is_zero() { - Duration::ZERO - } else { - current_time.saturating_sub(self.prev_time) - }; - self.prev_time = current_time; - - let slowdown = ANIMATION_SLOWDOWN.load(Ordering::SeqCst); - if slowdown == 0. { - delta = Duration::ZERO; - } else { - delta = delta.div_f64(slowdown); - } - - self.time = delta.as_secs_f32() ; - - if self.time >= 26.9 { - self.time = 0.0 - } - } - fn render( &mut self, _renderer: &mut GlesRenderer, From fc22d47b659050fc0a460d5bb2c2cc2d324e8eab Mon Sep 17 00:00:00 2001 From: K's Thinkpad Date: Wed, 10 Jul 2024 17:38:43 +0200 Subject: [PATCH 32/34] cleaned up 1 or 2 lines --- src/render_helpers/shaders/border.frag | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/render_helpers/shaders/border.frag b/src/render_helpers/shaders/border.frag index 6358bd4..17de2d2 100644 --- a/src/render_helpers/shaders/border.frag +++ b/src/render_helpers/shaders/border.frag @@ -24,11 +24,11 @@ uniform vec4 outer_radius; uniform float border_width; float srgb_to_linear(float color) { - return pow(color, 2.2) ; + return pow(color, 2.2); } float linear_to_srgb(float color) { - return pow(color, 1.0 / 2.2) ; + return pow(color, 1.0 / 2.2); } vec3 lab_to_lch(vec3 color) { @@ -149,11 +149,11 @@ vec4 color_mix(vec4 color1, vec4 color2, float color_ratio) { color1.z == min_hue ? mod(color1.z - path_mod_distance, 360.0) : mod(color1.z + path_mod_distance, 360.0) ; - float path_direct = color1.z == min_hue ? color1.z + path_direct_distance : color1.z - path_direct_distance ; + // shorter if (hue_interpolation == 0.0) { color_out.z = From 31da555f54b3f41da599d79111c205e20ade0501 Mon Sep 17 00:00:00 2001 From: K's Thinkpad Date: Wed, 10 Jul 2024 23:17:39 +0200 Subject: [PATCH 33/34] filtered out edgecases in the shader --- src/render_helpers/shaders/border.frag | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/render_helpers/shaders/border.frag b/src/render_helpers/shaders/border.frag index 17de2d2..3e36990 100644 --- a/src/render_helpers/shaders/border.frag +++ b/src/render_helpers/shaders/border.frag @@ -98,14 +98,19 @@ vec3 oklab_to_linear(vec3 color){ vec4 color_mix(vec4 color1, vec4 color2, float color_ratio) { // srgb - if (colorspace == 0.0) { + + if (color1 == color2) { + return color1; + } + + if (colorspace == 0.0 || color1.rgb == color2.rgb) { return mix(color1, color2, color_ratio); } vec4 color_out; - color1.rgb /= color1.a; - color2.rgb /= color2.a; + color1.rgb /= color1.a != 0.0 ? color1.a : 1.0; + color2.rgb /= color2.a != 0.0 ? color2.a : 1.0; color1.rgb = vec3( srgb_to_linear(color1.r), @@ -183,7 +188,7 @@ vec4 color_mix(vec4 color1, vec4 color2, float color_ratio) { } return vec4( - linear_to_srgb(color_out.r) * color_out.a , + linear_to_srgb(color_out.r) * color_out.a, linear_to_srgb(color_out.g) * color_out.a, linear_to_srgb(color_out.b) * color_out.a, color_out.a From 89d6c622cdb3338320bc2f71d04b2a4fb6db0fb3 Mon Sep 17 00:00:00 2001 From: K's Thinkpad Date: Wed, 10 Jul 2024 23:23:42 +0200 Subject: [PATCH 34/34] edit coding sleep deprived is not a good idea those werent edge cases those where important parts of the code --- src/render_helpers/shaders/border.frag | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/render_helpers/shaders/border.frag b/src/render_helpers/shaders/border.frag index 3e36990..d665797 100644 --- a/src/render_helpers/shaders/border.frag +++ b/src/render_helpers/shaders/border.frag @@ -99,11 +99,7 @@ vec3 oklab_to_linear(vec3 color){ vec4 color_mix(vec4 color1, vec4 color2, float color_ratio) { // srgb - if (color1 == color2) { - return color1; - } - - if (colorspace == 0.0 || color1.rgb == color2.rgb) { + if (colorspace == 0.0) { return mix(color1, color2, color_ratio); }