feat: support renderer-validated dma-buf imports
This commit is contained in:
1 parent
d32f20dbbf
commit
05f801aee6
5 files changed
+59
-3
No files matched your search
@@ -174,6 +174,11 @@ fn open_primary_device(
|
||||
// SAFETY: the new context is not current on another thread and remains renderer-owned.
|
||||
let renderer = unsafe { GlesRenderer::new(egl_context)? };
|
||||
state.shm_state.update_formats(renderer.shm_formats());
|
||||
let dmabuf_formats = renderer.dmabuf_formats();
|
||||
let display_handle = state.display_handle.clone();
|
||||
state
|
||||
.dmabuf_state
|
||||
.create_global::<Ferese>(&display_handle, dmabuf_formats);
|
||||
let (connector, crtc, mode) = select_output(&drm)?;
|
||||
let output = create_output(state, &connector, mode);
|
||||
if let Some(backend) = state.direct_backend.as_mut() {
|
||||
@@ -299,6 +304,7 @@ fn render_device(state: &mut Ferese, node: DrmNode) {
|
||||
}
|
||||
|
||||
let rendered = (|| -> Result<bool, Box<dyn Error>> {
|
||||
state.process_dmabuf_imports(&mut device.renderer);
|
||||
let (mut buffer, age) = device.surface.next_buffer()?;
|
||||
let elements = animated_window_elements(state, &mut device.renderer, &device.output);
|
||||
let mut framebuffer = device.renderer.bind(&mut buffer)?;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use smithay::{
|
||||
backend::renderer::utils::on_commit_buffer_handler,
|
||||
backend::{allocator::dmabuf::Dmabuf, renderer::utils::on_commit_buffer_handler},
|
||||
reexports::wayland_server::{
|
||||
Client,
|
||||
protocol::{wl_buffer, wl_surface::WlSurface},
|
||||
@@ -10,6 +10,7 @@ use smithay::{
|
||||
CompositorClientState, CompositorHandler, CompositorState, get_parent,
|
||||
is_sync_subsurface,
|
||||
},
|
||||
dmabuf::{DmabufGlobal, DmabufHandler, DmabufState, ImportNotifier},
|
||||
shm::{ShmHandler, ShmState},
|
||||
},
|
||||
};
|
||||
@@ -74,6 +75,22 @@ impl BufferHandler for Ferese {
|
||||
fn buffer_destroyed(&mut self, _buffer: &wl_buffer::WlBuffer) {}
|
||||
}
|
||||
|
||||
impl DmabufHandler for Ferese {
|
||||
fn dmabuf_state(&mut self) -> &mut DmabufState {
|
||||
&mut self.dmabuf_state
|
||||
}
|
||||
|
||||
fn dmabuf_imported(
|
||||
&mut self,
|
||||
_global: &DmabufGlobal,
|
||||
dmabuf: Dmabuf,
|
||||
notifier: ImportNotifier,
|
||||
) {
|
||||
self.queue_dmabuf_import(dmabuf, notifier);
|
||||
crate::backends::direct::render_all(self);
|
||||
}
|
||||
}
|
||||
|
||||
impl ShmHandler for Ferese {
|
||||
fn shm_state(&self) -> &ShmState {
|
||||
&self.shm_state
|
||||
|
||||
@@ -235,6 +235,7 @@ impl XdgForeignHandler for Ferese {
|
||||
smithay::delegate_compositor!(Ferese);
|
||||
smithay::delegate_cursor_shape!(Ferese);
|
||||
smithay::delegate_data_device!(Ferese);
|
||||
smithay::delegate_dmabuf!(Ferese);
|
||||
smithay::delegate_fractional_scale!(Ferese);
|
||||
smithay::delegate_idle_inhibit!(Ferese);
|
||||
smithay::delegate_idle_notify!(Ferese);
|
||||
|
||||
+26
-1
@@ -11,7 +11,7 @@ use ferese_core::{WindowPlacement, WorkspaceSet};
|
||||
use ferese_layout::{Axis, Direction, GapConfig, LayoutResult, Rect, SizeConstraints, WindowId};
|
||||
|
||||
use smithay::{
|
||||
backend::drm::DrmEventTime,
|
||||
backend::{allocator::dmabuf::Dmabuf, drm::DrmEventTime, renderer::ImportDma},
|
||||
desktop::{
|
||||
LayerSurface, PopupManager, Space, Window, WindowSurfaceType, layer_map_for_output,
|
||||
utils::send_frames_surface_tree,
|
||||
@@ -37,6 +37,7 @@ use smithay::{
|
||||
wayland::{
|
||||
compositor::{CompositorClientState, CompositorState, with_states},
|
||||
cursor_shape::CursorShapeManagerState,
|
||||
dmabuf::{DmabufState, ImportNotifier},
|
||||
fractional_scale::FractionalScaleManagerState,
|
||||
idle_inhibit::IdleInhibitManagerState,
|
||||
idle_notify::IdleNotifierState,
|
||||
@@ -78,6 +79,7 @@ pub struct Ferese {
|
||||
pub idle_inhibitors: HashMap<WlSurface, usize>,
|
||||
pub active_shortcuts_inhibitor: Option<KeyboardShortcutsInhibitor>,
|
||||
pub direct_backend: Option<crate::backends::direct::DirectBackendState>,
|
||||
pending_dmabuf_imports: Vec<(Dmabuf, ImportNotifier)>,
|
||||
next_window_id: u64,
|
||||
last_animation_tick: Instant,
|
||||
pub popups: PopupManager,
|
||||
@@ -86,6 +88,7 @@ pub struct Ferese {
|
||||
pub cursor_shape_state: CursorShapeManagerState,
|
||||
pub data_device_state: DataDeviceState,
|
||||
pub decoration_state: XdgDecorationState,
|
||||
pub dmabuf_state: DmabufState,
|
||||
pub fractional_scale_state: FractionalScaleManagerState,
|
||||
pub idle_inhibit_state: IdleInhibitManagerState,
|
||||
pub idle_notifier_state: IdleNotifierState<Self>,
|
||||
@@ -108,6 +111,25 @@ pub struct Ferese {
|
||||
}
|
||||
|
||||
impl Ferese {
|
||||
pub(crate) fn queue_dmabuf_import(&mut self, dmabuf: Dmabuf, notifier: ImportNotifier) {
|
||||
self.pending_dmabuf_imports.push((dmabuf, notifier));
|
||||
}
|
||||
|
||||
pub(crate) fn process_dmabuf_imports<R>(&mut self, renderer: &mut R)
|
||||
where
|
||||
R: ImportDma,
|
||||
{
|
||||
for (dmabuf, notifier) in self.pending_dmabuf_imports.drain(..) {
|
||||
if renderer.import_dmabuf(&dmabuf, None).is_ok() {
|
||||
if let Err(error) = notifier.successful::<Self>() {
|
||||
tracing::debug!(?error, "dma-buf client disappeared before import completed");
|
||||
}
|
||||
} else {
|
||||
notifier.failed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
event_loop: &mut EventLoop<'static, Self>,
|
||||
display: Display<Self>,
|
||||
@@ -117,6 +139,7 @@ impl Ferese {
|
||||
let cursor_shape_state = CursorShapeManagerState::new::<Self>(&display_handle);
|
||||
let xdg_shell_state = XdgShellState::new::<Self>(&display_handle);
|
||||
let decoration_state = XdgDecorationState::new::<Self>(&display_handle);
|
||||
let dmabuf_state = DmabufState::new();
|
||||
let fractional_scale_state = FractionalScaleManagerState::new::<Self>(&display_handle);
|
||||
let idle_inhibit_state = IdleInhibitManagerState::new::<Self>(&display_handle);
|
||||
let idle_notifier_state = IdleNotifierState::new(&display_handle, event_loop.handle());
|
||||
@@ -168,6 +191,7 @@ impl Ferese {
|
||||
idle_inhibitors: HashMap::new(),
|
||||
active_shortcuts_inhibitor: None,
|
||||
direct_backend: None,
|
||||
pending_dmabuf_imports: Vec::new(),
|
||||
next_window_id: 1,
|
||||
last_animation_tick: start_time,
|
||||
popups: PopupManager::default(),
|
||||
@@ -176,6 +200,7 @@ impl Ferese {
|
||||
cursor_shape_state,
|
||||
data_device_state,
|
||||
decoration_state,
|
||||
dmabuf_state,
|
||||
fractional_scale_state,
|
||||
idle_inhibit_state,
|
||||
idle_notifier_state,
|
||||
|
||||
@@ -6,6 +6,7 @@ use std::{
|
||||
use smithay::{
|
||||
backend::{
|
||||
renderer::{
|
||||
ImportDma,
|
||||
damage::OutputDamageTracker,
|
||||
element::{
|
||||
AsRenderElements, Kind as RenderElementKind,
|
||||
@@ -52,7 +53,12 @@ render_elements! {
|
||||
}
|
||||
|
||||
pub fn init(event_loop: &mut EventLoop<Ferese>, state: &mut Ferese) -> Result<(), Box<dyn Error>> {
|
||||
let (mut backend, event_source) = winit::init()?;
|
||||
let (mut backend, event_source) = winit::init::<GlesRenderer>()?;
|
||||
let dmabuf_formats = backend.renderer().dmabuf_formats();
|
||||
let display_handle = state.display_handle.clone();
|
||||
state
|
||||
.dmabuf_state
|
||||
.create_global::<Ferese>(&display_handle, dmabuf_formats);
|
||||
let initial_scale = normalized_scale(backend.scale_factor());
|
||||
let mode = Mode {
|
||||
size: backend.window_size(),
|
||||
@@ -127,6 +133,7 @@ pub fn init(event_loop: &mut EventLoop<Ferese>, state: &mut Ferese) -> Result<()
|
||||
let rendered = (|| -> Result<(), Box<dyn Error>> {
|
||||
{
|
||||
let (renderer, mut framebuffer) = backend.bind()?;
|
||||
state.process_dmabuf_imports(renderer);
|
||||
let elements = animated_window_elements(state, renderer, &output);
|
||||
damage_tracker.render_output(
|
||||
renderer,
|
||||
|
||||
Reference in new issue
Block a user