shader_element: Store and set location separately

This commit is contained in:
Ivan Molodetskikh
2024-05-04 09:49:32 +04:00
parent 7aab413048
commit 69aeba2a4d
7 changed files with 75 additions and 55 deletions
@@ -62,15 +62,16 @@ impl TestCase for GradientAngle {
let area = Rectangle::from_loc_and_size((a, b), size); let area = Rectangle::from_loc_and_size((a, b), size);
[BorderRenderElement::new( [BorderRenderElement::new(
area, area.size,
area, Rectangle::from_loc_and_size((0, 0), area.size),
[1., 0., 0., 1.], [1., 0., 0., 1.],
[0., 1., 0., 1.], [0., 1., 0., 1.],
self.angle - FRAC_PI_2, self.angle - FRAC_PI_2,
area, Rectangle::from_loc_and_size((0, 0), area.size),
0., 0.,
CornerRadius::default(), CornerRadius::default(),
)] )
.with_location(area.loc)]
.into_iter() .into_iter()
.map(|elem| Box::new(elem) as _) .map(|elem| Box::new(elem) as _)
.collect() .collect()
+6 -4
View File
@@ -83,7 +83,8 @@ impl TestCase for GradientArea {
(size.h as f32 / 8. + size.h as f32 / 8. * 7. * f).round() as i32, (size.h as f32 / 8. + size.h as f32 / 8. * 7. * f).round() as i32,
)); ));
let g_loc = ((size.w - g_size.w) / 2, (size.h - g_size.h) / 2); let g_loc = ((size.w - g_size.w) / 2, (size.h - g_size.h) / 2);
let g_area = Rectangle::from_loc_and_size(g_loc, g_size); let mut g_area = Rectangle::from_loc_and_size(g_loc, g_size);
g_area.loc -= area.loc;
self.border.update(g_size, true, CornerRadius::default()); self.border.update(g_size, true, CornerRadius::default());
rv.extend( rv.extend(
@@ -99,15 +100,16 @@ impl TestCase for GradientArea {
rv.extend( rv.extend(
[BorderRenderElement::new( [BorderRenderElement::new(
area, area.size,
g_area, g_area,
[1., 0., 0., 1.], [1., 0., 0., 1.],
[0., 1., 0., 1.], [0., 1., 0., 1.],
FRAC_PI_4, FRAC_PI_4,
area, Rectangle::from_loc_and_size((0, 0), rect_size),
0., 0.,
CornerRadius::default(), CornerRadius::default(),
)] )
.with_location(area.loc)]
.into_iter() .into_iter()
.map(|elem| Box::new(elem) as _), .map(|elem| Box::new(elem) as _),
); );
+7 -4
View File
@@ -194,6 +194,9 @@ impl FocusRing {
border: &mut BorderRenderElement, border: &mut BorderRenderElement,
location: Point<i32, Logical>, location: Point<i32, Logical>,
size: Size<i32, Logical>| { size: Size<i32, Logical>| {
let full_rect = Rectangle::from_loc_and_size(full_rect.loc - location, full_rect.size);
let view_rect = Rectangle::from_loc_and_size(view_rect.loc - location, view_rect.size);
let elem = if has_border_shader { let elem = if has_border_shader {
if let Some(gradient) = gradient { if let Some(gradient) = gradient {
let gradient_area = match gradient.relative_to { let gradient_area = match gradient.relative_to {
@@ -201,7 +204,7 @@ impl FocusRing {
GradientRelativeTo::WorkspaceView => view_rect, GradientRelativeTo::WorkspaceView => view_rect,
}; };
border.update( border.update(
Rectangle::from_loc_and_size(location, size), size,
gradient_area, gradient_area,
gradient.from.into(), gradient.from.into(),
gradient.to.into(), gradient.to.into(),
@@ -210,10 +213,10 @@ impl FocusRing {
border_width, border_width,
self.radius, self.radius,
); );
Some(border.clone().into()) Some(border.clone().with_location(location).into())
} else if self.radius != CornerRadius::default() { } else if self.radius != CornerRadius::default() {
border.update( border.update(
Rectangle::from_loc_and_size(location, size), size,
full_rect, full_rect,
color.into(), color.into(),
color.into(), color.into(),
@@ -222,7 +225,7 @@ impl FocusRing {
border_width, border_width,
self.radius, self.radius,
); );
Some(border.clone().into()) Some(border.clone().with_location(location).into())
} else { } else {
None None
} }
+5 -3
View File
@@ -720,16 +720,18 @@ impl<W: LayoutElement> Tile<W> {
// user-provided radius, so our blocked-out rendering should match that // user-provided radius, so our blocked-out rendering should match that
// radius. // radius.
if radius != CornerRadius::default() && has_border_shader { if radius != CornerRadius::default() && has_border_shader {
let elem_geo = elem.geometry(Scale::from(1.)).to_logical(1);
return BorderRenderElement::new( return BorderRenderElement::new(
elem.geometry(Scale::from(1.)).to_logical(1), elem_geo.size,
Rectangle::from_loc_and_size(Point::from((0, 0)), geo.size), Rectangle::from_loc_and_size((0, 0), elem_geo.size),
elem.color(), elem.color(),
elem.color(), elem.color(),
0., 0.,
elem.geometry(Scale::from(1.)).to_logical(1), Rectangle::from_loc_and_size(geo.loc - elem_geo.loc, geo.size),
0., 0.,
radius, radius,
) )
.with_location(elem_geo.loc)
.into(); .into();
} }
+16 -12
View File
@@ -5,7 +5,7 @@ use niri_config::CornerRadius;
use smithay::backend::renderer::element::{Element, Id, Kind, RenderElement, UnderlyingStorage}; use smithay::backend::renderer::element::{Element, Id, Kind, RenderElement, UnderlyingStorage};
use smithay::backend::renderer::gles::{GlesError, GlesFrame, GlesRenderer, Uniform}; use smithay::backend::renderer::gles::{GlesError, GlesFrame, GlesRenderer, Uniform};
use smithay::backend::renderer::utils::{CommitCounter, DamageSet}; use smithay::backend::renderer::utils::{CommitCounter, DamageSet};
use smithay::utils::{Buffer, Logical, Physical, Rectangle, Scale, Transform}; use smithay::utils::{Buffer, Logical, Physical, Point, Rectangle, Scale, Size, Transform};
use super::renderer::NiriRenderer; use super::renderer::NiriRenderer;
use super::shader_element::ShaderRenderElement; use super::shader_element::ShaderRenderElement;
@@ -26,7 +26,7 @@ pub struct BorderRenderElement {
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
struct Parameters { struct Parameters {
area: Rectangle<i32, Logical>, size: Size<i32, Logical>,
gradient_area: Rectangle<i32, Logical>, gradient_area: Rectangle<i32, Logical>,
color_from: [f32; 4], color_from: [f32; 4],
color_to: [f32; 4], color_to: [f32; 4],
@@ -39,7 +39,7 @@ struct Parameters {
impl BorderRenderElement { impl BorderRenderElement {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn new( pub fn new(
area: Rectangle<i32, Logical>, size: Size<i32, Logical>,
gradient_area: Rectangle<i32, Logical>, gradient_area: Rectangle<i32, Logical>,
color_from: [f32; 4], color_from: [f32; 4],
color_to: [f32; 4], color_to: [f32; 4],
@@ -52,7 +52,7 @@ impl BorderRenderElement {
let mut rv = Self { let mut rv = Self {
inner, inner,
params: Parameters { params: Parameters {
area, size,
gradient_area, gradient_area,
color_from, color_from,
color_to, color_to,
@@ -71,7 +71,7 @@ impl BorderRenderElement {
Self { Self {
inner, inner,
params: Parameters { params: Parameters {
area: Default::default(), size: Default::default(),
gradient_area: Default::default(), gradient_area: Default::default(),
color_from: Default::default(), color_from: Default::default(),
color_to: Default::default(), color_to: Default::default(),
@@ -90,7 +90,7 @@ impl BorderRenderElement {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn update( pub fn update(
&mut self, &mut self,
area: Rectangle<i32, Logical>, size: Size<i32, Logical>,
gradient_area: Rectangle<i32, Logical>, gradient_area: Rectangle<i32, Logical>,
color_from: [f32; 4], color_from: [f32; 4],
color_to: [f32; 4], color_to: [f32; 4],
@@ -100,7 +100,7 @@ impl BorderRenderElement {
corner_radius: CornerRadius, corner_radius: CornerRadius,
) { ) {
let params = Parameters { let params = Parameters {
area, size,
gradient_area, gradient_area,
color_from, color_from,
color_to, color_to,
@@ -119,7 +119,7 @@ impl BorderRenderElement {
fn update_inner(&mut self) { fn update_inner(&mut self) {
let Parameters { let Parameters {
area, size,
gradient_area, gradient_area,
color_from, color_from,
color_to, color_to,
@@ -146,17 +146,16 @@ impl BorderRenderElement {
grad_vec = -grad_vec; grad_vec = -grad_vec;
} }
let area_loc = Vec2::new(area.loc.x as f32, area.loc.y as f32); let area_size = Vec2::new(size.w as f32, size.h as f32);
let area_size = Vec2::new(area.size.w as f32, area.size.h as f32);
let geo_loc = Vec2::new(geometry.loc.x as f32, geometry.loc.y as f32); let geo_loc = Vec2::new(geometry.loc.x as f32, geometry.loc.y as f32);
let geo_size = Vec2::new(geometry.size.w as f32, geometry.size.h as f32); let geo_size = Vec2::new(geometry.size.w as f32, geometry.size.h as f32);
let input_to_geo = let input_to_geo =
Mat3::from_scale(area_size) * Mat3::from_translation((area_loc - geo_loc) / area_size); Mat3::from_scale(area_size) * Mat3::from_translation(-geo_loc / area_size);
self.inner.update( self.inner.update(
area, size,
None, None,
vec![ vec![
Uniform::new("color_from", color_from), Uniform::new("color_from", color_from),
@@ -173,6 +172,11 @@ impl BorderRenderElement {
); );
} }
pub fn with_location(mut self, location: Point<i32, Logical>) -> Self {
self.inner = self.inner.with_location(location);
self
}
pub fn has_shader(renderer: &mut impl NiriRenderer) -> bool { pub fn has_shader(renderer: &mut impl NiriRenderer) -> bool {
Shaders::get(renderer) Shaders::get(renderer)
.program(ProgramType::Border) .program(ProgramType::Border)
+6 -3
View File
@@ -85,9 +85,10 @@ impl ResizeRenderElement {
let clip_to_geometry = if clip_to_geometry { 1. } else { 0. }; let clip_to_geometry = if clip_to_geometry { 1. } else { 0. };
// Create the shader. // Create the shader.
Self(ShaderRenderElement::new( Self(
ShaderRenderElement::new(
ProgramType::Resize, ProgramType::Resize,
area, area.size,
None, None,
result_alpha, result_alpha,
vec![ vec![
@@ -107,7 +108,9 @@ impl ResizeRenderElement {
(String::from("niri_tex_next"), texture_next), (String::from("niri_tex_next"), texture_next),
]), ]),
Kind::Unspecified, Kind::Unspecified,
)) )
.with_location(area.loc),
)
} }
pub fn has_shader(renderer: &mut impl NiriRenderer) -> bool { pub fn has_shader(renderer: &mut impl NiriRenderer) -> bool {
+10 -5
View File
@@ -10,7 +10,7 @@ use smithay::backend::renderer::gles::{
}; };
use smithay::backend::renderer::utils::CommitCounter; use smithay::backend::renderer::utils::CommitCounter;
use smithay::backend::renderer::DebugFlags; use smithay::backend::renderer::DebugFlags;
use smithay::utils::{Buffer, Logical, Physical, Rectangle, Scale}; use smithay::utils::{Buffer, Logical, Physical, Point, Rectangle, Scale, Size};
use super::renderer::AsGlesFrame; use super::renderer::AsGlesFrame;
use super::resources::Resources; use super::resources::Resources;
@@ -198,7 +198,7 @@ impl ShaderRenderElement {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn new( pub fn new(
program: ProgramType, program: ProgramType,
area: Rectangle<i32, Logical>, size: Size<i32, Logical>,
opaque_regions: Option<Vec<Rectangle<i32, Logical>>>, opaque_regions: Option<Vec<Rectangle<i32, Logical>>>,
alpha: f32, alpha: f32,
uniforms: Vec<Uniform<'_>>, uniforms: Vec<Uniform<'_>>,
@@ -209,7 +209,7 @@ impl ShaderRenderElement {
program, program,
id: Id::new(), id: Id::new(),
commit_counter: CommitCounter::default(), commit_counter: CommitCounter::default(),
area, area: Rectangle::from_loc_and_size((0, 0), size),
opaque_regions: opaque_regions.unwrap_or_default(), opaque_regions: opaque_regions.unwrap_or_default(),
alpha, alpha,
additional_uniforms: uniforms.into_iter().map(|u| u.into_owned()).collect(), additional_uniforms: uniforms.into_iter().map(|u| u.into_owned()).collect(),
@@ -238,18 +238,23 @@ impl ShaderRenderElement {
pub fn update( pub fn update(
&mut self, &mut self,
area: Rectangle<i32, Logical>, size: Size<i32, Logical>,
opaque_regions: Option<Vec<Rectangle<i32, Logical>>>, opaque_regions: Option<Vec<Rectangle<i32, Logical>>>,
uniforms: Vec<Uniform<'_>>, uniforms: Vec<Uniform<'_>>,
textures: HashMap<String, GlesTexture>, textures: HashMap<String, GlesTexture>,
) { ) {
self.area = area; self.area.size = size;
self.opaque_regions = opaque_regions.unwrap_or_default(); self.opaque_regions = opaque_regions.unwrap_or_default();
self.additional_uniforms = uniforms.into_iter().map(|u| u.into_owned()).collect(); self.additional_uniforms = uniforms.into_iter().map(|u| u.into_owned()).collect();
self.textures = textures; self.textures = textures;
self.commit_counter.increment(); self.commit_counter.increment();
} }
pub fn with_location(mut self, location: Point<i32, Logical>) -> Self {
self.area.loc = location;
self
}
} }
impl Element for ShaderRenderElement { impl Element for ShaderRenderElement {