kms: Track active clients instead of active buffers
This commit is contained in:
parent
a15e378f1e
commit
ca00df0b37
6 changed files with 72 additions and 131 deletions
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue