kms: Allow updating the primary node

Add more sophisticated code to handle the primary node disappearing.

Also overhaul the selection logic to respect our allow/deny-list and
prefer devices with built-in connectors before using the boot gpu.

This will also allow triggering a primary node switch at runtime
for debugging purposes in the future.
This commit is contained in:
Victoria Brekenfeld 2025-05-21 22:07:46 +02:00 committed by Victoria Brekenfeld
parent 4c0c61e94b
commit 8194be30c6
8 changed files with 153 additions and 93 deletions

View file

@ -12,7 +12,7 @@ impl BufferHandler for State {
if let BackendData::Kms(kms_state) = &mut self.backend {
for device in kms_state.drm_devices.values_mut() {
if device.active_buffers.remove(&buffer.downgrade()) {
if !device.in_use(kms_state.primary_node.as_ref()) {
if !device.in_use(kms_state.primary_node.read().unwrap().as_ref()) {
if let Err(err) = kms_state.refresh_used_devices() {
warn!(?err, "Failed to init devices.");
};

View file

@ -355,7 +355,10 @@ fn constraints_for_output(output: &Output, backend: &mut BackendData) -> Option<
};
let mut renderer = backend
.offscreen_renderer(|kms| kms.target_node_for_output(&output).or(kms.primary_node))
.offscreen_renderer(|kms| {
kms.target_node_for_output(&output)
.or(*kms.primary_node.read().unwrap())
})
.unwrap();
Some(constraints_for_renderer(mode, renderer.as_mut()))
}
@ -376,7 +379,7 @@ fn constraints_for_toplevel(
})
.flatten();
dma_node.or(kms.primary_node)
dma_node.or(*kms.primary_node.read().unwrap())
})
.unwrap();

View file

@ -337,7 +337,9 @@ pub fn render_workspace_to_buffer(
let common = &mut state.common;
let renderer = match state.backend.offscreen_renderer(|kms| {
let render_node = kms.target_node_for_output(&output).or(kms.primary_node)?;
let render_node = kms
.target_node_for_output(&output)
.or(*kms.primary_node.read().unwrap())?;
let target_node = get_dmabuf(&buffer)
.ok()
.and_then(|dma| dma.node())
@ -591,7 +593,7 @@ pub fn render_window_to_buffer(
})
.flatten()
})
.or(kms.primary_node)
.or(*kms.primary_node.read().unwrap())
}) {
Ok(renderer) => renderer,
Err(err) => {
@ -745,7 +747,10 @@ pub fn render_cursor_to_buffer(
}
let common = &mut state.common;
let renderer = match state.backend.offscreen_renderer(|kms| kms.primary_node) {
let renderer = match state
.backend
.offscreen_renderer(|kms| *kms.primary_node.read().unwrap())
{
Ok(renderer) => renderer,
Err(err) => {
warn!(?err, "Couldn't use node for screencopy");