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:
parent
cac7a5aca6
commit
9bc1b6e1ee
4 changed files with 74 additions and 113 deletions
|
|
@ -1080,7 +1080,7 @@ impl SurfaceThreadState {
|
|||
let frames = self
|
||||
.mirroring
|
||||
.is_none()
|
||||
.then(|| take_screencopy_frames(&self.output, &mut elements, &mut has_cursor_mode_none))
|
||||
.then(|| take_screencopy_frames(&self.output, &elements, &mut has_cursor_mode_none))
|
||||
.unwrap_or_default();
|
||||
|
||||
// actual rendering
|
||||
|
|
@ -1606,10 +1606,9 @@ fn get_surface_dmabuf_feedback(
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: Don't mutate `elements`
|
||||
fn take_screencopy_frames(
|
||||
output: &Output,
|
||||
elements: &mut Vec<CosmicElement<GlMultiRenderer>>,
|
||||
elements: &[CosmicElement<GlMultiRenderer>],
|
||||
has_cursor_mode_none: &mut bool,
|
||||
) -> Vec<(
|
||||
ScreencopySessionRef,
|
||||
|
|
@ -1624,7 +1623,15 @@ fn take_screencopy_frames(
|
|||
let session_data = session.user_data().get::<SessionData>().unwrap();
|
||||
let mut damage_tracking = session_data.lock().unwrap();
|
||||
|
||||
let old_len = if !additional_damage.is_empty() {
|
||||
let buffer = frame.buffer();
|
||||
let age = if matches!(buffer_type(&buffer), Some(BufferType::Shm)) {
|
||||
// TODO re-use offscreen buffer to damage track screencopy to shm
|
||||
0
|
||||
} else {
|
||||
damage_tracking.age_for_buffer(&buffer)
|
||||
};
|
||||
|
||||
if !additional_damage.is_empty() {
|
||||
let area = output
|
||||
.current_mode()
|
||||
.unwrap()
|
||||
|
|
@ -1634,41 +1641,26 @@ fn take_screencopy_frames(
|
|||
.to_buffer(1, Transform::Normal)
|
||||
.to_f64();
|
||||
|
||||
let old_len = elements.len();
|
||||
elements.extend(
|
||||
additional_damage
|
||||
.into_iter()
|
||||
.map(|rect| {
|
||||
rect.to_f64()
|
||||
.to_logical(
|
||||
output.current_scale().fractional_scale(),
|
||||
output.current_transform(),
|
||||
&area,
|
||||
)
|
||||
.to_i32_round()
|
||||
})
|
||||
.map(DamageElement::new)
|
||||
.map(Into::into),
|
||||
);
|
||||
|
||||
Some(old_len)
|
||||
} else {
|
||||
None
|
||||
let additional_damage_elements: Vec<_> = additional_damage
|
||||
.into_iter()
|
||||
.map(|rect| {
|
||||
rect.to_f64()
|
||||
.to_logical(
|
||||
output.current_scale().fractional_scale(),
|
||||
output.current_transform(),
|
||||
&area,
|
||||
)
|
||||
.to_i32_round()
|
||||
})
|
||||
.map(DamageElement::new)
|
||||
.collect();
|
||||
let _ = damage_tracking
|
||||
.dt
|
||||
.damage_output(age, &additional_damage_elements);
|
||||
};
|
||||
|
||||
let buffer = frame.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 {
|
||||
elements.truncate(old_len);
|
||||
}
|
||||
|
||||
if !session.draw_cursor() {
|
||||
*has_cursor_mode_none = true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue