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.
|
// 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 device = gbm::Device::new(drm_node).expect("Failed to create gbm device");
|
||||||
let format = backend.format();
|
let format = backend.format();
|
||||||
let surface =
|
let surface = X11Surface::new(&mut backend, device, format).expect("Failed to create X11 surface");
|
||||||
X11Surface::new(&mut backend, device, format).expect("Failed to create X11 surface");
|
|
||||||
|
|
||||||
// Initialize EGL using the GBM device setup earlier.
|
// Initialize EGL using the GBM device setup earlier.
|
||||||
let egl = EGLDisplay::new(&surface, log.clone()).expect("Failed to create EGLDisplay");
|
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")]
|
#[cfg(feature = "debug")]
|
||||||
let fps_texture = &backend_data.fps_texture;
|
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);
|
error!(log, "Error while binding buffer: {}", err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
|
use gbm::DeviceDestroyedError;
|
||||||
use nix::errno::Errno;
|
use nix::errno::Errno;
|
||||||
use x11rb::rust_connection::{ConnectError, ConnectionError, ReplyError, ReplyOrIdError};
|
use x11rb::rust_connection::{ConnectError, ConnectionError, ReplyError, ReplyOrIdError};
|
||||||
|
|
||||||
|
@ -120,7 +121,11 @@ impl From<CreateWindowError> for X11Error {
|
||||||
pub enum AllocateBuffersError {
|
pub enum AllocateBuffersError {
|
||||||
/// Failed to open the DRM device to allocate buffers.
|
/// Failed to open the DRM device to allocate buffers.
|
||||||
#[error("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.
|
/// 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.")]
|
#[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.
|
/// Exporting a dmabuf failed.
|
||||||
#[error("Exporting a dmabuf failed.")]
|
#[error("Exporting a dmabuf failed.")]
|
||||||
ExportDmabuf(GbmConvertError),
|
ExportDmabuf(#[from] GbmConvertError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Errno> for AllocateBuffersError {
|
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 {
|
impl From<CreateDrmNodeError> for AllocateBuffersError {
|
||||||
fn from(err: CreateDrmNodeError) -> Self {
|
fn from(err: CreateDrmNodeError) -> Self {
|
||||||
match err {
|
match err {
|
||||||
|
|
|
@ -83,7 +83,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
use calloop::{EventSource, Poll, PostAction, Readiness, Token, TokenFactory};
|
use calloop::{EventSource, Poll, PostAction, Readiness, Token, TokenFactory};
|
||||||
use drm_fourcc::DrmFourcc;
|
use drm_fourcc::DrmFourcc;
|
||||||
use gbm::BufferObjectFlags;
|
use gbm::{BufferObject, BufferObjectFlags};
|
||||||
use nix::{
|
use nix::{
|
||||||
fcntl::{self, OFlag},
|
fcntl::{self, OFlag},
|
||||||
sys::stat::Mode,
|
sys::stat::Mode,
|
||||||
|
@ -344,8 +344,8 @@ pub struct X11Surface {
|
||||||
format: DrmFourcc,
|
format: DrmFourcc,
|
||||||
width: u16,
|
width: u16,
|
||||||
height: u16,
|
height: u16,
|
||||||
current: Dmabuf,
|
current: BufferObject<Dmabuf>,
|
||||||
next: Dmabuf,
|
next: BufferObject<Dmabuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
@ -447,16 +447,17 @@ impl X11Surface {
|
||||||
}
|
}
|
||||||
|
|
||||||
let size = backend.window().size();
|
let size = backend.window().size();
|
||||||
let current = device
|
let mut current = device
|
||||||
.create_buffer_object::<()>(size.w as u32, size.h as u32, format, BufferObjectFlags::empty())
|
.create_buffer_object(size.w as u32, size.h as u32, format, BufferObjectFlags::empty())
|
||||||
.map_err(Into::<AllocateBuffersError>::into)?
|
.map_err(Into::<AllocateBuffersError>::into)?;
|
||||||
.export()
|
current
|
||||||
|
.set_userdata(current.export().map_err(Into::<AllocateBuffersError>::into)?)
|
||||||
.map_err(Into::<AllocateBuffersError>::into)?;
|
.map_err(Into::<AllocateBuffersError>::into)?;
|
||||||
|
|
||||||
let next = device
|
let mut next = device
|
||||||
.create_buffer_object::<()>(size.w as u32, size.h as u32, format, BufferObjectFlags::empty())
|
.create_buffer_object(size.w as u32, size.h as u32, format, BufferObjectFlags::empty())
|
||||||
.map_err(Into::<AllocateBuffersError>::into)?
|
.map_err(Into::<AllocateBuffersError>::into)?;
|
||||||
.export()
|
next.set_userdata(next.export().map_err(Into::<AllocateBuffersError>::into)?)
|
||||||
.map_err(Into::<AllocateBuffersError>::into)?;
|
.map_err(Into::<AllocateBuffersError>::into)?;
|
||||||
|
|
||||||
let (sender, recv) = mpsc::channel();
|
let (sender, recv) = mpsc::channel();
|
||||||
|
@ -498,25 +499,30 @@ impl X11Surface {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resize(&mut self, size: Size<u16, Logical>) -> Result<(), AllocateBuffersError> {
|
fn resize(&mut self, size: Size<u16, Logical>) -> Result<(), AllocateBuffersError> {
|
||||||
let current = self
|
let mut current = self
|
||||||
.device
|
.device
|
||||||
.create_buffer_object::<()>(
|
.create_buffer_object(
|
||||||
size.w as u32,
|
size.w as u32,
|
||||||
size.h as u32,
|
size.h as u32,
|
||||||
self.format,
|
self.format,
|
||||||
BufferObjectFlags::empty(),
|
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
|
.device
|
||||||
.create_buffer_object::<()>(
|
.create_buffer_object(
|
||||||
size.w as u32,
|
size.w as u32,
|
||||||
size.h as u32,
|
size.h as u32,
|
||||||
self.format,
|
self.format,
|
||||||
BufferObjectFlags::empty(),
|
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.width = size.w;
|
||||||
self.height = size.h;
|
self.height = size.h;
|
||||||
|
@ -556,8 +562,13 @@ impl Present<'_> {
|
||||||
/// Returns the next buffer that will be presented to the Window.
|
/// Returns the next buffer that will be presented to the Window.
|
||||||
///
|
///
|
||||||
/// You may bind this buffer to a renderer to render.
|
/// You may bind this buffer to a renderer to render.
|
||||||
pub fn buffer(&self) -> Dmabuf {
|
pub fn buffer(&self) -> Result<Dmabuf, AllocateBuffersError> {
|
||||||
self.surface.next.clone()
|
Ok(self
|
||||||
|
.surface
|
||||||
|
.next
|
||||||
|
.userdata()
|
||||||
|
.map(|dmabuf| dmabuf.cloned())
|
||||||
|
.map(Option::unwrap)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -569,10 +580,17 @@ impl Drop for Present<'_> {
|
||||||
// Swap the buffers
|
// Swap the buffers
|
||||||
mem::swap(&mut surface.next, &mut surface.current);
|
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
|
// Now present the current buffer
|
||||||
let _ = pixmap.present(&*connection, &surface.window);
|
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.
|
// 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();
|
let _ = connection.flush();
|
||||||
|
|
Loading…
Reference in New Issue