kms: Track active clients instead of active buffers

This commit is contained in:
Victoria Brekenfeld 2025-12-19 18:49:22 +01:00 committed by Victoria Brekenfeld
parent a15e378f1e
commit ca00df0b37
6 changed files with 72 additions and 131 deletions

View file

@ -14,7 +14,7 @@ use indexmap::IndexMap;
use render::gles::GbmGlowBackend;
use smithay::{
backend::{
allocator::{Buffer, dmabuf::Dmabuf, format::FormatSet},
allocator::{dmabuf::Dmabuf, format::FormatSet},
drm::{DrmDeviceFd, DrmNode, NodeType, VrrSupport, output::DrmOutputRenderElements},
egl::{EGLContext, EGLDevice, EGLDisplay},
input::InputEvent,
@ -41,7 +41,7 @@ use smithay::{
},
};
use surface::GbmDrmOutput;
use tracing::{debug, error, info, trace, warn};
use tracing::{debug, error, info, warn};
use std::{
collections::{HashMap, HashSet},
@ -487,78 +487,55 @@ impl KmsState {
pub fn dmabuf_imported(
&mut self,
_client: Option<Client>,
client: Option<Client>,
global: &DmabufGlobal,
dmabuf: Dmabuf,
) -> Result<DrmNode> {
let (expected_node, mut other_nodes) = self
let device = self
.drm_devices
.values_mut()
.partition::<Vec<_>, _>(|device| {
.find(|device| {
device
.socket
.as_ref()
.map(|s| &s.dmabuf_global == global)
.unwrap_or(false)
});
other_nodes.retain(|device| device.socket.is_some());
})
.context("Couldn't find gpu for dmabuf global")?;
let mut last_err = anyhow::anyhow!("Dmabuf cannot be imported on any gpu");
for device in expected_node.into_iter().chain(other_nodes.into_iter()) {
let mut _egl = None;
let egl_display = if let Some(egl_display) = device
.inner
.egl
.as_ref()
.map(|internals| &internals.display)
{
egl_display
} else {
_egl =
Some(init_egl(&device.inner.gbm).context("Failed to initialize egl context")?);
&_egl.as_ref().unwrap().display
};
let new_client = if let Some(client) = client {
let new = device.inner.active_clients.insert(client.id());
device.inner.update_egl(
self.primary_node.read().unwrap().as_ref(),
self.api.as_mut(),
)? && new
} else {
false
};
if !egl_display
.dmabuf_texture_formats()
.contains(&dmabuf.format())
{
trace!(
"Skipping import of dmabuf on {:?}: unsupported format",
device.inner.render_node
let egl = device
.inner
.egl
.as_ref()
.context("EGL initialization Error")?;
egl.display
.create_image_from_dmabuf(&dmabuf)
.inspect(|image| unsafe {
smithay::backend::egl::ffi::egl::DestroyImageKHR(
**egl.display.get_display_handle(),
*image,
);
continue;
}
})
.context("Failed to create EGLImage from dmabuf")?;
let result = egl_display
.create_image_from_dmabuf(&dmabuf)
.map(|image| {
unsafe {
smithay::backend::egl::ffi::egl::DestroyImageKHR(
**egl_display.get_display_handle(),
image,
);
};
device.inner.render_node
})
.map_err(Into::into);
let node = device.inner.render_node;
dmabuf.set_node(node);
match result {
Ok(node) => {
dmabuf.set_node(node); // so the MultiRenderer knows what node to use
return Ok(node);
}
Err(err) => {
trace!(
?err,
"Failed to import dmabuf on {:?}", device.inner.render_node
);
last_err = err;
}
}
if new_client {
self.refresh_used_devices()?;
}
Err(last_err)
Ok(node)
}
pub fn schedule_render(&mut self, output: &Output) {