mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-24 02:01:18 +07:00
clipped surface: Compute uniforms on-demand
Removes two allocations for every clipped surface.
This commit is contained in:
@@ -19,7 +19,7 @@ pub struct ClippedSurfaceRenderElement<R: NiriRenderer> {
|
|||||||
program: GlesTexProgram,
|
program: GlesTexProgram,
|
||||||
corner_radius: CornerRadius,
|
corner_radius: CornerRadius,
|
||||||
geometry: Rectangle<f64, Logical>,
|
geometry: Rectangle<f64, Logical>,
|
||||||
uniforms: Vec<Uniform<'static>>,
|
scale: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
@@ -36,23 +36,34 @@ impl<R: NiriRenderer> ClippedSurfaceRenderElement<R> {
|
|||||||
program: GlesTexProgram,
|
program: GlesTexProgram,
|
||||||
corner_radius: CornerRadius,
|
corner_radius: CornerRadius,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let elem_geo = elem.geometry(scale);
|
Self {
|
||||||
|
inner: elem,
|
||||||
|
program,
|
||||||
|
corner_radius,
|
||||||
|
geometry,
|
||||||
|
scale: scale.x as f32,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compute_uniforms(&self) -> Vec<Uniform<'static>> {
|
||||||
|
let scale = Scale::from(f64::from(self.scale));
|
||||||
|
let elem_geo = self.inner.geometry(scale);
|
||||||
|
|
||||||
let elem_geo_loc = Vec2::new(elem_geo.loc.x as f32, elem_geo.loc.y as f32);
|
let elem_geo_loc = Vec2::new(elem_geo.loc.x as f32, elem_geo.loc.y as f32);
|
||||||
let elem_geo_size = Vec2::new(elem_geo.size.w as f32, elem_geo.size.h as f32);
|
let elem_geo_size = Vec2::new(elem_geo.size.w as f32, elem_geo.size.h as f32);
|
||||||
|
|
||||||
let geo = geometry.to_physical_precise_round(scale);
|
let geo = self.geometry.to_physical_precise_round(scale);
|
||||||
let geo_loc = Vec2::new(geo.loc.x, geo.loc.y);
|
let geo_loc = Vec2::new(geo.loc.x, geo.loc.y);
|
||||||
let geo_size = Vec2::new(geo.size.w, geo.size.h);
|
let geo_size = Vec2::new(geo.size.w, geo.size.h);
|
||||||
|
|
||||||
let buf_size = elem.buffer_size();
|
let buf_size = self.inner.buffer_size();
|
||||||
let buf_size = Vec2::new(buf_size.w as f32, buf_size.h as f32);
|
let buf_size = Vec2::new(buf_size.w as f32, buf_size.h as f32);
|
||||||
|
|
||||||
let view = elem.view();
|
let view = self.inner.view();
|
||||||
let src_loc = Vec2::new(view.src.loc.x as f32, view.src.loc.y as f32);
|
let src_loc = Vec2::new(view.src.loc.x as f32, view.src.loc.y as f32);
|
||||||
let src_size = Vec2::new(view.src.size.w as f32, view.src.size.h as f32);
|
let src_size = Vec2::new(view.src.size.w as f32, view.src.size.h as f32);
|
||||||
|
|
||||||
let transform = elem.transform();
|
let transform = self.inner.transform();
|
||||||
// HACK: ??? for some reason flipped ones are fine.
|
// HACK: ??? for some reason flipped ones are fine.
|
||||||
let transform = match transform {
|
let transform = match transform {
|
||||||
Transform::_90 => Transform::_270,
|
Transform::_90 => Transform::_270,
|
||||||
@@ -70,20 +81,14 @@ impl<R: NiriRenderer> ClippedSurfaceRenderElement<R> {
|
|||||||
* Mat3::from_scale(buf_size / src_size)
|
* Mat3::from_scale(buf_size / src_size)
|
||||||
* Mat3::from_translation(-src_loc / buf_size);
|
* Mat3::from_translation(-src_loc / buf_size);
|
||||||
|
|
||||||
let uniforms = vec![
|
let geo_size = (self.geometry.size.w as f32, self.geometry.size.h as f32);
|
||||||
Uniform::new("niri_scale", scale.x as f32),
|
|
||||||
Uniform::new("geo_size", (geometry.size.w as f32, geometry.size.h as f32)),
|
|
||||||
Uniform::new("corner_radius", <[f32; 4]>::from(corner_radius)),
|
|
||||||
mat3_uniform("input_to_geo", input_to_geo),
|
|
||||||
];
|
|
||||||
|
|
||||||
Self {
|
vec![
|
||||||
inner: elem,
|
Uniform::new("niri_scale", self.scale),
|
||||||
program,
|
Uniform::new("geo_size", geo_size),
|
||||||
corner_radius,
|
Uniform::new("corner_radius", <[f32; 4]>::from(self.corner_radius)),
|
||||||
geometry,
|
mat3_uniform("input_to_geo", input_to_geo),
|
||||||
uniforms,
|
]
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shader(renderer: &mut R) -> Option<&GlesTexProgram> {
|
pub fn shader(renderer: &mut R) -> Option<&GlesTexProgram> {
|
||||||
@@ -224,7 +229,7 @@ impl RenderElement<GlesRenderer> for ClippedSurfaceRenderElement<GlesRenderer> {
|
|||||||
damage: &[Rectangle<i32, Physical>],
|
damage: &[Rectangle<i32, Physical>],
|
||||||
opaque_regions: &[Rectangle<i32, Physical>],
|
opaque_regions: &[Rectangle<i32, Physical>],
|
||||||
) -> Result<(), GlesError> {
|
) -> Result<(), GlesError> {
|
||||||
frame.override_default_tex_program(self.program.clone(), self.uniforms.clone());
|
frame.override_default_tex_program(self.program.clone(), self.compute_uniforms());
|
||||||
RenderElement::<GlesRenderer>::draw(&self.inner, frame, src, dst, damage, opaque_regions)?;
|
RenderElement::<GlesRenderer>::draw(&self.inner, frame, src, dst, damage, opaque_regions)?;
|
||||||
frame.clear_tex_program_override();
|
frame.clear_tex_program_override();
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -250,7 +255,7 @@ impl<'render> RenderElement<TtyRenderer<'render>>
|
|||||||
) -> Result<(), TtyRendererError<'render>> {
|
) -> Result<(), TtyRendererError<'render>> {
|
||||||
frame
|
frame
|
||||||
.as_gles_frame()
|
.as_gles_frame()
|
||||||
.override_default_tex_program(self.program.clone(), self.uniforms.clone());
|
.override_default_tex_program(self.program.clone(), self.compute_uniforms());
|
||||||
RenderElement::draw(&self.inner, frame, src, dst, damage, opaque_regions)?;
|
RenderElement::draw(&self.inner, frame, src, dst, damage, opaque_regions)?;
|
||||||
frame.as_gles_frame().clear_tex_program_override();
|
frame.as_gles_frame().clear_tex_program_override();
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
Reference in New Issue
Block a user