diff options
Diffstat (limited to 'src/layout')
| -rw-r--r-- | src/layout/closing_window.rs | 60 | ||||
| -rw-r--r-- | src/layout/workspace.rs | 4 |
2 files changed, 56 insertions, 8 deletions
diff --git a/src/layout/closing_window.rs b/src/layout/closing_window.rs index c1f4e599..bdeb73a5 100644 --- a/src/layout/closing_window.rs +++ b/src/layout/closing_window.rs @@ -1,6 +1,8 @@ +use std::collections::HashMap; use std::time::Duration; use anyhow::Context as _; +use glam::{Mat3, Vec2}; use niri_config::BlockOutFrom; use smithay::backend::allocator::Fourcc; use smithay::backend::renderer::element::texture::TextureRenderElement; @@ -8,13 +10,15 @@ use smithay::backend::renderer::element::utils::{ Relocate, RelocateRenderElement, RescaleRenderElement, }; use smithay::backend::renderer::element::{Id, Kind, RenderElement}; -use smithay::backend::renderer::gles::{GlesRenderer, GlesTexture}; -use smithay::backend::renderer::Renderer as _; +use smithay::backend::renderer::gles::{GlesRenderer, GlesTexture, Uniform}; +use smithay::backend::renderer::{Renderer as _, Texture}; use smithay::utils::{Logical, Point, Rectangle, Scale, Size, Transform}; use crate::animation::Animation; use crate::niri_render_elements; use crate::render_helpers::primary_gpu_texture::PrimaryGpuTextureRenderElement; +use crate::render_helpers::shader_element::ShaderRenderElement; +use crate::render_helpers::shaders::{mat3_uniform, ProgramType, Shaders}; use crate::render_helpers::snapshot::RenderSnapshot; use crate::render_helpers::{render_to_encompassing_texture, RenderTarget}; @@ -49,11 +53,15 @@ pub struct ClosingWindow { /// The closing animation. anim: Animation, + + /// Random seed for the shader. + random_seed: f32, } niri_render_elements! { ClosingWindowRenderElement => { Texture = RelocateRenderElement<RescaleRenderElement<PrimaryGpuTextureRenderElement>>, + Shader = ShaderRenderElement, } } @@ -100,6 +108,7 @@ impl ClosingWindow { texture_offset, blocked_out_texture_offset, anim, + random_seed: fastrand::f32(), }) } @@ -108,16 +117,18 @@ impl ClosingWindow { } pub fn are_animations_ongoing(&self) -> bool { - !self.anim.is_clamped_done() + !self.anim.is_done() } pub fn render( &self, + renderer: &mut GlesRenderer, view_rect: Rectangle<i32, Logical>, scale: Scale<f64>, target: RenderTarget, ) -> ClosingWindowRenderElement { - let val = self.anim.clamped_value(); + let progress = self.anim.value(); + let clamped_progress = self.anim.clamped_value().clamp(0., 1.); let (texture, offset) = if target.should_block_out(self.block_out_from) { (&self.blocked_out_texture, self.blocked_out_texture_offset) @@ -125,6 +136,43 @@ impl ClosingWindow { (&self.texture, self.texture_offset) }; + if Shaders::get(renderer).program(ProgramType::Close).is_some() { + let area_loc = Vec2::new(view_rect.loc.x as f32, view_rect.loc.y as f32); + let area_size = Vec2::new(view_rect.size.w as f32, view_rect.size.h as f32); + + let geo_loc = Vec2::new(self.pos.x as f32, self.pos.y as f32); + let geo_size = Vec2::new(self.geo_size.w as f32, self.geo_size.h as f32); + + let input_to_geo = Mat3::from_scale(area_size / geo_size) + * Mat3::from_translation((area_loc - geo_loc) / area_size); + + let tex_scale = Vec2::new(self.texture_scale.x as f32, self.texture_scale.y as f32); + let tex_loc = Vec2::new(offset.x as f32, offset.y as f32); + let tex_size = Vec2::new(texture.width() as f32, texture.height() as f32) / tex_scale; + + let geo_to_tex = + Mat3::from_translation(-tex_loc / tex_size) * Mat3::from_scale(geo_size / tex_size); + + return ShaderRenderElement::new( + ProgramType::Close, + view_rect.size, + None, + 1., + vec![ + mat3_uniform("niri_input_to_geo", input_to_geo), + Uniform::new("niri_geo_size", geo_size.to_array()), + mat3_uniform("niri_geo_to_tex", geo_to_tex), + Uniform::new("niri_progress", progress as f32), + Uniform::new("niri_clamped_progress", clamped_progress as f32), + Uniform::new("niri_random_seed", self.random_seed), + ], + HashMap::from([(String::from("niri_tex"), texture.clone())]), + Kind::Unspecified, + ) + .with_location(Point::from((0, 0))) + .into(); + } + let elem = TextureRenderElement::from_static_texture( Id::new(), self.texture_renderer_id, @@ -132,7 +180,7 @@ impl ClosingWindow { texture.clone(), self.texture_scale.x as i32, Transform::Normal, - Some(val.clamp(0., 1.) as f32), + Some(1. - clamped_progress as f32), None, None, None, @@ -145,7 +193,7 @@ impl ClosingWindow { let elem = RescaleRenderElement::from_element( elem, (center - offset).to_physical_precise_round(scale), - (val / 5. + 0.8).max(0.), + ((1. - clamped_progress) / 5. + 0.8).max(0.), ); let mut location = self.pos.to_f64() + offset; diff --git a/src/layout/workspace.rs b/src/layout/workspace.rs index a2515a76..08f170f8 100644 --- a/src/layout/workspace.rs +++ b/src/layout/workspace.rs @@ -1344,7 +1344,7 @@ impl<W: LayoutElement> Workspace<W> { tile_pos.x -= offset; } - let anim = Animation::new(1., 0., 0., self.options.animations.window_close.0); + let anim = Animation::new(0., 1., 0., self.options.animations.window_close.anim); let res = ClosingWindow::new( renderer, @@ -2095,7 +2095,7 @@ impl<W: LayoutElement> Workspace<W> { // Draw the closing windows on top. let view_rect = Rectangle::from_loc_and_size((self.view_pos(), 0), self.view_size); for closing in &self.closing_windows { - let elem = closing.render(view_rect, output_scale, target); + let elem = closing.render(renderer.as_gles_renderer(), view_rect, output_scale, target); rv.push(elem.into()); } |
