kms/surface: Split off part of redraw into take_screencopy_frames
This commit is contained in:
parent
e80e46e911
commit
b823dd4247
1 changed files with 72 additions and 65 deletions
|
|
@ -1044,73 +1044,11 @@ impl SurfaceThreadState {
|
||||||
// we can't use the elements after `compositor.render_frame`,
|
// we can't use the elements after `compositor.render_frame`,
|
||||||
// so let's collect everything we need for screencopy now
|
// so let's collect everything we need for screencopy now
|
||||||
let mut has_cursor_mode_none = false;
|
let mut has_cursor_mode_none = false;
|
||||||
let frames: Vec<(
|
let frames = self
|
||||||
ScreencopySessionRef,
|
|
||||||
ScreencopyFrame,
|
|
||||||
Result<(Option<Vec<Rectangle<i32, Physical>>>, RenderElementStates), OutputNoMode>,
|
|
||||||
)> = self
|
|
||||||
.mirroring
|
.mirroring
|
||||||
.is_none()
|
.is_none()
|
||||||
.then(|| {
|
.then(|| take_screencopy_frames(&self.output, &mut elements, &mut has_cursor_mode_none))
|
||||||
self.output
|
.unwrap_or_default();
|
||||||
.take_pending_frames()
|
|
||||||
.into_iter()
|
|
||||||
.map(|(session, frame)| {
|
|
||||||
let additional_damage = frame.damage();
|
|
||||||
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 area = self
|
|
||||||
.output
|
|
||||||
.current_mode()
|
|
||||||
.unwrap()
|
|
||||||
/* TODO: Mode is Buffer..., why is this Physical in the first place */
|
|
||||||
.size
|
|
||||||
.to_logical(1)
|
|
||||||
.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(
|
|
||||||
self.output.current_scale().fractional_scale(),
|
|
||||||
self.output.current_transform(),
|
|
||||||
&area,
|
|
||||||
)
|
|
||||||
.to_i32_round()
|
|
||||||
})
|
|
||||||
.map(DamageElement::new)
|
|
||||||
.map(Into::into),
|
|
||||||
);
|
|
||||||
|
|
||||||
Some(old_len)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
let buffer = frame.buffer();
|
|
||||||
let age = 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
let res = res.map(|(a, b)| (a.cloned(), b));
|
|
||||||
std::mem::drop(damage_tracking);
|
|
||||||
(session, frame, res)
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}).unwrap_or_default();
|
|
||||||
|
|
||||||
// actual rendering
|
// actual rendering
|
||||||
let source_output = self
|
let source_output = self
|
||||||
|
|
@ -1628,6 +1566,75 @@ fn get_surface_dmabuf_feedback(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Don't mutate `elements`
|
||||||
|
fn take_screencopy_frames(
|
||||||
|
output: &Output,
|
||||||
|
elements: &mut Vec<CosmicElement<GlMultiRenderer>>,
|
||||||
|
has_cursor_mode_none: &mut bool,
|
||||||
|
) -> Vec<(
|
||||||
|
ScreencopySessionRef,
|
||||||
|
ScreencopyFrame,
|
||||||
|
Result<(Option<Vec<Rectangle<i32, Physical>>>, RenderElementStates), OutputNoMode>,
|
||||||
|
)> {
|
||||||
|
output
|
||||||
|
.take_pending_frames()
|
||||||
|
.into_iter()
|
||||||
|
.map(|(session, frame)| {
|
||||||
|
let additional_damage = frame.damage();
|
||||||
|
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 area = output
|
||||||
|
.current_mode()
|
||||||
|
.unwrap()
|
||||||
|
/* TODO: Mode is Buffer..., why is this Physical in the first place */
|
||||||
|
.size
|
||||||
|
.to_logical(1)
|
||||||
|
.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 buffer = frame.buffer();
|
||||||
|
let age = 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = res.map(|(a, b)| (a.cloned(), b));
|
||||||
|
std::mem::drop(damage_tracking);
|
||||||
|
(session, frame, res)
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
fn send_screencopy_result<'a>(
|
fn send_screencopy_result<'a>(
|
||||||
renderer: &mut GlMultiRenderer<'a>,
|
renderer: &mut GlMultiRenderer<'a>,
|
||||||
output: &Output,
|
output: &Output,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue