use std::mem; use std::path::PathBuf; use wayland_client::{Dispatch, Proxy, QueueHandle}; use wayland_protocols::wp::linux_dmabuf::zv1::client::zwp_linux_buffer_params_v1::{ Event as BufferParamsEvent, ZwpLinuxBufferParamsV1, }; use wayland_protocols::wp::linux_dmabuf::zv1::client::zwp_linux_dmabuf_feedback_v1::{ Event as DmabufFeedbackEvent, ZwpLinuxDmabufFeedbackV1, }; use wayland_protocols::wp::linux_dmabuf::zv1::client::zwp_linux_dmabuf_v1::{ Event as DmabufEvent, ZwpLinuxDmabufV1, }; use crate::state::{CaptureSource, EncConstructionStage, InFlightSurface, State}; impl Dispatch for State { fn event( _state: &mut Self, _proxy: &ZwpLinuxDmabufV1, event: ::Event, _data: &(), _conn: &wayland_client::Connection, _qhandle: &QueueHandle>, ) { match event { DmabufEvent::Format { .. } => {} DmabufEvent::Modifier { .. } => {} _ => {} } } } impl Dispatch for State { fn event( state: &mut Self, _proxy: &ZwpLinuxDmabufFeedbackV1, event: ::Event, _data: &(), _conn: &wayland_client::Connection, _qhandle: &QueueHandle>, ) { match event { DmabufFeedbackEvent::MainDevice { device } => { if device.len() >= 8 { let dev_bytes: [u8; 8] = device[..8].try_into().unwrap_or([0u8; 8]); let dev = u64::from_ne_bytes(dev_bytes); let minor = ((dev & 0xFF) | ((dev >> 12) & 0xFFFFFF00)) as u32; let path = PathBuf::from(format!("/dev/dri/renderD{}", minor)); if path.exists() { tracing::info!( "Compositor DRM device: {} (dev_t: {})", path.display(), dev ); state.drm_device_from_compositor = Some(path); } else { tracing::warn!( "Compositor reported DRM device {} (dev_t: {}) but path does not exist", path.display(), dev ); } } else { tracing::warn!( "main_device event with unexpected data length: {}", device.len() ); } } DmabufFeedbackEvent::FormatTable { .. } => {} DmabufFeedbackEvent::Done => {} DmabufFeedbackEvent::TrancheDone => {} DmabufFeedbackEvent::TrancheTargetDevice { .. } => {} DmabufFeedbackEvent::TrancheFormats { .. } => {} DmabufFeedbackEvent::TrancheFlags { .. } => {} _ => {} } } } impl Dispatch for State { fn event( state: &mut Self, proxy: &ZwpLinuxBufferParamsV1, event: ::Event, _data: &(), _conn: &wayland_client::Connection, _qhandle: &QueueHandle>, ) { match event { BufferParamsEvent::Created { .. } => { tracing::debug!("DMA-BUF buffer created"); } BufferParamsEvent::Failed => { tracing::error!("DMA-BUF buffer creation failed"); let taken = mem::replace(&mut state.in_flight_surface, InFlightSurface::None); match taken { InFlightSurface::CopyQueued { buffer, frame, .. } => { drop(buffer); if let EncConstructionStage::Streaming { cap, .. } = &mut state.stage { cap.on_done_with_frame(frame); } } other => { state.in_flight_surface = other; } } proxy.destroy(); state.errored = true; } _ => {} } } }