kms/surface: Update how errors in send_screencopy_result are handled

Previously, some errors in the screencopy code resulted in `redraw`
returning an error, while others make the screencopy frame fail, and
logged a warning.

Instead, make all errors here log a warning, and call `reset()` on the
session, but continue running `redraw()`.

Calling `frame.error` explictly isn't needed, since the same error will
be sent on drop otherwise.
This commit is contained in:
Ian Douglas Scott 2025-06-05 14:13:33 -07:00 committed by Victoria Brekenfeld
parent ca817e2579
commit e80e46e911

View file

@ -1371,17 +1371,26 @@ impl SurfaceThreadState {
} }
let now = self.clock.now(); let now = self.clock.now();
for frame in frames { for (session, frame, res) in frames {
send_screencopy_result( if let Err(err) = send_screencopy_result(
&mut renderer, &mut renderer,
&self.output, &self.output,
&mut pre_postprocess_data, &mut pre_postprocess_data,
&tx, &tx,
&frame_result, &frame_result,
&elements, &elements,
frame, (&session, frame, res),
now.into(), now.into(),
)?; ) {
session
.user_data()
.get::<SessionData>()
.unwrap()
.lock()
.unwrap()
.reset();
tracing::warn!(?err, "Failed to screencopy");
}
} }
if self.mirroring.is_none() { if self.mirroring.is_none() {
@ -1627,27 +1636,13 @@ fn send_screencopy_result<'a>(
frame_result: &RenderFrameResult<GbmBuffer, GbmFramebuffer, CosmicElement<GlMultiRenderer<'a>>>, frame_result: &RenderFrameResult<GbmBuffer, GbmFramebuffer, CosmicElement<GlMultiRenderer<'a>>>,
elements: &[CosmicElement<GlMultiRenderer>], elements: &[CosmicElement<GlMultiRenderer>],
(session, frame, res): ( (session, frame, res): (
ScreencopySessionRef, &ScreencopySessionRef,
ScreencopyFrame, ScreencopyFrame,
Result<(Option<Vec<Rectangle<i32, Physical>>>, RenderElementStates), OutputNoMode>, Result<(Option<Vec<Rectangle<i32, Physical>>>, RenderElementStates), OutputNoMode>,
), ),
presentation_time: Duration, presentation_time: Duration,
) -> Result<()> { ) -> Result<()> {
let damage = match res { let (damage, _) = res?;
Ok((damage, _)) => damage,
Err(err) => {
tracing::warn!(?err, "Failed to screencopy");
session
.user_data()
.get::<SessionData>()
.unwrap()
.lock()
.unwrap()
.reset();
frame.fail(FailureReason::Unknown);
return Ok(());
}
};
let mut sync = SyncPoint::default(); let mut sync = SyncPoint::default();
let mut dmabuf_clone; let mut dmabuf_clone;
@ -1783,7 +1778,7 @@ fn send_screencopy_result<'a>(
fb = Some(tex_fb); fb = Some(tex_fb);
} }
} else { } else {
match frame_result sync = frame_result
.blit_frame_result( .blit_frame_result(
output_size, output_size,
output_transform, output_transform,
@ -1802,53 +1797,24 @@ fn send_screencopy_result<'a>(
MultiError::DeviceMissing, MultiError::DeviceMissing,
) )
} }
}) { })?;
Ok(new_sync) => {
sync = new_sync;
}
Err(err) => {
tracing::warn!(?err, "Failed to screencopy");
session
.user_data()
.get::<SessionData>()
.unwrap()
.lock()
.unwrap()
.reset();
frame.fail(FailureReason::Unknown);
return Ok(());
}
};
}; };
} }
let transform = output.current_transform(); let transform = output.current_transform();
match submit_buffer( if let Some((frame, damage)) = submit_buffer(
frame, frame,
renderer, renderer,
shm_buffer.then_some(fb.as_mut().unwrap()), shm_buffer.then_some(fb.as_mut().unwrap()),
transform, transform,
damage.as_deref(), damage.as_deref(),
sync, sync,
) { )? {
Ok(Some((frame, damage))) => { if frame_result.is_empty {
if frame_result.is_empty { frame.success(transform, damage, presentation_time);
frame.success(transform, damage, presentation_time); } else {
} else { let _ = tx.send((frame, damage));
let _ = tx.send((frame, damage));
}
}
Ok(None) => {}
Err(err) => {
session
.user_data()
.get::<SessionData>()
.unwrap()
.lock()
.unwrap()
.reset();
tracing::warn!(?err, "Failed to screencopy");
} }
} }