mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-21 02:01:55 +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,
|
||||
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(())
|
||||
|
||||
Reference in New Issue
Block a user