x11: store dmabufs in buffer object userdata

This commit is contained in:
i509VCB 2021-11-04 16:56:45 -05:00 committed by Victor Brekenfeld
parent 42b646a152
commit 53d43905ac
3 changed files with 51 additions and 41 deletions

View File

@ -63,8 +63,7 @@ pub fn run_x11(log: Logger) {
// Create the gbm device for buffer allocation and the X11 surface which presents to the window.
let device = gbm::Device::new(drm_node).expect("Failed to create gbm device");
let format = backend.format();
let surface =
X11Surface::new(&mut backend, device, format).expect("Failed to create X11 surface");
let surface = X11Surface::new(&mut backend, device, format).expect("Failed to create X11 surface");
// Initialize EGL using the GBM device setup earlier.
let egl = EGLDisplay::new(&surface, log.clone()).expect("Failed to create EGLDisplay");
@ -213,7 +212,7 @@ pub fn run_x11(log: Logger) {
#[cfg(feature = "debug")]
let fps_texture = &backend_data.fps_texture;
if let Err(err) = renderer.bind(present.buffer()) {
if let Err(err) = renderer.bind(present.buffer().expect("gbm device was destroyed")) {
error!(log, "Error while binding buffer: {}", err);
}

View File

@ -1,5 +1,6 @@
use std::io;
use gbm::DeviceDestroyedError;
use nix::errno::Errno;
use x11rb::rust_connection::{ConnectError, ConnectionError, ReplyError, ReplyOrIdError};
@ -120,7 +121,11 @@ impl From<CreateWindowError> for X11Error {
pub enum AllocateBuffersError {
/// Failed to open the DRM device to allocate buffers.
#[error("Failed to open the DRM device to allocate buffers.")]
OpenDevice(io::Error),
OpenDevice(#[from] io::Error),
/// The gbm device was destroyed
#[error("The gbm device was destroyed.")]
DeviceDestroyed(#[from] DeviceDestroyedError),
/// The device used to allocate buffers is not the correct drm node type.
#[error("The device used to allocate buffers is not the correct drm node type.")]
@ -128,7 +133,7 @@ pub enum AllocateBuffersError {
/// Exporting a dmabuf failed.
#[error("Exporting a dmabuf failed.")]
ExportDmabuf(GbmConvertError),
ExportDmabuf(#[from] GbmConvertError),
}
impl From<Errno> for AllocateBuffersError {
@ -137,18 +142,6 @@ impl From<Errno> for AllocateBuffersError {
}
}
impl From<io::Error> for AllocateBuffersError {
fn from(err: io::Error) -> Self {
Self::OpenDevice(err)
}
}
impl From<GbmConvertError> for AllocateBuffersError {
fn from(err: GbmConvertError) -> Self {
Self::ExportDmabuf(err)
}
}
impl From<CreateDrmNodeError> for AllocateBuffersError {
fn from(err: CreateDrmNodeError) -> Self {
match err {

View File

@ -83,7 +83,7 @@ use crate::{
};
use calloop::{EventSource, Poll, PostAction, Readiness, Token, TokenFactory};
use drm_fourcc::DrmFourcc;
use gbm::BufferObjectFlags;
use gbm::{BufferObject, BufferObjectFlags};
use nix::{
fcntl::{self, OFlag},
sys::stat::Mode,
@ -344,8 +344,8 @@ pub struct X11Surface {
format: DrmFourcc,
width: u16,
height: u16,
current: Dmabuf,
next: Dmabuf,
current: BufferObject<Dmabuf>,
next: BufferObject<Dmabuf>,
}
#[derive(Debug, thiserror::Error)]
@ -447,16 +447,17 @@ impl X11Surface {
}
let size = backend.window().size();
let current = device
.create_buffer_object::<()>(size.w as u32, size.h as u32, format, BufferObjectFlags::empty())
.map_err(Into::<AllocateBuffersError>::into)?
.export()
let mut current = device
.create_buffer_object(size.w as u32, size.h as u32, format, BufferObjectFlags::empty())
.map_err(Into::<AllocateBuffersError>::into)?;
current
.set_userdata(current.export().map_err(Into::<AllocateBuffersError>::into)?)
.map_err(Into::<AllocateBuffersError>::into)?;
let next = device
.create_buffer_object::<()>(size.w as u32, size.h as u32, format, BufferObjectFlags::empty())
.map_err(Into::<AllocateBuffersError>::into)?
.export()
let mut next = device
.create_buffer_object(size.w as u32, size.h as u32, format, BufferObjectFlags::empty())
.map_err(Into::<AllocateBuffersError>::into)?;
next.set_userdata(next.export().map_err(Into::<AllocateBuffersError>::into)?)
.map_err(Into::<AllocateBuffersError>::into)?;
let (sender, recv) = mpsc::channel();
@ -498,25 +499,30 @@ impl X11Surface {
}
fn resize(&mut self, size: Size<u16, Logical>) -> Result<(), AllocateBuffersError> {
let current = self
let mut current = self
.device
.create_buffer_object::<()>(
.create_buffer_object(
size.w as u32,
size.h as u32,
self.format,
BufferObjectFlags::empty(),
)?
.export()?;
)
.map_err(Into::<AllocateBuffersError>::into)?;
current
.set_userdata(current.export().map_err(Into::<AllocateBuffersError>::into)?)
.map_err(Into::<AllocateBuffersError>::into)?;
let next = self
let mut next = self
.device
.create_buffer_object::<()>(
.create_buffer_object(
size.w as u32,
size.h as u32,
self.format,
BufferObjectFlags::empty(),
)?
.export()?;
)
.map_err(Into::<AllocateBuffersError>::into)?;
next.set_userdata(next.export().map_err(Into::<AllocateBuffersError>::into)?)
.map_err(Into::<AllocateBuffersError>::into)?;
self.width = size.w;
self.height = size.h;
@ -556,8 +562,13 @@ impl Present<'_> {
/// Returns the next buffer that will be presented to the Window.
///
/// You may bind this buffer to a renderer to render.
pub fn buffer(&self) -> Dmabuf {
self.surface.next.clone()
pub fn buffer(&self) -> Result<Dmabuf, AllocateBuffersError> {
Ok(self
.surface
.next
.userdata()
.map(|dmabuf| dmabuf.cloned())
.map(Option::unwrap)?)
}
}
@ -569,10 +580,17 @@ impl Drop for Present<'_> {
// Swap the buffers
mem::swap(&mut surface.next, &mut surface.current);
if let Ok(pixmap) = PixmapWrapper::with_dmabuf(&*connection, &surface.window, &surface.current) {
match surface.current.userdata().map(Option::unwrap) {
Ok(dmabuf) => {
if let Ok(pixmap) = PixmapWrapper::with_dmabuf(&*connection, &surface.window, &dmabuf) {
// Now present the current buffer
let _ = pixmap.present(&*connection, &surface.window);
}
}
Err(_err) => {
todo!("Log error")
}
}
// Flush the connection after presenting to the window to ensure we don't run out of buffer space in the X11 connection.
let _ = connection.flush();