Bundle renderer and target into a RenderCtx

This commit is contained in:
Ivan Molodetskikh
2026-01-30 08:44:32 +03:00
parent 874e7fd70e
commit dd1f28998f
21 changed files with 273 additions and 293 deletions
+6 -4
View File
@@ -3,7 +3,7 @@ use std::time::Duration;
use niri::animation::Clock;
use niri::layout::{ActivateWindow, AddWindowTarget, LayoutElement as _, Options, SizingMode};
use niri::render_helpers::RenderTarget;
use niri::render_helpers::{RenderCtx, RenderTarget};
use niri_config::{Color, OutputName, PresetSize};
use smithay::backend::renderer::element::RenderElement;
use smithay::backend::renderer::gles::GlesRenderer;
@@ -270,12 +270,14 @@ impl TestCase for Layout {
self.layout.update_render_elements(Some(&self.output));
let mut rv = Vec::new();
let ctx = RenderCtx {
renderer,
target: RenderTarget::Output,
};
self.layout
.monitor_for_output(&self.output)
.unwrap()
.render_workspaces(renderer, RenderTarget::Output, true, &mut |elem| {
rv.push(Box::new(elem) as _)
});
.render_workspaces(ctx, true, &mut |elem| rv.push(Box::new(elem) as _));
rv
}
}
+7 -7
View File
@@ -2,7 +2,7 @@ use std::rc::Rc;
use std::time::Duration;
use niri::layout::Options;
use niri::render_helpers::RenderTarget;
use niri::render_helpers::{RenderCtx, RenderTarget};
use niri_config::Color;
use smithay::backend::renderer::element::RenderElement;
use smithay::backend::renderer::gles::GlesRenderer;
@@ -121,13 +121,13 @@ impl TestCase for Tile {
);
let mut rv = Vec::new();
self.tile.render(
let ctx = RenderCtx {
renderer,
location,
true,
RenderTarget::Output,
&mut |elem| rv.push(Box::new(elem) as _),
);
target: RenderTarget::Output,
};
self.tile.render(ctx, location, true, &mut |elem| {
rv.push(Box::new(elem) as _)
});
rv
}
}
+8 -8
View File
@@ -1,5 +1,5 @@
use niri::layout::{LayoutElement, SizingMode};
use niri::render_helpers::RenderTarget;
use niri::render_helpers::{RenderCtx, RenderTarget};
use smithay::backend::renderer::element::RenderElement;
use smithay::backend::renderer::gles::GlesRenderer;
use smithay::utils::{Physical, Point, Scale, Size};
@@ -53,14 +53,14 @@ impl TestCase for Window {
.downscale(2.);
let mut rv = Vec::new();
self.window.render_normal(
let ctx = RenderCtx {
renderer,
location,
Scale::from(1.),
1.,
RenderTarget::Output,
&mut |elem| rv.push(Box::new(elem) as _),
);
target: RenderTarget::Output,
};
self.window
.render_normal(ctx, location, Scale::from(1.), 1., &mut |elem| {
rv.push(Box::new(elem) as _)
});
rv
}
}
+2 -3
View File
@@ -9,7 +9,7 @@ use niri::layout::{
use niri::render_helpers::offscreen::OffscreenData;
use niri::render_helpers::renderer::NiriRenderer;
use niri::render_helpers::solid_color::{SolidColorBuffer, SolidColorRenderElement};
use niri::render_helpers::RenderTarget;
use niri::render_helpers::RenderCtx;
use niri::utils::transaction::Transaction;
use niri::window::ResolvedWindowRules;
use smithay::backend::renderer::element::Kind;
@@ -151,11 +151,10 @@ impl LayoutElement for TestWindow {
fn render_normal<R: NiriRenderer>(
&self,
_renderer: &mut R,
_ctx: RenderCtx<R>,
location: Point<f64, Logical>,
_scale: Scale<f64>,
alpha: f32,
_target: RenderTarget,
push: &mut dyn FnMut(LayoutElementRenderElement<R>),
) {
let inner = self.inner.borrow();
+6 -3
View File
@@ -67,7 +67,7 @@ use crate::frame_clock::FrameClock;
use crate::niri::{Niri, RedrawState, State};
use crate::render_helpers::debug::draw_damage;
use crate::render_helpers::renderer::AsGlesRenderer;
use crate::render_helpers::{resources, shaders, RenderTarget};
use crate::render_helpers::{resources, shaders, RenderCtx, RenderTarget};
use crate::utils::{get_monotonic_time, is_laptop_panel, logical_output, PanelOrientation};
const SUPPORTED_COLOR_FORMATS: [Fourcc; 4] = [
@@ -1865,8 +1865,11 @@ impl Tty {
};
// Render the elements.
let mut elements =
niri.render::<TtyRenderer>(&mut renderer, output, true, RenderTarget::Output);
let ctx = RenderCtx {
renderer: &mut renderer,
target: RenderTarget::Output,
};
let mut elements = niri.render(ctx, output, true);
// Visualize the damage, if enabled.
if niri.debug_draw_damage {
+6 -7
View File
@@ -21,7 +21,7 @@ use smithay::wayland::presentation::Refresh;
use super::{IpcOutputMap, OutputId, RenderResult};
use crate::niri::{Niri, RedrawState, State};
use crate::render_helpers::debug::draw_damage;
use crate::render_helpers::{resources, shaders, RenderTarget};
use crate::render_helpers::{resources, shaders, RenderCtx, RenderTarget};
use crate::utils::{get_monotonic_time, logical_output};
pub struct Winit {
@@ -182,12 +182,11 @@ impl Winit {
let _span = tracy_client::span!("Winit::render");
// Render the elements.
let mut elements = niri.render::<GlesRenderer>(
self.backend.renderer(),
output,
true,
RenderTarget::Output,
);
let ctx = RenderCtx {
renderer: self.backend.renderer(),
target: RenderTarget::Output,
};
let mut elements = niri.render(ctx, output, true);
// Visualize the damage, if enabled.
if niri.debug_draw_damage {
+5 -6
View File
@@ -13,7 +13,7 @@ use smithay::input::SeatHandler;
use smithay::utils::{Logical, Physical, Point, Scale, Size, Transform};
use crate::niri::State;
use crate::render_helpers::{render_and_download, RenderTarget};
use crate::render_helpers::{render_and_download, RenderCtx, RenderTarget};
pub struct PickColorGrab {
start_data: PointerGrabStartData<State>,
@@ -49,13 +49,12 @@ impl PickColorGrab {
let pos = pos_within_output.to_physical_precise_floor(scale);
let size = Size::<i32, Physical>::from((1, 1));
let elements = data.niri.render(
let ctx = RenderCtx {
renderer,
&output,
false,
// This is an interactive operation so we can render without blocking out.
RenderTarget::Output,
);
target: RenderTarget::Output,
};
let elements = data.niri.render(ctx, &output, false);
let mapping = match render_and_download(
renderer,
+8 -10
View File
@@ -14,7 +14,7 @@ use crate::render_helpers::renderer::NiriRenderer;
use crate::render_helpers::shadow::ShadowRenderElement;
use crate::render_helpers::solid_color::{SolidColorBuffer, SolidColorRenderElement};
use crate::render_helpers::surface::push_elements_from_surface_tree;
use crate::render_helpers::RenderTarget;
use crate::render_helpers::RenderCtx;
use crate::utils::{baba_is_float_offset, round_logical_in_physical};
#[derive(Debug)]
@@ -157,16 +157,15 @@ impl MappedLayer {
pub fn render_normal<R: NiriRenderer>(
&self,
renderer: &mut R,
ctx: RenderCtx<R>,
location: Point<f64, Logical>,
target: RenderTarget,
push: &mut dyn FnMut(LayerSurfaceRenderElement<R>),
) {
let scale = Scale::from(self.scale);
let alpha = self.rules.opacity.unwrap_or(1.).clamp(0., 1.);
let location = location + self.bob_offset();
if target.should_block_out(self.rules.block_out_from) {
if ctx.target.should_block_out(self.rules.block_out_from) {
// Round to physical pixels.
let location = location.to_physical_precise_round(scale).to_logical(scale);
@@ -184,7 +183,7 @@ impl MappedLayer {
let surface = self.surface.wl_surface();
push_elements_from_surface_tree(
renderer,
ctx.renderer,
surface,
buf_pos.to_physical_precise_round(scale),
scale,
@@ -196,21 +195,20 @@ impl MappedLayer {
let location = location.to_physical_precise_round(scale).to_logical(scale);
self.shadow
.render(renderer, location, &mut |elem| push(elem.into()));
.render(ctx.renderer, location, &mut |elem| push(elem.into()));
}
pub fn render_popups<R: NiriRenderer>(
&self,
renderer: &mut R,
ctx: RenderCtx<R>,
location: Point<f64, Logical>,
target: RenderTarget,
push: &mut dyn FnMut(LayerSurfaceRenderElement<R>),
) {
let scale = Scale::from(self.scale);
let alpha = self.rules.opacity.unwrap_or(1.).clamp(0., 1.);
let location = location + self.bob_offset();
if target.should_block_out(self.rules.block_out_from) {
if ctx.target.should_block_out(self.rules.block_out_from) {
return;
}
@@ -223,7 +221,7 @@ impl MappedLayer {
let offset = popup_offset - popup.geometry().loc;
push_elements_from_surface_tree(
renderer,
ctx.renderer,
popup.wl_surface(),
(buf_pos + offset.to_f64()).to_physical_precise_round(scale),
scale,
+7 -5
View File
@@ -21,7 +21,7 @@ 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::texture::{TextureBuffer, TextureRenderElement};
use crate::render_helpers::{render_to_encompassing_texture, RenderTarget};
use crate::render_helpers::{render_to_encompassing_texture, RenderCtx};
use crate::utils::transaction::TransactionBlocker;
#[derive(Debug)]
@@ -159,12 +159,11 @@ impl ClosingWindow {
pub fn render(
&self,
renderer: &mut GlesRenderer,
ctx: RenderCtx<GlesRenderer>,
view_rect: Rectangle<f64, Logical>,
scale: Scale<f64>,
target: RenderTarget,
) -> ClosingWindowRenderElement {
let (buffer, offset) = if target.should_block_out(self.block_out_from) {
let (buffer, offset) = if ctx.target.should_block_out(self.block_out_from) {
(&self.blocked_out_buffer, self.blocked_out_buffer_offset)
} else {
(&self.buffer, self.buffer_offset)
@@ -200,7 +199,10 @@ impl ClosingWindow {
let progress = anim.value();
let clamped_progress = anim.clamped_value().clamp(0., 1.);
if Shaders::get(renderer).program(ProgramType::Close).is_some() {
if Shaders::get(ctx.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);
+4 -7
View File
@@ -18,7 +18,7 @@ use super::{
use crate::animation::{Animation, Clock};
use crate::niri_render_elements;
use crate::render_helpers::renderer::NiriRenderer;
use crate::render_helpers::RenderTarget;
use crate::render_helpers::RenderCtx;
use crate::utils::transaction::TransactionBlocker;
use crate::utils::{
center_preferring_top_left_in_area, clamp_preferring_top_left_in_area, ensure_min_max_size,
@@ -1055,9 +1055,8 @@ impl<W: LayoutElement> FloatingSpace<W> {
pub fn render<R: NiriRenderer>(
&self,
renderer: &mut R,
mut ctx: RenderCtx<R>,
view_rect: Rectangle<f64, Logical>,
target: RenderTarget,
focus_ring: bool,
push: &mut dyn FnMut(FloatingSpaceRenderElement<R>),
) {
@@ -1067,7 +1066,7 @@ impl<W: LayoutElement> FloatingSpace<W> {
//
// FIXME: I guess this should rather preserve the stacking order when the window is closed.
for closing in self.closing_windows.iter().rev() {
let elem = closing.render(renderer.as_gles_renderer(), view_rect, scale, target);
let elem = closing.render(ctx.as_gles(), view_rect, scale);
push(elem.into());
}
@@ -1076,9 +1075,7 @@ impl<W: LayoutElement> FloatingSpace<W> {
// For the active tile, draw the focus ring.
let focus_ring = focus_ring && Some(tile.window().id()) == active.as_ref();
tile.render(renderer, tile_pos, focus_ring, target, &mut |elem| {
push(elem.into())
});
tile.render(ctx.r(), tile_pos, focus_ring, &mut |elem| push(elem.into()));
}
}
+16 -22
View File
@@ -64,7 +64,7 @@ use crate::render_helpers::renderer::NiriRenderer;
use crate::render_helpers::snapshot::RenderSnapshot;
use crate::render_helpers::solid_color::{SolidColorBuffer, SolidColorRenderElement};
use crate::render_helpers::texture::TextureBuffer;
use crate::render_helpers::{BakedBuffer, RenderTarget};
use crate::render_helpers::{BakedBuffer, RenderCtx};
use crate::rubber_band::RubberBand;
use crate::utils::transaction::{Transaction, TransactionBlocker};
use crate::utils::{
@@ -154,41 +154,38 @@ pub trait LayoutElement {
/// location.
fn render<R: NiriRenderer>(
&self,
renderer: &mut R,
mut ctx: RenderCtx<R>,
location: Point<f64, Logical>,
scale: Scale<f64>,
alpha: f32,
target: RenderTarget,
push: &mut dyn FnMut(LayoutElementRenderElement<R>),
) {
self.render_popups(renderer, location, scale, alpha, target, push);
self.render_normal(renderer, location, scale, alpha, target, push);
self.render_popups(ctx.r(), location, scale, alpha, push);
self.render_normal(ctx.r(), location, scale, alpha, push);
}
/// Renders the non-popup parts of the element.
fn render_normal<R: NiriRenderer>(
&self,
renderer: &mut R,
ctx: RenderCtx<R>,
location: Point<f64, Logical>,
scale: Scale<f64>,
alpha: f32,
target: RenderTarget,
push: &mut dyn FnMut(LayoutElementRenderElement<R>),
) {
let _ = (renderer, location, scale, alpha, target, push);
let _ = (ctx, location, scale, alpha, push);
}
/// Renders the popups of the element.
fn render_popups<R: NiriRenderer>(
&self,
renderer: &mut R,
ctx: RenderCtx<R>,
location: Point<f64, Logical>,
scale: Scale<f64>,
alpha: f32,
target: RenderTarget,
push: &mut dyn FnMut(LayoutElementRenderElement<R>),
) {
let _ = (renderer, location, scale, alpha, target, push);
let _ = (ctx, location, scale, alpha, push);
}
/// Requests the element to change its size.
@@ -4721,9 +4718,8 @@ impl<W: LayoutElement> Layout<W> {
pub fn render_interactive_move_for_output<R: NiriRenderer>(
&self,
renderer: &mut R,
ctx: RenderCtx<R>,
output: &Output,
target: RenderTarget,
push: &mut dyn FnMut(RescaleRenderElement<TileRenderElement<R>>),
) {
if self.update_render_elements_time != self.clock.now() {
@@ -4741,15 +4737,13 @@ impl<W: LayoutElement> Layout<W> {
let scale = Scale::from(move_.output.current_scale().fractional_scale());
let zoom = self.overview_zoom();
let location = move_.tile_render_location(zoom);
move_
.tile
.render(renderer, location, true, target, &mut |elem| {
push(RescaleRenderElement::from_element(
elem,
location.to_physical_precise_round(scale),
zoom,
));
});
move_.tile.render(ctx, location, true, &mut |elem| {
push(RescaleRenderElement::from_element(
elem,
location.to_physical_precise_round(scale),
zoom,
));
});
}
pub fn refresh(&mut self, is_active: bool) {
+5 -6
View File
@@ -24,7 +24,7 @@ use crate::niri_render_elements;
use crate::render_helpers::renderer::NiriRenderer;
use crate::render_helpers::shadow::ShadowRenderElement;
use crate::render_helpers::solid_color::SolidColorRenderElement;
use crate::render_helpers::RenderTarget;
use crate::render_helpers::RenderCtx;
use crate::rubber_band::RubberBand;
use crate::utils::transaction::Transaction;
use crate::utils::{
@@ -1669,8 +1669,7 @@ impl<W: LayoutElement> Monitor<W> {
pub fn render_workspaces<R: NiriRenderer>(
&self,
renderer: &mut R,
target: RenderTarget,
mut ctx: RenderCtx<R>,
focus_ring: bool,
push: &mut dyn FnMut(MonitorRenderElement<R>),
) {
@@ -1734,16 +1733,16 @@ impl<W: LayoutElement> Monitor<W> {
}};
}
ws.render_floating(renderer, target, focus_ring, push!());
ws.render_floating(ctx.r(), focus_ring, push!());
if let Some(loc) = insert_hint_render_loc {
if loc.workspace == InsertWorkspace::Existing(ws.id()) {
self.insert_hint_element
.render(renderer, loc.location, push!());
.render(ctx.renderer, loc.location, push!());
}
}
ws.render_scrolling(renderer, target, focus_ring, push!());
ws.render_scrolling(ctx.r(), focus_ring, push!());
}
}
+5 -8
View File
@@ -21,7 +21,7 @@ use crate::input::swipe_tracker::SwipeTracker;
use crate::layout::SizingMode;
use crate::niri_render_elements;
use crate::render_helpers::renderer::NiriRenderer;
use crate::render_helpers::RenderTarget;
use crate::render_helpers::RenderCtx;
use crate::utils::transaction::{Transaction, TransactionBlocker};
use crate::utils::ResizeEdge;
use crate::window::ResolvedWindowRules;
@@ -2899,8 +2899,7 @@ impl<W: LayoutElement> ScrollingSpace<W> {
pub fn render<R: NiriRenderer>(
&self,
renderer: &mut R,
target: RenderTarget,
mut ctx: RenderCtx<R>,
focus_ring: bool,
push: &mut dyn FnMut(ScrollingSpaceRenderElement<R>),
) {
@@ -2909,7 +2908,7 @@ impl<W: LayoutElement> ScrollingSpace<W> {
// Draw the closing windows on top of the other windows.
let view_rect = Rectangle::new(Point::from((self.view_pos(), 0.)), self.view_size);
for closing in self.closing_windows.iter().rev() {
let elem = closing.render(renderer.as_gles_renderer(), view_rect, scale, target);
let elem = closing.render(ctx.as_gles(), view_rect, scale);
push(elem.into());
}
@@ -2930,7 +2929,7 @@ impl<W: LayoutElement> ScrollingSpace<W> {
let pos = view_off + col_off + col_render_off;
let pos = pos.to_physical_precise_round(scale).to_logical(scale);
col.tab_indicator
.render(renderer, pos, &mut |elem| push(elem.into()));
.render(ctx.renderer, pos, &mut |elem| push(elem.into()));
}
for (tile, tile_off, visible) in col.tiles_in_render_order() {
@@ -2955,9 +2954,7 @@ impl<W: LayoutElement> ScrollingSpace<W> {
continue;
}
tile.render(renderer, tile_pos, focus_ring, target, &mut |elem| {
push(elem.into())
});
tile.render(ctx.r(), tile_pos, focus_ring, &mut |elem| push(elem.into()));
}
}
}
+48 -65
View File
@@ -27,7 +27,7 @@ use crate::render_helpers::resize::ResizeRenderElement;
use crate::render_helpers::shadow::ShadowRenderElement;
use crate::render_helpers::snapshot::RenderSnapshot;
use crate::render_helpers::solid_color::{SolidColorBuffer, SolidColorRenderElement};
use crate::render_helpers::RenderTarget;
use crate::render_helpers::{RenderCtx, RenderTarget};
use crate::utils::transaction::Transaction;
use crate::utils::{
baba_is_float_offset, round_logical_in_physical, round_logical_in_physical_max1,
@@ -1009,10 +1009,9 @@ impl<W: LayoutElement> Tile<W> {
fn render_inner<R: NiriRenderer>(
&self,
renderer: &mut R,
mut ctx: RenderCtx<R>,
location: Point<f64, Logical>,
focus_ring: bool,
target: RenderTarget,
push: &mut dyn FnMut(TileRenderElement<R>),
) {
let _span = tracy_client::span!("Tile::render_inner");
@@ -1058,48 +1057,43 @@ impl<W: LayoutElement> Tile<W> {
.scaled_by(1. - expanded_progress as f32);
// Popups go on top, whether it's resize or not.
self.window.render_popups(
renderer,
window_render_loc,
scale,
win_alpha,
target,
&mut |elem| push(elem.into()),
);
self.window
.render_popups(ctx.r(), window_render_loc, scale, win_alpha, &mut |elem| {
push(elem.into())
});
// If we're resizing, try to render a shader, or a fallback.
let mut pushed_resize = false;
if let Some(resize) = &self.resize_animation {
if ResizeRenderElement::has_shader(renderer) {
let gles_renderer = renderer.as_gles_renderer();
if ResizeRenderElement::has_shader(ctx.renderer) {
let mut ctx = ctx.as_gles();
if let Some(texture_from) = resize.snapshot.texture(gles_renderer, scale, target) {
if let Some(texture_from) = resize.snapshot.texture(ctx.r(), scale) {
let mut window_elements = Vec::new();
self.window.render_normal(
gles_renderer,
ctx.r(),
Point::from((0., 0.)),
scale,
1.,
target,
&mut |elem| window_elements.push(elem),
);
let current = resize
.offscreen
.render(gles_renderer, scale, &window_elements)
.render(ctx.renderer, scale, &window_elements)
.map_err(|err| warn!("error rendering window to texture: {err:?}"))
.ok();
// Clip blocked-out resizes unconditionally because they use solid color render
// elements.
let clip_to_geometry = if target
.should_block_out(resize.snapshot.block_out_from)
&& target.should_block_out(rules.block_out_from)
{
true
} else {
clip_to_geometry
};
let clip_to_geometry =
if ctx.target.should_block_out(resize.snapshot.block_out_from)
&& ctx.target.should_block_out(rules.block_out_from)
{
true
} else {
clip_to_geometry
};
if let Some((elem_current, _sync_point, mut data)) = current {
let texture_current = elem_current.texture().clone();
@@ -1148,12 +1142,12 @@ impl<W: LayoutElement> Tile<W> {
}
// If we're not resizing, render the window itself.
let has_border_shader = BorderRenderElement::has_shader(renderer);
let has_border_shader = BorderRenderElement::has_shader(ctx.renderer);
if !pushed_resize {
let geo = Rectangle::new(window_render_loc, window_size);
let radius = radius.fit_to(window_size.w as f32, window_size.h as f32);
let clip_shader = ClippedSurfaceRenderElement::shader(renderer).cloned();
let clip_shader = ClippedSurfaceRenderElement::shader(ctx.renderer).cloned();
let clip = |elem| match elem {
LayoutElementRenderElement::Wayland(elem) => {
// If we should clip to geometry, render a clipped window.
@@ -1210,14 +1204,10 @@ impl<W: LayoutElement> Tile<W> {
push(damage.with_location(window_render_loc).into());
}
self.window.render_normal(
renderer,
window_render_loc,
scale,
win_alpha,
target,
&mut |elem| push(clip(elem)),
);
self.window
.render_normal(ctx.r(), window_render_loc, scale, win_alpha, &mut |elem| {
push(clip(elem))
});
}
if fullscreen_progress > 0. {
@@ -1264,7 +1254,7 @@ impl<W: LayoutElement> Tile<W> {
if let Some(width) = self.visual_border_width() {
self.border.render(
renderer,
ctx.renderer,
location + Point::from((width, width)),
&mut |elem| push(elem.into()),
);
@@ -1276,21 +1266,20 @@ impl<W: LayoutElement> Tile<W> {
// a bit weird).
if focus_ring && expanded_progress < 1. {
self.focus_ring
.render(renderer, location, &mut |elem| push(elem.into()));
.render(ctx.renderer, location, &mut |elem| push(elem.into()));
}
if expanded_progress < 1. {
self.shadow
.render(renderer, location, &mut |elem| push(elem.into()));
.render(ctx.renderer, location, &mut |elem| push(elem.into()));
}
}
pub fn render<R: NiriRenderer>(
&self,
renderer: &mut R,
mut ctx: RenderCtx<R>,
location: Point<f64, Logical>,
focus_ring: bool,
target: RenderTarget,
push: &mut dyn FnMut(TileRenderElement<R>),
) {
let _span = tracy_client::span!("Tile::render");
@@ -1306,17 +1295,13 @@ impl<W: LayoutElement> Tile<W> {
self.window().set_offscreen_data(None);
if let Some(open) = &self.open_animation {
let renderer = renderer.as_gles_renderer();
let mut ctx = ctx.as_gles();
let mut elements = Vec::new();
self.render_inner(
renderer,
Point::from((0., 0.)),
focus_ring,
target,
&mut |elem| elements.push(elem),
);
self.render_inner(ctx.r(), Point::from((0., 0.)), focus_ring, &mut |elem| {
elements.push(elem)
});
match open.render(
renderer,
ctx.renderer,
&elements,
self.animated_tile_size(),
location,
@@ -1333,16 +1318,12 @@ impl<W: LayoutElement> Tile<W> {
}
}
} else if let Some(alpha) = &self.alpha_animation {
let renderer = renderer.as_gles_renderer();
let mut ctx = ctx.as_gles();
let mut elements = Vec::new();
self.render_inner(
renderer,
Point::from((0., 0.)),
focus_ring,
target,
&mut |elem| elements.push(elem),
);
match alpha.offscreen.render(renderer, scale, &elements) {
self.render_inner(ctx.r(), Point::from((0., 0.)), focus_ring, &mut |elem| {
elements.push(elem)
});
match alpha.offscreen.render(ctx.renderer, scale, &elements) {
Ok((elem, _sync, data)) => {
let offset = elem.offset();
let elem = elem.with_alpha(tile_alpha).with_offset(location + offset);
@@ -1358,9 +1339,7 @@ impl<W: LayoutElement> Tile<W> {
}
if !pushed {
self.render_inner(renderer, location, focus_ring, target, &mut |elem| {
push(elem)
});
self.render_inner(ctx, location, focus_ring, &mut |elem| push(elem));
}
}
@@ -1377,20 +1356,24 @@ impl<W: LayoutElement> Tile<W> {
let mut contents = Vec::new();
self.render(
renderer,
RenderCtx {
renderer,
target: RenderTarget::Output,
},
Point::from((0., 0.)),
false,
RenderTarget::Output,
&mut |elem| contents.push(elem),
);
// A bit of a hack to render blocked out as for screencast, but I think it's fine here.
let mut blocked_out_contents = Vec::new();
self.render(
renderer,
RenderCtx {
renderer,
target: RenderTarget::Screencast,
},
Point::from((0., 0.)),
false,
RenderTarget::Screencast,
&mut |elem| blocked_out_contents.push(elem),
);
+8 -15
View File
@@ -32,7 +32,7 @@ use crate::niri_render_elements;
use crate::render_helpers::renderer::NiriRenderer;
use crate::render_helpers::shadow::ShadowRenderElement;
use crate::render_helpers::solid_color::{SolidColorBuffer, SolidColorRenderElement};
use crate::render_helpers::RenderTarget;
use crate::render_helpers::RenderCtx;
use crate::utils::id::IdCounter;
use crate::utils::transaction::{Transaction, TransactionBlocker};
use crate::utils::{
@@ -1626,22 +1626,18 @@ impl<W: LayoutElement> Workspace<W> {
pub fn render_scrolling<R: NiriRenderer>(
&self,
renderer: &mut R,
target: RenderTarget,
ctx: RenderCtx<R>,
focus_ring: bool,
push: &mut dyn FnMut(WorkspaceRenderElement<R>),
) {
let scrolling_focus_ring = focus_ring && !self.floating_is_active();
self.scrolling
.render(renderer, target, scrolling_focus_ring, &mut |elem| {
push(elem.into())
});
.render(ctx, scrolling_focus_ring, &mut |elem| push(elem.into()));
}
pub fn render_floating<R: NiriRenderer>(
&self,
renderer: &mut R,
target: RenderTarget,
ctx: RenderCtx<R>,
focus_ring: bool,
push: &mut dyn FnMut(WorkspaceRenderElement<R>),
) {
@@ -1651,13 +1647,10 @@ impl<W: LayoutElement> Workspace<W> {
let view_rect = Rectangle::from_size(self.view_size);
let floating_focus_ring = focus_ring && self.floating_is_active();
self.floating.render(
renderer,
view_rect,
target,
floating_focus_ring,
&mut |elem| push(elem.into()),
);
self.floating
.render(ctx, view_rect, floating_focus_ring, &mut |elem| {
push(elem.into())
});
}
pub fn render_shadow<R: NiriRenderer>(
+54 -57
View File
@@ -156,7 +156,7 @@ use crate::render_helpers::surface::push_elements_from_surface_tree;
use crate::render_helpers::texture::TextureBuffer;
use crate::render_helpers::{
encompassing_geo, render_to_dmabuf, render_to_encompassing_texture, render_to_shm,
render_to_texture, render_to_vec, shaders, RenderTarget,
render_to_texture, render_to_vec, shaders, RenderCtx, RenderTarget,
};
#[cfg(feature = "xdp-gnome-screencast")]
use crate::screencasting::Screencasting;
@@ -4021,13 +4021,12 @@ impl Niri {
pub fn render<R: NiriRenderer>(
&self,
renderer: &mut R,
ctx: RenderCtx<R>,
output: &Output,
include_pointer: bool,
target: RenderTarget,
) -> Vec<OutputRenderElements<R>> {
let mut elements = Vec::new();
self.render_inner(renderer, output, include_pointer, target, &mut |elem| {
self.render_inner(ctx, output, include_pointer, &mut |elem| {
elements.push(elem)
});
elements
@@ -4035,17 +4034,16 @@ impl Niri {
pub fn render_inner<R: NiriRenderer>(
&self,
renderer: &mut R,
mut ctx: RenderCtx<R>,
output: &Output,
include_pointer: bool,
mut target: RenderTarget,
push: &mut dyn FnMut(OutputRenderElements<R>),
) {
let _span = tracy_client::span!("Niri::render");
if target == RenderTarget::Output {
if ctx.target == RenderTarget::Output {
if let Some(preview) = self.config.borrow().debug.preview_render {
target = match preview {
ctx.target = match preview {
PreviewRender::Screencast => RenderTarget::Screencast,
PreviewRender::ScreenCapture => RenderTarget::ScreenCapture,
};
@@ -4065,23 +4063,23 @@ impl Niri {
// The pointer goes on the top.
if include_pointer && self.pointer_visibility.is_visible() {
self.render_pointer(renderer, output, &mut |elem| push(elem.into()));
self.render_pointer(ctx.renderer, output, &mut |elem| push(elem.into()));
}
// Next, the screen transition texture.
{
let state = self.output_state.get(output).unwrap();
if let Some(transition) = &state.screen_transition {
push(transition.render(target).into());
push(transition.render(ctx.target).into());
}
}
// Next, the exit confirm dialog.
self.exit_confirm_dialog
.render(renderer, output, &mut |elem| push(elem.into()));
.render(ctx.renderer, output, &mut |elem| push(elem.into()));
// Next, the config error notification too.
if let Some(element) = self.config_error_notification.render(renderer, output) {
if let Some(element) = self.config_error_notification.render(ctx.renderer, output) {
push(element.into());
}
@@ -4090,7 +4088,7 @@ impl Niri {
let state = self.output_state.get(output).unwrap();
if let Some(surface) = state.lock_surface.as_ref() {
push_elements_from_surface_tree(
renderer,
ctx.renderer,
surface.wl_surface(),
Point::new(0, 0),
output_scale,
@@ -4127,7 +4125,7 @@ impl Niri {
// If the screenshot UI is open, draw it.
if self.screenshot_ui.is_open() {
self.screenshot_ui
.render_output(output, target, &mut |elem| push(elem.into()));
.render_output(output, ctx.target, &mut |elem| push(elem.into()));
// Add the backdrop for outputs that were connected while the screenshot UI was open.
push(backdrop);
@@ -4136,15 +4134,13 @@ impl Niri {
}
// Draw the hotkey overlay on top.
if let Some(element) = self.hotkey_overlay.render(renderer, output) {
if let Some(element) = self.hotkey_overlay.render(ctx.renderer, output) {
push(element.into());
}
// Then, the Alt-Tab switcher.
self.window_mru_ui
.render_output(self, output, renderer, target, &mut |elem| {
push(elem.into())
});
.render_output(self, output, ctx.r(), &mut |elem| push(elem.into()));
// Don't draw the focus ring on the workspaces while interactively moving above those
// workspaces, since the interactively-moved window already has a focus ring.
@@ -4161,7 +4157,7 @@ impl Niri {
// into different functions).
macro_rules! push_popups_from_layer {
($layer:expr, $backdrop:expr, $push:expr) => {{
self.render_layer_popups(renderer, target, &layer_map, $layer, $backdrop, $push);
self.render_layer_popups(ctx.r(), &layer_map, $layer, $backdrop, $push);
}};
($layer:expr, true) => {{
push_popups_from_layer!($layer, true, &mut |elem| push(elem.into()));
@@ -4175,7 +4171,7 @@ impl Niri {
}
macro_rules! push_normal_from_layer {
($layer:expr, $backdrop:expr, $push:expr) => {{
self.render_layer_normal(renderer, target, &layer_map, $layer, $backdrop, $push);
self.render_layer_normal(ctx.r(), &layer_map, $layer, $backdrop, $push);
}};
($layer:expr, true) => {{
push_normal_from_layer!($layer, true, &mut |elem| push(elem.into()));
@@ -4196,13 +4192,11 @@ impl Niri {
// Otherwise, we will render all layer-shell pop-ups and the top layer on top.
if mon.render_above_top_layer() {
self.layout
.render_interactive_move_for_output(renderer, output, target, &mut |elem| {
push(elem.into())
});
.render_interactive_move_for_output(ctx.r(), output, &mut |elem| push(elem.into()));
mon.render_insert_hint_between_workspaces(renderer, &mut |elem| push(elem.into()));
mon.render_insert_hint_between_workspaces(ctx.renderer, &mut |elem| push(elem.into()));
mon.render_workspaces(renderer, target, focus_ring, &mut |elem| push(elem.into()));
mon.render_workspaces(ctx.r(), focus_ring, &mut |elem| push(elem.into()));
push_popups_from_layer!(Layer::Top);
push_normal_from_layer!(Layer::Top);
@@ -4221,11 +4215,9 @@ impl Niri {
push_normal_from_layer!(Layer::Top);
self.layout
.render_interactive_move_for_output(renderer, output, target, &mut |elem| {
push(elem.into())
});
.render_interactive_move_for_output(ctx.r(), output, &mut |elem| push(elem.into()));
mon.render_insert_hint_between_workspaces(renderer, &mut |elem| push(elem.into()));
mon.render_insert_hint_between_workspaces(ctx.renderer, &mut |elem| push(elem.into()));
// Macro instead of closure to avoid borrowing push().
macro_rules! process {
@@ -4243,7 +4235,7 @@ impl Niri {
push_popups_from_layer!(Layer::Background, process!(geo));
}
mon.render_workspaces(renderer, target, focus_ring, &mut |elem| push(elem.into()));
mon.render_workspaces(ctx.r(), focus_ring, &mut |elem| push(elem.into()));
for (ws, geo) in mon.workspaces_with_render_geo() {
push_normal_from_layer!(Layer::Bottom, process!(geo));
@@ -4253,7 +4245,7 @@ impl Niri {
}
}
mon.render_workspace_shadows(renderer, &mut |elem| push(elem.into()));
mon.render_workspace_shadows(ctx.renderer, &mut |elem| push(elem.into()));
// Then the backdrop.
push_popups_from_layer!(Layer::Background, true);
@@ -4283,29 +4275,27 @@ impl Niri {
fn render_layer_normal<R: NiriRenderer>(
&self,
renderer: &mut R,
target: RenderTarget,
mut ctx: RenderCtx<R>,
layer_map: &LayerMap,
layer: Layer,
for_backdrop: bool,
push: &mut dyn FnMut(LayerSurfaceRenderElement<R>),
) {
for (mapped, geo) in self.layers_in_render_order(layer_map, layer, for_backdrop) {
mapped.render_normal(renderer, geo.loc.to_f64(), target, push);
mapped.render_normal(ctx.r(), geo.loc.to_f64(), push);
}
}
fn render_layer_popups<R: NiriRenderer>(
&self,
renderer: &mut R,
target: RenderTarget,
mut ctx: RenderCtx<R>,
layer_map: &LayerMap,
layer: Layer,
for_backdrop: bool,
push: &mut dyn FnMut(LayerSurfaceRenderElement<R>),
) {
for (mapped, geo) in self.layers_in_render_order(layer_map, layer, for_backdrop) {
mapped.render_popups(renderer, geo.loc.to_f64(), target, push);
mapped.render_popups(ctx.r(), geo.loc.to_f64(), push);
}
}
@@ -4929,7 +4919,11 @@ impl Niri {
if let Some(screencopy) = screencopy {
if screencopy.output() == output {
let elements = elements.get_or_init(|| {
self.render(renderer, output, true, RenderTarget::ScreenCapture)
let ctx = RenderCtx {
renderer,
target: RenderTarget::ScreenCapture,
};
self.render(ctx, output, true)
});
// FIXME: skip elements if not including pointers
let render_result = Self::render_for_screencopy_internal(
@@ -4992,12 +4986,12 @@ impl Niri {
self.update_render_elements(Some(output));
let elements = self.render(
let ctx = RenderCtx {
renderer,
output,
screencopy.overlay_cursor(),
RenderTarget::ScreenCapture,
);
target: RenderTarget::ScreenCapture,
};
let elements = self.render(ctx, output, screencopy.overlay_cursor());
let Some(damage_tracker) = self.screencopy_state.damage_tracker(manager) else {
error!("screencopy queue must not be deleted as long as frames exist");
bail!("screencopy queue missing");
@@ -5120,7 +5114,8 @@ impl Niri {
RenderTarget::ScreenCapture,
];
let screenshot = targets.map(|target| {
let elements = self.render::<GlesRenderer>(renderer, &output, false, target);
let ctx = RenderCtx { renderer, target };
let elements = self.render(ctx, &output, false);
let elements = elements.iter().rev();
let res = render_to_texture(
@@ -5197,12 +5192,11 @@ impl Niri {
let size = transform.transform_size(size);
let scale = Scale::from(output.current_scale().fractional_scale());
let elements = self.render::<GlesRenderer>(
let ctx = RenderCtx {
renderer,
output,
include_pointer,
RenderTarget::ScreenCapture,
);
target: RenderTarget::ScreenCapture,
};
let elements = self.render(ctx, output, include_pointer);
let elements = elements.iter().rev();
let pixels = render_to_vec(
renderer,
@@ -5252,12 +5246,15 @@ impl Niri {
}
let pointer_count = elements.len();
mapped.render(
let ctx = RenderCtx {
renderer,
target: RenderTarget::ScreenCapture,
};
mapped.render(
ctx,
mapped.window.geometry().loc.to_f64(),
scale,
alpha,
RenderTarget::ScreenCapture,
&mut |elem| elements.push(elem.into()),
);
@@ -5413,12 +5410,11 @@ impl Niri {
let transform = output.current_transform();
let size = transform.transform_size(size);
let elements = self.render::<GlesRenderer>(
let ctx = RenderCtx {
renderer,
&output,
include_pointer,
RenderTarget::ScreenCapture,
);
target: RenderTarget::ScreenCapture,
};
let elements = self.render(ctx, &output, include_pointer);
let elements = elements.iter().rev();
let pixels = render_to_vec(
renderer,
@@ -5891,7 +5887,8 @@ impl Niri {
RenderTarget::ScreenCapture,
];
let textures = targets.map(|target| {
let elements = self.render::<GlesRenderer>(renderer, &output, false, target);
let ctx = RenderCtx { renderer, target };
let elements = self.render(ctx, &output, false);
let elements = elements.iter().rev();
let res = render_to_texture(
+30 -1
View File
@@ -1,6 +1,6 @@
use std::ptr;
use anyhow::{ensure, Context};
use anyhow::{ensure, Context as _};
use niri_config::BlockOutFrom;
use smithay::backend::allocator::dmabuf::Dmabuf;
use smithay::backend::allocator::{Buffer, Fourcc};
@@ -17,6 +17,7 @@ use solid_color::{SolidColorBuffer, SolidColorRenderElement};
use self::primary_gpu_texture::PrimaryGpuTextureRenderElement;
use self::texture::{TextureBuffer, TextureRenderElement};
use crate::render_helpers::renderer::AsGlesRenderer;
pub mod border;
pub mod clipped_surface;
@@ -38,6 +39,34 @@ pub mod solid_color;
pub mod surface;
pub mod texture;
/// A rendering context.
///
/// Bundles together things needed by most rendering code.
pub struct RenderCtx<'a, R> {
pub renderer: &'a mut R,
pub target: RenderTarget,
}
impl<'a, R> RenderCtx<'a, R> {
/// Reborrows this context with a smaller lifetime.
#[inline]
pub fn r<'b>(&'b mut self) -> RenderCtx<'b, R> {
RenderCtx {
renderer: self.renderer,
target: self.target,
}
}
}
impl<'a, R: AsGlesRenderer> RenderCtx<'a, R> {
pub fn as_gles<'b>(&'b mut self) -> RenderCtx<'b, GlesRenderer> {
RenderCtx {
renderer: self.renderer.as_gles_renderer(),
target: self.target,
}
}
}
/// What we're rendering for.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RenderTarget {
+6 -6
View File
@@ -6,7 +6,8 @@ use smithay::backend::renderer::element::{Kind, RenderElement};
use smithay::backend::renderer::gles::{GlesRenderer, GlesTexture};
use smithay::utils::{Logical, Physical, Point, Rectangle, Scale, Size, Transform};
use super::{render_to_encompassing_texture, RenderTarget, ToRenderElement};
use super::{render_to_encompassing_texture, ToRenderElement};
use crate::render_helpers::RenderCtx;
/// Snapshot of a render.
#[derive(Debug)]
@@ -43,11 +44,10 @@ where
{
pub fn texture(
&self,
renderer: &mut GlesRenderer,
ctx: RenderCtx<GlesRenderer>,
scale: Scale<f64>,
target: RenderTarget,
) -> Option<&(GlesTexture, Rectangle<i32, Physical>)> {
if target.should_block_out(self.block_out_from) {
if ctx.target.should_block_out(self.block_out_from) {
self.blocked_out_texture.get_or_init(|| {
let _span = tracy_client::span!("RenderSnapshot::texture");
@@ -60,7 +60,7 @@ where
.collect();
match render_to_encompassing_texture(
renderer,
ctx.renderer,
scale,
Transform::Normal,
Fourcc::Abgr8888,
@@ -86,7 +86,7 @@ where
.collect();
match render_to_encompassing_texture(
renderer,
ctx.renderer,
scale,
Transform::Normal,
Fourcc::Abgr8888,
+5 -7
View File
@@ -19,7 +19,7 @@ use zbus::object_server::SignalEmitter;
use crate::dbus::mutter_screen_cast::{self, CursorMode, ScreenCastToNiri, StreamTargetId};
use crate::niri::{CastTarget, Niri, OutputRenderElements, PointerRenderElements, State};
use crate::niri_render_elements;
use crate::render_helpers::RenderTarget;
use crate::render_helpers::{RenderCtx, RenderTarget};
use crate::utils::{get_monotonic_time, CastSessionId, CastStreamId};
use crate::window::mapped::{MappedId, WindowCastRenderElements};
@@ -575,13 +575,11 @@ impl Niri {
}
if cursor_data.is_none() {
self.render_inner(
let ctx = RenderCtx {
renderer,
output,
false,
RenderTarget::Screencast,
&mut |elem| elements.push(elem.into()),
);
target: RenderTarget::Screencast,
};
self.render_inner(ctx, output, false, &mut |elem| elements.push(elem.into()));
let mut pointer_pos = Point::default();
if self.pointer_visibility.is_visible() {
+26 -35
View File
@@ -36,7 +36,7 @@ use crate::render_helpers::primary_gpu_texture::PrimaryGpuTextureRenderElement;
use crate::render_helpers::renderer::NiriRenderer;
use crate::render_helpers::solid_color::{SolidColorBuffer, SolidColorRenderElement};
use crate::render_helpers::texture::{TextureBuffer, TextureRenderElement};
use crate::render_helpers::RenderTarget;
use crate::render_helpers::RenderCtx;
use crate::utils::{
baba_is_float_offset, output_size, round_logical_in_physical, to_physical_precise_round,
with_toplevel_role,
@@ -338,14 +338,13 @@ impl Thumbnail {
#[allow(clippy::too_many_arguments)]
fn render<R: NiriRenderer>(
&self,
renderer: &mut R,
mut ctx: RenderCtx<R>,
config: &niri_config::RecentWindows,
mapped: &Mapped,
preview_geo: Rectangle<f64, Logical>,
scale: f64,
is_active: bool,
bob_y: f64,
target: RenderTarget,
push: &mut dyn FnMut(WindowMruUiRenderElement<R>),
) {
let _span = tracy_client::span!("Thumbnail::render");
@@ -377,8 +376,8 @@ impl Thumbnail {
}
.unwrap_or_default();
let has_border_shader = BorderRenderElement::has_shader(renderer);
let clip_shader = ClippedSurfaceRenderElement::shader(renderer).cloned();
let has_border_shader = BorderRenderElement::has_shader(ctx.renderer);
let clip_shader = ClippedSurfaceRenderElement::shader(ctx.renderer).cloned();
let geo = Rectangle::from_size(self.size.to_f64());
// FIXME: deduplicate code with Tile::render_inner()
let clip = move |elem| match elem {
@@ -444,21 +443,14 @@ impl Thumbnail {
};
// FIXME: this could use mipmaps, for that it should be rendered through an offscreen.
mapped.render_normal(
renderer,
Point::new(0., 0.),
s,
preview_alpha,
target,
&mut |elem| {
let elem = clip(elem);
let elem = downscale(elem);
push(elem)
},
);
mapped.render_normal(ctx.r(), Point::new(0., 0.), s, preview_alpha, &mut |elem| {
let elem = clip(elem);
let elem = downscale(elem);
push(elem)
});
let mut title_size = None;
let title_texture = self.title_texture(renderer.as_gles_renderer(), mapped, scale);
let title_texture = self.title_texture(ctx.as_gles().renderer, mapped, scale);
let title_texture = title_texture.map(|texture| {
let mut size = texture.logical_size();
size.w = f64::min(size.w, preview_geo.size.w);
@@ -469,7 +461,7 @@ impl Thumbnail {
// Hide title for blocked-out windows, but only after computing the title size. This way,
// the background and the border won't have to oscillate in size between normal and
// screencast renders, causing excessive damage.
let should_block_out = target.should_block_out(mapped.rules().block_out_from);
let should_block_out = ctx.target.should_block_out(mapped.rules().block_out_from);
let title_texture = title_texture.filter(|_| !should_block_out);
if let Some((texture, size)) = title_texture {
@@ -491,8 +483,8 @@ impl Thumbnail {
Kind::Unspecified,
);
let renderer = renderer.as_gles_renderer();
if let Some(program) = GradientFadeTextureRenderElement::shader(renderer) {
let ctx = ctx.as_gles();
if let Some(program) = GradientFadeTextureRenderElement::shader(ctx.renderer) {
let elem = GradientFadeTextureRenderElement::new(texture, program);
push(WindowMruUiRenderElement::GradientFadeElem(elem));
} else {
@@ -542,7 +534,7 @@ impl Thumbnail {
scale,
0.5,
);
background.render(renderer, loc, &mut |elem| {
background.render(ctx.renderer, loc, &mut |elem| {
push(WindowMruUiRenderElement::FocusRing(elem))
});
@@ -564,7 +556,7 @@ impl Thumbnail {
1.,
);
border.render(renderer, loc, &mut |elem| {
border.render(ctx.renderer, loc, &mut |elem| {
push(WindowMruUiRenderElement::FocusRing(elem))
});
}
@@ -1100,8 +1092,7 @@ impl WindowMruUi {
&self,
niri: &Niri,
output: &Output,
renderer: &mut R,
target: RenderTarget,
mut ctx: RenderCtx<R>,
push: &mut dyn FnMut(WindowMruUiRenderElement<R>),
) {
let (inner, progress) = match &self.state {
@@ -1139,14 +1130,17 @@ impl WindowMruUi {
// During the closing fade, use an offscreen to avoid transparent compositing artifacts.
let mut pushed_offscreen = false;
if *output == inner.output && alpha < 1. {
let renderer = renderer.as_gles_renderer();
let mut ctx = ctx.as_gles();
let mut elems = Vec::new();
inner.render(niri, renderer, target, &mut |elem| elems.push(elem));
inner.render(niri, ctx.r(), &mut |elem| elems.push(elem));
elems.push(WindowMruUiRenderElement::SolidColor(render_backdrop(1.)));
let scale = output.current_scale().fractional_scale();
match inner.offscreen.render(renderer, Scale::from(scale), &elems) {
match inner
.offscreen
.render(ctx.renderer, Scale::from(scale), &elems)
{
Ok((elem, _sync, _data)) => {
// FIXME: would be good to passthrough offscreen data to visible windows here.
// As is, during the closing fade, windows from other workspaces stop receiving
@@ -1172,7 +1166,7 @@ impl WindowMruUi {
// This is not used as fallback when offscreen fails to render because it looks better to
// hide the previews immediately than to render them with alpha = 1. during a fade-out.
if *output == inner.output && alpha == 1. {
inner.render(niri, renderer, target, &mut |elem| push(elem));
inner.render(niri, ctx, &mut |elem| push(elem));
}
// This is used for both normal elems and for other outputs.
@@ -1554,8 +1548,7 @@ impl Inner {
fn render<R: NiriRenderer>(
&self,
niri: &Niri,
renderer: &mut R,
target: RenderTarget,
mut ctx: RenderCtx<R>,
push: &mut dyn FnMut(WindowMruUiRenderElement<R>),
) {
let output_size = output_size(&self.output);
@@ -1564,7 +1557,7 @@ impl Inner {
let panel_texture =
self.scope_panel
.borrow_mut()
.get(renderer.as_gles_renderer(), scale, self.wmru.scope);
.get(ctx.as_gles().renderer, scale, self.wmru.scope);
if let Some(texture) = panel_texture {
let padding = round_logical_in_physical(scale, f64::from(PANEL_PADDING));
@@ -1598,9 +1591,7 @@ impl Inner {
let config = &config.recent_windows;
let is_active = Some(id) == current_id;
thumbnail.render(
renderer, config, mapped, geo, scale, is_active, bob_y, target, push,
);
thumbnail.render(ctx.r(), config, mapped, geo, scale, is_active, bob_y, push);
}
}
+11 -11
View File
@@ -36,7 +36,7 @@ use crate::render_helpers::solid_color::{SolidColorBuffer, SolidColorRenderEleme
use crate::render_helpers::surface::{
push_elements_from_surface_tree, render_snapshot_from_surface_tree,
};
use crate::render_helpers::{BakedBuffer, RenderTarget};
use crate::render_helpers::{BakedBuffer, RenderCtx, RenderTarget};
use crate::utils::id::IdCounter;
use crate::utils::transaction::Transaction;
use crate::utils::{
@@ -520,11 +520,13 @@ impl Mapped {
};
self.render(
renderer,
RenderCtx {
renderer,
target: RenderTarget::Screencast,
},
location,
scale,
1.,
RenderTarget::Screencast,
&mut |elem| push(use_border(elem)),
);
}
@@ -613,14 +615,13 @@ impl LayoutElement for Mapped {
fn render_normal<R: NiriRenderer>(
&self,
renderer: &mut R,
ctx: RenderCtx<R>,
location: Point<f64, Logical>,
scale: Scale<f64>,
alpha: f32,
target: RenderTarget,
push: &mut dyn FnMut(LayoutElementRenderElement<R>),
) {
if target.should_block_out(self.rules.block_out_from) {
if ctx.target.should_block_out(self.rules.block_out_from) {
let mut buffer = self.block_out_buffer.borrow_mut();
buffer.resize(self.window.geometry().size.to_f64());
let elem =
@@ -631,7 +632,7 @@ impl LayoutElement for Mapped {
let surface = self.toplevel().wl_surface();
let mut push = |elem: WaylandSurfaceRenderElement<R>| push(elem.into());
push_elements_from_surface_tree(
renderer,
ctx.renderer,
surface,
buf_pos.to_physical_precise_round(scale),
scale,
@@ -644,14 +645,13 @@ impl LayoutElement for Mapped {
fn render_popups<R: NiriRenderer>(
&self,
renderer: &mut R,
ctx: RenderCtx<R>,
location: Point<f64, Logical>,
scale: Scale<f64>,
alpha: f32,
target: RenderTarget,
push: &mut dyn FnMut(LayoutElementRenderElement<R>),
) {
if target.should_block_out(self.rules.block_out_from) {
if ctx.target.should_block_out(self.rules.block_out_from) {
return;
}
@@ -662,7 +662,7 @@ impl LayoutElement for Mapped {
let offset = self.window.geometry().loc + popup_offset - popup.geometry().loc;
push_elements_from_surface_tree(
renderer,
ctx.renderer,
popup.wl_surface(),
(buf_pos + offset.to_f64()).to_physical_precise_round(scale),
scale,