diff options
Diffstat (limited to 'src/render_helpers/shaders')
| -rw-r--r-- | src/render_helpers/shaders/crossfade.frag | 31 | ||||
| -rw-r--r-- | src/render_helpers/shaders/mod.rs | 75 | ||||
| -rw-r--r-- | src/render_helpers/shaders/resize.frag | 41 |
3 files changed, 105 insertions, 42 deletions
diff --git a/src/render_helpers/shaders/crossfade.frag b/src/render_helpers/shaders/crossfade.frag deleted file mode 100644 index 56280ad2..00000000 --- a/src/render_helpers/shaders/crossfade.frag +++ /dev/null @@ -1,31 +0,0 @@ -#version 100 - -precision mediump float; - -uniform sampler2D tex_from; -uniform vec2 tex_from_loc; -uniform vec2 tex_from_size; - -uniform sampler2D tex_to; -uniform vec2 tex_to_loc; -uniform vec2 tex_to_size; - -uniform float alpha; -uniform float amount; - -uniform vec2 size; -varying vec2 v_coords; - -void main() { - vec2 coords_from = (v_coords - tex_from_loc) / tex_from_size; - vec2 coords_to = (v_coords - tex_to_loc) / tex_to_size; - - vec4 color_from = texture2D(tex_from, coords_from); - vec4 color_to = texture2D(tex_to, coords_to); - - vec4 color = mix(color_from, color_to, amount); - color = color * alpha; - - gl_FragColor = color; -} - diff --git a/src/render_helpers/shaders/mod.rs b/src/render_helpers/shaders/mod.rs index ebe0d08c..040cf503 100644 --- a/src/render_helpers/shaders/mod.rs +++ b/src/render_helpers/shaders/mod.rs @@ -1,3 +1,5 @@ +use std::cell::RefCell; + use smithay::backend::renderer::gles::{GlesPixelProgram, GlesRenderer, UniformName, UniformType}; use super::primary_gpu_pixel_shader_with_textures::PixelWithTexturesProgram; @@ -5,7 +7,8 @@ use super::renderer::NiriRenderer; pub struct Shaders { pub gradient_border: Option<GlesPixelProgram>, - pub crossfade: Option<PixelWithTexturesProgram>, + pub resize: Option<PixelWithTexturesProgram>, + pub custom_resize: RefCell<Option<PixelWithTexturesProgram>>, } impl Shaders { @@ -28,26 +31,29 @@ impl Shaders { }) .ok(); - let crossfade = PixelWithTexturesProgram::compile( + let resize = PixelWithTexturesProgram::compile( renderer, - include_str!("crossfade.frag"), + include_str!("resize.frag"), &[ - UniformName::new("tex_from_loc", UniformType::_2f), - UniformName::new("tex_from_size", UniformType::_2f), - UniformName::new("tex_to_loc", UniformType::_2f), - UniformName::new("tex_to_size", UniformType::_2f), - UniformName::new("amount", UniformType::_1f), + UniformName::new("input_to_curr_geo", UniformType::Matrix3x3), + UniformName::new("input_to_prev_geo", UniformType::Matrix3x3), + UniformName::new("input_to_next_geo", UniformType::Matrix3x3), + UniformName::new("geo_to_tex_prev", UniformType::Matrix3x3), + UniformName::new("geo_to_tex_next", UniformType::Matrix3x3), + UniformName::new("progress", UniformType::_1f), + UniformName::new("clamped_progress", UniformType::_1f), ], - &["tex_from", "tex_to"], + &["tex_prev", "tex_next"], ) .map_err(|err| { - warn!("error compiling crossfade shader: {err:?}"); + warn!("error compiling resize shader: {err:?}"); }) .ok(); Self { gradient_border, - crossfade, + resize, + custom_resize: RefCell::new(None), } } @@ -57,6 +63,20 @@ impl Shaders { data.get() .expect("shaders::init() must be called when creating the renderer") } + + pub fn replace_custom_resize_program( + &self, + program: Option<PixelWithTexturesProgram>, + ) -> Option<PixelWithTexturesProgram> { + self.custom_resize.replace(program) + } + + pub fn resize(&self) -> Option<PixelWithTexturesProgram> { + self.custom_resize + .borrow() + .clone() + .or_else(|| self.resize.clone()) + } } pub fn init(renderer: &mut GlesRenderer) { @@ -66,3 +86,36 @@ pub fn init(renderer: &mut GlesRenderer) { error!("shaders were already compiled"); } } + +pub fn set_custom_resize_program(renderer: &mut GlesRenderer, src: Option<&str>) { + let program = if let Some(src) = src { + match PixelWithTexturesProgram::compile( + renderer, + src, + &[ + UniformName::new("input_to_curr_geo", UniformType::Matrix3x3), + UniformName::new("input_to_prev_geo", UniformType::Matrix3x3), + UniformName::new("input_to_next_geo", UniformType::Matrix3x3), + UniformName::new("geo_to_tex_prev", UniformType::Matrix3x3), + UniformName::new("geo_to_tex_next", UniformType::Matrix3x3), + UniformName::new("progress", UniformType::_1f), + UniformName::new("clamped_progress", UniformType::_1f), + ], + &["tex_prev", "tex_next"], + ) { + Ok(program) => Some(program), + Err(err) => { + warn!("error compiling custom resize shader: {err:?}"); + return; + } + } + } else { + None + }; + + if let Some(prev) = Shaders::get(renderer).replace_custom_resize_program(program) { + if let Err(err) = prev.destroy(renderer) { + warn!("error destroying previous custom resize shader: {err:?}"); + } + } +} diff --git a/src/render_helpers/shaders/resize.frag b/src/render_helpers/shaders/resize.frag new file mode 100644 index 00000000..d77b9163 --- /dev/null +++ b/src/render_helpers/shaders/resize.frag @@ -0,0 +1,41 @@ +#version 100 + +precision mediump float; + +varying vec2 v_coords; +uniform vec2 size; + +uniform mat3 input_to_curr_geo; +uniform mat3 input_to_prev_geo; +uniform mat3 input_to_next_geo; + +uniform sampler2D tex_prev; +uniform mat3 geo_to_tex_prev; + +uniform sampler2D tex_next; +uniform mat3 geo_to_tex_next; + +uniform float progress; +uniform float clamped_progress; + +uniform float alpha; + +vec4 crossfade() { + vec3 coords_curr_geo = input_to_curr_geo * vec3(v_coords, 1.0); + + vec3 coords_tex_prev = geo_to_tex_prev * coords_curr_geo; + vec4 color_prev = texture2D(tex_prev, vec2(coords_tex_prev)); + + vec3 coords_tex_next = geo_to_tex_next * coords_curr_geo; + vec4 color_next = texture2D(tex_next, vec2(coords_tex_next)); + + vec4 color = mix(color_prev, color_next, clamped_progress); + return color; +} + +void main() { + vec4 color = crossfade(); + + gl_FragColor = color * alpha; +} + |
