From 8ff205a26697efbd8506eb2a74413b040e07602b Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Sat, 14 Mar 2026 14:04:58 +0100 Subject: [PATCH] gbm: handle render nodes that cannot allocate buffers --- src/video/drm.rs | 16 +++++++++++----- src/video/gbm.rs | 32 ++++++++++++++++++++++---------- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/src/video/drm.rs b/src/video/drm.rs index a4396d08..80db5b5e 100644 --- a/src/video/drm.rs +++ b/src/video/drm.rs @@ -168,11 +168,13 @@ fn reopen(fd: c::c_int, need_primary: bool) -> Result, DrmError> { return Ok(Rc::new(fd)); } let path = 'path: { - if get_node_type_from_fd(fd).map_err(DrmError::GetDeviceType)? == NodeType::Render { - break 'path uapi::format_ustr!("/proc/self/fd/{}", fd); - } - if !need_primary && let Ok(path) = render_node_name(fd) { - break 'path path; + if !need_primary { + if get_node_type_from_fd(fd).map_err(DrmError::GetDeviceType)? == NodeType::Render { + break 'path uapi::format_ustr!("/proc/self/fd/{}", fd); + } + if let Ok(path) = render_node_name(fd) { + break 'path path; + } } device_node_name(fd)? }; @@ -212,6 +214,10 @@ impl Drm { self.fd.raw() } + pub fn dup_primary(&self) -> Result { + Self::reopen(self.fd.raw(), true) + } + pub fn dup_render(&self) -> Result { Self::reopen(self.fd.raw(), false) } diff --git a/src/video/gbm.rs b/src/video/gbm.rs index 52ebb7ae..eb34ca71 100644 --- a/src/video/gbm.rs +++ b/src/video/gbm.rs @@ -7,8 +7,8 @@ use { BO_USE_RENDERING, BO_USE_SCANOUT, BO_USE_WRITE, BufferObject, BufferUsage, MappedBuffer, }, - format::{Format, formats}, - utils::oserror::OsError, + format::{Format, XRGB8888, formats}, + utils::{errorfmt::ErrorFmt, oserror::OsError}, video::{ INVALID_MODIFIER, Modifier, dmabuf::{DmaBuf, DmaBufIds, DmaBufPlane, PlaneVec}, @@ -214,14 +214,26 @@ unsafe fn export_bo(dmabuf_ids: &DmaBufIds, bo: *mut Bo) -> Result Result { - let drm = drm.dup_render()?; - let dev = unsafe { gbm_create_device(drm.raw()) }; - if dev.is_null() { - Err(GbmError::CreateDevice) - } else { - let dev = Rc::new(DeviceHolder { dev }); - Ok(Self { drm, dev }) - } + let open = |drm: Drm| { + let dev = unsafe { gbm_create_device(drm.raw()) }; + if dev.is_null() { + Err(GbmError::CreateDevice) + } else { + let dev = Rc::new(DeviceHolder { dev }); + Ok(Self { drm, dev }) + } + }; + let dma_buf_ids = DmaBufIds::default(); + let create_bo = + |gbm: &GbmDevice| gbm.create_bo(&dma_buf_ids, 1, 1, XRGB8888, &[INVALID_MODIFIER], 0); + let gbm = open(drm.dup_render()?)?; + match create_bo(&gbm) { + Ok(..) => return Ok(gbm), + Err(e) => log::warn!("Render node cannot allocate buffers: {}", ErrorFmt(e)), + }; + let gbm = open(drm.dup_primary()?)?; + create_bo(&gbm)?; + Ok(gbm) } pub fn raw(&self) -> *mut Device {