backend: Support wl-dmabuf v6
This commit is contained in:
parent
81cd5fdbaa
commit
091583ac84
14 changed files with 298 additions and 210 deletions
|
|
@ -40,7 +40,7 @@ impl DmabufHandler for State {
|
|||
fn new_surface_feedback(
|
||||
&mut self,
|
||||
surface: &WlSurface,
|
||||
global: &DmabufGlobal,
|
||||
_global: &DmabufGlobal,
|
||||
) -> Option<DmabufFeedback> {
|
||||
let BackendData::Kms(kms) = &self.backend else {
|
||||
return None;
|
||||
|
|
@ -57,18 +57,7 @@ impl DmabufHandler for State {
|
|||
f.ended_at.is_none() && f.surface.has_surface(surface, WindowSurfaceType::all())
|
||||
});
|
||||
|
||||
let node = kms
|
||||
.drm_devices
|
||||
.values()
|
||||
.find(|device| {
|
||||
device
|
||||
.socket
|
||||
.as_ref()
|
||||
.map(|s| &s.dmabuf_global == global)
|
||||
.unwrap_or(false)
|
||||
})?
|
||||
.inner
|
||||
.render_node;
|
||||
let node = kms.primary_node.read().unwrap().unwrap();
|
||||
let kms_surface = kms
|
||||
.drm_devices
|
||||
.values()
|
||||
|
|
@ -77,9 +66,7 @@ impl DmabufHandler for State {
|
|||
|
||||
Some(with_states(surface, |data| {
|
||||
if is_fullscreen {
|
||||
feedback
|
||||
.primary_scanout_feedback
|
||||
.unwrap_or(feedback.render_feedback)
|
||||
feedback.primary_scanout_feedback
|
||||
} else if frame_time_filter_fn(data) == Kind::ScanoutCandidate {
|
||||
feedback
|
||||
.overlay_scanout_feedback
|
||||
|
|
|
|||
|
|
@ -38,7 +38,11 @@ use smithay::{
|
|||
};
|
||||
use tracing::trace;
|
||||
|
||||
use std::{convert::TryFrom, path::PathBuf, sync::Arc};
|
||||
use std::{
|
||||
convert::TryFrom,
|
||||
path::PathBuf,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
pub enum ImportError {
|
||||
Failed,
|
||||
|
|
@ -52,19 +56,28 @@ pub trait DrmHandler<R: 'static> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct WlDrmState<R>(std::marker::PhantomData<R>);
|
||||
#[derive(Debug)]
|
||||
pub struct WlDrmState<R> {
|
||||
device: Arc<Mutex<DrmGlobalDeviceData>>,
|
||||
global: GlobalId,
|
||||
_marker: std::marker::PhantomData<R>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DrmGlobalDeviceData {
|
||||
formats: Vec<Fourcc>,
|
||||
path: PathBuf,
|
||||
}
|
||||
|
||||
/// Data associated with a drm global.
|
||||
pub struct DrmGlobalData {
|
||||
filter: Box<dyn for<'a> Fn(&'a Client) -> bool + Send + Sync>,
|
||||
formats: Arc<Vec<Fourcc>>,
|
||||
device_path: PathBuf,
|
||||
dmabuf_global: DmabufGlobal,
|
||||
device: Arc<Mutex<DrmGlobalDeviceData>>,
|
||||
}
|
||||
|
||||
pub struct DrmInstanceData {
|
||||
formats: Arc<Vec<Fourcc>>,
|
||||
device: Arc<Mutex<DrmGlobalDeviceData>>,
|
||||
dmabuf_global: DmabufGlobal,
|
||||
}
|
||||
|
||||
|
|
@ -86,16 +99,24 @@ where
|
|||
data_init: &mut DataInit<'_, D>,
|
||||
) {
|
||||
let data = DrmInstanceData {
|
||||
formats: global_data.formats.clone(),
|
||||
device: global_data.device.clone(),
|
||||
dmabuf_global: global_data.dmabuf_global,
|
||||
};
|
||||
let drm_instance = data_init.init(resource, data);
|
||||
|
||||
drm_instance.device(global_data.device_path.to_string_lossy().into_owned());
|
||||
drm_instance.device(
|
||||
global_data
|
||||
.device
|
||||
.lock()
|
||||
.unwrap()
|
||||
.path
|
||||
.to_string_lossy()
|
||||
.into_owned(),
|
||||
);
|
||||
if drm_instance.version() >= 2 {
|
||||
drm_instance.capabilities(wl_drm::Capability::Prime as u32);
|
||||
}
|
||||
for format in global_data.formats.iter() {
|
||||
for format in global_data.device.lock().unwrap().formats.iter() {
|
||||
if let Ok(converted) = wl_drm::Format::try_from(*format as u32) {
|
||||
drm_instance.format(converted as u32);
|
||||
}
|
||||
|
|
@ -148,7 +169,7 @@ where
|
|||
} => {
|
||||
let format = match Fourcc::try_from(format) {
|
||||
Ok(format) => {
|
||||
if !data.formats.contains(&format) {
|
||||
if !data.device.lock().unwrap().formats.contains(&format) {
|
||||
drm.post_error(
|
||||
wl_drm::Error::InvalidFormat,
|
||||
String::from("Format not advertised by wl_drm"),
|
||||
|
|
@ -220,13 +241,12 @@ where
|
|||
}
|
||||
|
||||
impl<R: 'static> WlDrmState<R> {
|
||||
pub fn create_global<D>(
|
||||
&mut self,
|
||||
pub fn new<D>(
|
||||
display: &DisplayHandle,
|
||||
device_path: PathBuf,
|
||||
formats: FormatSet,
|
||||
dmabuf_global: &DmabufGlobal,
|
||||
) -> GlobalId
|
||||
) -> Self
|
||||
where
|
||||
D: GlobalDispatch<wl_drm::WlDrm, DrmGlobalData>
|
||||
+ Dispatch<wl_drm::WlDrm, DrmInstanceData>
|
||||
|
|
@ -234,19 +254,16 @@ impl<R: 'static> WlDrmState<R> {
|
|||
+ DmabufHandler
|
||||
+ 'static,
|
||||
{
|
||||
self.create_global_with_filter::<D, _>(display, device_path, formats, dmabuf_global, |_| {
|
||||
true
|
||||
})
|
||||
Self::new_with_filter::<D, _>(display, device_path, formats, dmabuf_global, |_| true)
|
||||
}
|
||||
|
||||
pub fn create_global_with_filter<D, F>(
|
||||
&mut self,
|
||||
pub fn new_with_filter<D, F>(
|
||||
display: &DisplayHandle,
|
||||
device_path: PathBuf,
|
||||
formats: FormatSet,
|
||||
dmabuf_global: &DmabufGlobal,
|
||||
client_filter: F,
|
||||
) -> GlobalId
|
||||
) -> Self
|
||||
where
|
||||
D: GlobalDispatch<wl_drm::WlDrm, DrmGlobalData>
|
||||
+ Dispatch<wl_drm::WlDrm, DrmInstanceData>
|
||||
|
|
@ -255,21 +272,45 @@ impl<R: 'static> WlDrmState<R> {
|
|||
+ 'static,
|
||||
F: for<'a> Fn(&'a Client) -> bool + Send + Sync + 'static,
|
||||
{
|
||||
let formats = Arc::new(
|
||||
formats
|
||||
let device = Arc::new(Mutex::new(DrmGlobalDeviceData {
|
||||
formats: formats
|
||||
.into_iter()
|
||||
.filter(|f| f.modifier == Modifier::Invalid)
|
||||
.map(|f| f.code)
|
||||
.collect(),
|
||||
);
|
||||
path: device_path,
|
||||
}));
|
||||
|
||||
let data = DrmGlobalData {
|
||||
filter: Box::new(client_filter),
|
||||
formats,
|
||||
device_path,
|
||||
device: device.clone(),
|
||||
dmabuf_global: *dmabuf_global,
|
||||
};
|
||||
|
||||
display.create_global::<D, wl_drm::WlDrm, _>(2, data)
|
||||
let global = display.create_global::<D, wl_drm::WlDrm, _>(2, data);
|
||||
|
||||
WlDrmState {
|
||||
device,
|
||||
global,
|
||||
_marker: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_device(&mut self, device_path: PathBuf, formats: FormatSet) {
|
||||
let new_device = DrmGlobalDeviceData {
|
||||
formats: formats
|
||||
.into_iter()
|
||||
.filter(|f| f.modifier == Modifier::Invalid)
|
||||
.map(|f| f.code)
|
||||
.collect(),
|
||||
path: device_path,
|
||||
};
|
||||
|
||||
*self.device.lock().unwrap() = new_device;
|
||||
}
|
||||
|
||||
pub fn global(&self) -> &GlobalId {
|
||||
&self.global
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use calloop::{
|
||||
LoopHandle,
|
||||
timer::{TimeoutAction, Timer},
|
||||
};
|
||||
use calloop::LoopHandle;
|
||||
use cosmic_comp_config::output::comp::AdaptiveSync;
|
||||
use cosmic_protocols::output_management::v1::server::{
|
||||
zcosmic_output_configuration_head_v1::ZcosmicOutputConfigurationHeadV1,
|
||||
|
|
@ -30,7 +27,7 @@ use smithay::{
|
|||
utils::{Logical, Physical, Point, Size, Transform},
|
||||
wayland::output::WlOutputData,
|
||||
};
|
||||
use std::{convert::TryFrom, sync::Mutex, time::Duration};
|
||||
use std::{convert::TryFrom, sync::Mutex};
|
||||
|
||||
mod handlers;
|
||||
|
||||
|
|
@ -519,26 +516,6 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
fn remove_global_with_timer<D: 'static>(
|
||||
dh: &DisplayHandle,
|
||||
event_loop_handle: &LoopHandle<D>,
|
||||
id: GlobalId,
|
||||
) {
|
||||
dh.disable_global::<D>(id.clone());
|
||||
let source = Timer::from_duration(Duration::from_secs(5));
|
||||
let dh = dh.clone();
|
||||
let res = event_loop_handle.insert_source(source, move |_, _, _state| {
|
||||
dh.remove_global::<D>(id.clone());
|
||||
TimeoutAction::Drop
|
||||
});
|
||||
if let Err(err) = res {
|
||||
tracing::error!(
|
||||
"failed to insert timer source to destroy output global: {}",
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! delegate_output_configuration {
|
||||
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
|
||||
smithay::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
|
||||
|
|
@ -578,4 +555,4 @@ macro_rules! delegate_output_configuration {
|
|||
}
|
||||
pub(crate) use delegate_output_configuration;
|
||||
|
||||
use crate::utils::prelude::OutputExt;
|
||||
use crate::utils::{global::remove_global_with_timer, prelude::OutputExt};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue