x11: store dmabufs in buffer object userdata
This commit is contained in:
parent
42b646a152
commit
53d43905ac
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,9 +580,16 @@ 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) {
|
||||
// Now present the current buffer
|
||||
let _ = pixmap.present(&*connection, &surface.window);
|
||||
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.
|
||||
|
|
Loading…
Reference in New Issue