clipped surface: Compute uniforms on-demand

Removes two allocations for every clipped surface.
This commit is contained in:
Ivan Molodetskikh
2025-12-23 12:30:40 +03:00
parent f01d48bc51
commit 4d295418ce
+26 -21
View File
@@ -19,7 +19,7 @@ pub struct ClippedSurfaceRenderElement<R: NiriRenderer> {
program: GlesTexProgram,
corner_radius: CornerRadius,
geometry: Rectangle<f64, Logical>,
uniforms: Vec<Uniform<'static>>,
scale: f32,
}
#[derive(Debug, Default, Clone)]
@@ -36,23 +36,34 @@ impl<R: NiriRenderer> ClippedSurfaceRenderElement<R> {
program: GlesTexProgram,
corner_radius: CornerRadius,
) -> 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_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_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 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_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.
let transform = match transform {
Transform::_90 => Transform::_270,
@@ -70,20 +81,14 @@ impl<R: NiriRenderer> ClippedSurfaceRenderElement<R> {
* Mat3::from_scale(buf_size / src_size)
* Mat3::from_translation(-src_loc / buf_size);
let uniforms = vec![
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),
];
let geo_size = (self.geometry.size.w as f32, self.geometry.size.h as f32);
Self {
inner: elem,
program,
corner_radius,
geometry,
uniforms,
}
vec![
Uniform::new("niri_scale", self.scale),
Uniform::new("geo_size", geo_size),
Uniform::new("corner_radius", <[f32; 4]>::from(self.corner_radius)),
mat3_uniform("input_to_geo", input_to_geo),
]
}
pub fn shader(renderer: &mut R) -> Option<&GlesTexProgram> {
@@ -224,7 +229,7 @@ impl RenderElement<GlesRenderer> for ClippedSurfaceRenderElement<GlesRenderer> {
damage: &[Rectangle<i32, Physical>],
opaque_regions: &[Rectangle<i32, Physical>],
) -> 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)?;
frame.clear_tex_program_override();
Ok(())
@@ -250,7 +255,7 @@ impl<'render> RenderElement<TtyRenderer<'render>>
) -> Result<(), TtyRendererError<'render>> {
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)?;
frame.as_gles_frame().clear_tex_program_override();
Ok(())