image-copy: Use damage_output() for additional damage

The important change here is that we now apply the additional damage
first, instead of using `.extend()` to add it after other elements. This
is important since `OutputDamageTracker` will ignore our damage elements
if there are behind an element with an opaque region.

This also makes things a bit simpler, especially `take_screencopy_frames()`,
which no longer needs a mutable references to extend then truncate.

The implementation of `OutputDamageTracker` isn't entirely clear, but as
far as I can tell this is intended to work, and it seems to work in some
testing.
This commit is contained in:
Ian Douglas Scott 2025-09-17 11:06:02 -07:00 committed by Victoria Brekenfeld
parent cac7a5aca6
commit 9bc1b6e1ee
4 changed files with 74 additions and 113 deletions

View file

@ -492,7 +492,6 @@ smithay::render_elements! {
pub WindowCaptureElement<R> where R: ImportAll + ImportMem;
WaylandElement=WaylandSurfaceRenderElement<R>,
CursorElement=RelocateRenderElement<cursor::CursorRenderElement<R>>,
AdditionalDamage=DamageElement,
}
pub fn render_window_to_buffer(
@ -543,22 +542,19 @@ pub fn render_window_to_buffer(
CosmicElement<R>: RenderElement<R>,
CosmicMappedRenderElement<R>: RenderElement<R>,
{
let mut elements = Vec::new();
elements.extend(
additional_damage
.into_iter()
.filter_map(|rect| {
let logical_rect = rect.to_logical(
1,
Transform::Normal,
&geometry.size.to_buffer(1, Transform::Normal),
);
logical_rect.intersection(Rectangle::from_size(geometry.size))
})
.map(DamageElement::new)
.map(Into::<WindowCaptureElement<R>>::into),
);
let additional_damage_elements: Vec<_> = additional_damage
.into_iter()
.filter_map(|rect| {
let logical_rect = rect.to_logical(
1,
Transform::Normal,
&geometry.size.to_buffer(1, Transform::Normal),
);
logical_rect.intersection(Rectangle::from_size(geometry.size))
})
.map(DamageElement::new)
.collect();
dt.damage_output(age, &additional_damage_elements)?;
let shell = common.shell.read();
let seat = shell.seats.last_active().clone();
@ -581,6 +577,8 @@ pub fn render_window_to_buffer(
};
std::mem::drop(shell);
let mut elements = Vec::new();
if let Some(location) = location {
if draw_cursor {
elements.extend(
@ -783,7 +781,17 @@ pub fn render_cursor_to_buffer(
CosmicElement<R>: RenderElement<R>,
CosmicMappedRenderElement<R>: RenderElement<R>,
{
let mut elements = cursor::draw_cursor(
let additional_damage_elements: Vec<_> = additional_damage
.into_iter()
.filter_map(|rect| {
let logical_rect = rect.to_logical(1, Transform::Normal, &Size::from((64, 64)));
logical_rect.intersection(Rectangle::from_size((64, 64).into()))
})
.map(DamageElement::new)
.collect();
dt.damage_output(age, &additional_damage_elements)?;
let elements = cursor::draw_cursor(
renderer,
seat,
Point::from((0.0, 0.0)),
@ -797,17 +805,6 @@ pub fn render_cursor_to_buffer(
.map(WindowCaptureElement::from)
.collect::<Vec<_>>();
elements.extend(
additional_damage
.into_iter()
.filter_map(|rect| {
let logical_rect = rect.to_logical(1, Transform::Normal, &Size::from((64, 64)));
logical_rect.intersection(Rectangle::from_size((64, 64).into()))
})
.map(DamageElement::new)
.map(Into::<WindowCaptureElement<R>>::into),
);
if let Ok(dmabuf) = get_dmabuf(buffer) {
let mut dmabuf_clone = dmabuf.clone();
let mut fb = renderer