mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-22 02:01:55 +07:00
Bundle renderer and target into a RenderCtx
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
@@ -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) {
|
||||
|
||||
@@ -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!());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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(
|
||||
|
||||
@@ -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,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,
|
||||
|
||||
@@ -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
@@ -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
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user