diff --git a/src/backend/tty.rs b/src/backend/tty.rs index 5646e8d30..52ec1ebdc 100644 --- a/src/backend/tty.rs +++ b/src/backend/tty.rs @@ -38,7 +38,7 @@ use smithay_drm_extras::drm_scanner::{DrmScanEvent, DrmScanner}; use smithay_drm_extras::edid::EdidInfo; use crate::config::Config; -use crate::niri::{OutputRenderElements, State, RedrawState, CLEAR_COLOR}; +use crate::niri::{OutputRenderElements, State, RedrawState}; use crate::utils::get_monotonic_time; use crate::Niri; @@ -859,11 +859,8 @@ impl Tty { span.emit_text(&surface.name); let drm_compositor = &mut surface.compositor; - match drm_compositor.render_frame::<_, _, GlesTexture>( - &mut device.gles, - elements, - CLEAR_COLOR, - ) { + match drm_compositor.render_frame::<_, _, GlesTexture>(&mut device.gles, elements, [0.; 4]) + { Ok(res) => { if self .config diff --git a/src/backend/winit.rs b/src/backend/winit.rs index 592789825..1afb8d97f 100644 --- a/src/backend/winit.rs +++ b/src/backend/winit.rs @@ -18,7 +18,7 @@ use smithay::utils::Transform; use super::RenderResult; use crate::config::Config; -use crate::niri::{OutputRenderElements, RedrawState, State, CLEAR_COLOR}; +use crate::niri::{OutputRenderElements, RedrawState, State}; use crate::utils::get_monotonic_time; use crate::Niri; @@ -148,7 +148,7 @@ impl Winit { let age = self.backend.buffer_age().unwrap(); let res = self .damage_tracker - .render_output(self.backend.renderer(), age, elements, CLEAR_COLOR) + .render_output(self.backend.renderer(), age, elements, [0.; 4]) .unwrap(); niri.update_primary_scanout_output(output, &res.states); diff --git a/src/niri.rs b/src/niri.rs index 0835fc944..91878e2e3 100644 --- a/src/niri.rs +++ b/src/niri.rs @@ -86,8 +86,8 @@ use crate::layout::{output_size, Layout, MonitorRenderElement}; use crate::pw_utils::{Cast, PipeWire}; use crate::utils::{center, get_monotonic_time, make_screenshot_path, write_png_rgba8}; -pub const CLEAR_COLOR: [f32; 4] = [0.2, 0.2, 0.2, 1.]; -pub const CLEAR_COLOR_LOCKED: [f32; 4] = [0.3, 0.1, 0.1, 1.]; +const CLEAR_COLOR: [f32; 4] = [0.2, 0.2, 0.2, 1.]; +const CLEAR_COLOR_LOCKED: [f32; 4] = [0.3, 0.1, 0.1, 1.]; pub struct Niri { pub config: Rc>, @@ -169,6 +169,9 @@ pub struct OutputState { /// If there are no commits, then we won't have a timer running, so the estimated sequence will /// not increase. pub current_estimated_sequence: Option, + /// Solid color buffer for the background that we use instead of clearing to avoid damage + /// tracking issues and make screenshots easier. + pub background_buffer: SolidColorBuffer, pub lock_render_state: LockRenderState, pub lock_surface: Option, pub lock_color_buffer: SolidColorBuffer, @@ -750,6 +753,7 @@ impl Niri { unfinished_animations_remain: false, frame_clock: FrameClock::new(refresh_interval), current_estimated_sequence: None, + background_buffer: SolidColorBuffer::new(size, CLEAR_COLOR), lock_render_state, lock_surface: None, lock_color_buffer: SolidColorBuffer::new(size, CLEAR_COLOR_LOCKED), @@ -817,12 +821,16 @@ impl Niri { } pub fn output_resized(&mut self, output: Output) { + let output_size = output_size(&output); + let is_locked = self.is_locked(); + layer_map_for_output(&output).arrange(); self.layout.update_output_size(&output); - let is_locked = self.is_locked(); if let Some(state) = self.output_state.get_mut(&output) { - state.lock_color_buffer.resize(output_size(&output)); + state.background_buffer.resize(output_size); + + state.lock_color_buffer.resize(output_size); if is_locked { if let Some(lock_surface) = &state.lock_surface { configure_lock_surface(lock_surface, &output); @@ -1309,6 +1317,19 @@ impl Niri { extend_from_layer(&mut elements, Layer::Bottom); extend_from_layer(&mut elements, Layer::Background); + // Then the background. + let state = self.output_state.get(output).unwrap(); + elements.push( + SolidColorRenderElement::from_buffer( + &state.background_buffer, + (0, 0), + output_scale, + 1., + Kind::Unspecified, + ) + .into(), + ); + elements } @@ -2079,10 +2100,6 @@ fn render_to_dmabuf( .render(size, Transform::Normal) .context("error starting frame")?; - frame - .clear(CLEAR_COLOR, &[output_rect]) - .context("error clearing")?; - for element in elements.iter().rev() { let src = element.src(); let dst = element.geometry(scale);