From 8ef6c161a0b8a85fbeb5b91be03f5bc999517a4c Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Thu, 3 Jul 2025 13:41:40 -0700 Subject: [PATCH] screencopy: Fix damage tracking bug with shm screencopy of output Similar to the change in https://github.com/pop-os/cosmic-comp/pull/780, but also updates it to be a little clearer than just an uncommented `age = 0` line. Ideally we want some robust system to re-use the offscreen buffer (but not allocate more buffers indefinitely if the client doesn't capture with the same `wl_buffer`). --- src/backend/kms/surface/mod.rs | 11 ++++++++--- src/wayland/handlers/screencopy/render.rs | 10 +++++++--- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/backend/kms/surface/mod.rs b/src/backend/kms/surface/mod.rs index d5a56e86..47cc61ca 100644 --- a/src/backend/kms/surface/mod.rs +++ b/src/backend/kms/surface/mod.rs @@ -39,7 +39,7 @@ use smithay::{ }, egl::EGLContext, renderer::{ - buffer_dimensions, + buffer_dimensions, buffer_type, damage::Error as RenderError, element::{ texture::TextureRenderElement, @@ -56,7 +56,7 @@ use smithay::{ multigpu::{ApiDevice, Error as MultiError, GpuManager}, sync::SyncPoint, utils::with_renderer_surface_state, - Bind, Blit, Frame, ImportDma, Offscreen, Renderer, RendererSuper, Texture, + Bind, Blit, BufferType, Frame, ImportDma, Offscreen, Renderer, RendererSuper, Texture, TextureFilter, }, }, @@ -1617,7 +1617,12 @@ fn take_screencopy_frames( }; let buffer = frame.buffer(); - let age = damage_tracking.age_for_buffer(&buffer); + let age = if matches!(buffer_type(&frame.buffer()), Some(BufferType::Shm)) { + // TODO re-use offscreen buffer to damage track screencopy to shm + 0 + } else { + damage_tracking.age_for_buffer(&buffer) + }; let res = damage_tracking.dt.damage_output(age, &elements); if let Some(old_len) = old_len { diff --git a/src/wayland/handlers/screencopy/render.rs b/src/wayland/handlers/screencopy/render.rs index a6bc403a..79af623a 100644 --- a/src/wayland/handlers/screencopy/render.rs +++ b/src/wayland/handlers/screencopy/render.rs @@ -172,7 +172,12 @@ where }) .transpose()?; - let age = session_damage_tracking.age_for_buffer(&buffer); + let age = if offscreen.is_some() { + // TODO re-use offscreen buffer to damage track screencopy to shm + 0 + } else { + session_damage_tracking.age_for_buffer(&buffer) + }; let mut fb = offscreen .as_mut() .map(|tex| renderer.bind(tex).map_err(DTError::Rendering)) @@ -242,7 +247,7 @@ pub fn render_workspace_to_buffer( renderer: &mut R, offscreen: Option<&mut R::Framebuffer<'_>>, dt: &'d mut OutputDamageTracker, - mut age: usize, + age: usize, additional_damage: Vec>, draw_cursor: bool, common: &mut Common, @@ -311,7 +316,6 @@ pub fn render_workspace_to_buffer( .map(|res| res.0) } else { let target = offscreen.expect("shm buffers should have an offscreen target"); - age = 0; render_workspace( None, renderer,