fix(kms): don't panic when renderer creation fails after a GPU reset
When the DRM device is lost transiently, for example when the amdgpu driver
performs a GPU reset and recovers ("device wedged, but recovered through
reset"), acquiring a renderer in `SurfaceThreadState::redraw` fails. The three
`renderer`/`single_renderer` calls used `.unwrap()`, so the failure panicked
the surface's render thread. Because that panic unwinds across the EGL/GBM FFI
boundary it aborts the whole process (SIGABRT), dropping the session back to
the greeter and closing every running application.
`redraw` is already fallible and its caller logs the error and reschedules a
redraw, and the frame-submission path (`render_frame`/`queue_frame`) already
propagates errors the same way. Propagate the renderer-acquisition errors too,
so a transient device loss is retried on the next frame, once the device is
back, instead of taking down the compositor.
Relates to #649.
Assisted by an AI coding tool; I have reviewed and fully understand the change
and am able to maintain it and respond to review.
This commit is contained in:
parent
5ce21fb4f3
commit
9514b4945e
1 changed files with 10 additions and 3 deletions
|
|
@ -1006,12 +1006,16 @@ impl SurfaceThreadState {
|
|||
&self.shell.read(),
|
||||
);
|
||||
|
||||
// Acquiring a renderer can fail transiently when the underlying DRM
|
||||
// device is lost (e.g. after a GPU reset).
|
||||
let mut renderer = if render_node != self.target_node {
|
||||
self.api
|
||||
.renderer(&render_node, &self.target_node, compositor.format())
|
||||
.unwrap()
|
||||
.map_err(|err| anyhow::format_err!("Failed to create renderer: {:?}", err))?
|
||||
} else {
|
||||
self.api.single_renderer(&self.target_node).unwrap()
|
||||
self.api
|
||||
.single_renderer(&self.target_node)
|
||||
.map_err(|err| anyhow::format_err!("Failed to create renderer: {:?}", err))?
|
||||
};
|
||||
|
||||
self.timings.start_render(&self.clock);
|
||||
|
|
@ -1267,7 +1271,10 @@ impl SurfaceThreadState {
|
|||
})
|
||||
.context("Failed to draw to offscreen render target")?;
|
||||
|
||||
renderer = self.api.single_renderer(&self.target_node).unwrap();
|
||||
renderer = self
|
||||
.api
|
||||
.single_renderer(&self.target_node)
|
||||
.map_err(|err| anyhow::format_err!("Failed to create renderer: {:?}", err))?;
|
||||
|
||||
elements = postprocess_elements(
|
||||
&mut renderer,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue