drm: adjust RenderSurface to swapchain changes and AsDmabuf
This commit is contained in:
parent
5cf328a1b8
commit
2200d09841
|
@ -1,5 +1,4 @@
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::convert::TryInto;
|
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
@ -11,8 +10,10 @@ use gbm::{BufferObject, BufferObjectFlags, Device as GbmDevice};
|
||||||
use wayland_server::protocol::{wl_buffer, wl_shm};
|
use wayland_server::protocol::{wl_buffer, wl_shm};
|
||||||
|
|
||||||
use super::{device::DevPath, surface::DrmSurfaceInternal, DrmError, DrmSurface};
|
use super::{device::DevPath, surface::DrmSurfaceInternal, DrmError, DrmSurface};
|
||||||
use crate::backend::allocator::{
|
use crate::backend::{
|
||||||
dmabuf::Dmabuf, Allocator, Buffer, Format, Fourcc, Modifier, Slot, Swapchain, SwapchainError,
|
allocator::{
|
||||||
|
dmabuf::{AsDmabuf, Dmabuf}, Allocator, Buffer, Format, Fourcc, Modifier, Slot, Swapchain,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use crate::backend::egl::EGLBuffer;
|
use crate::backend::egl::EGLBuffer;
|
||||||
use crate::backend::renderer::{Bind, Renderer, Texture, Transform};
|
use crate::backend::renderer::{Bind, Renderer, Texture, Transform};
|
||||||
|
@ -29,12 +30,12 @@ pub struct DrmRenderSurface<
|
||||||
D: AsRawFd + 'static,
|
D: AsRawFd + 'static,
|
||||||
A: Allocator<B>,
|
A: Allocator<B>,
|
||||||
R: Bind<Dmabuf>,
|
R: Bind<Dmabuf>,
|
||||||
B: Buffer + TryInto<Dmabuf>,
|
B: Buffer,
|
||||||
> {
|
> {
|
||||||
_format: Format,
|
_format: Format,
|
||||||
buffers: Buffers<D>,
|
buffers: Buffers<D, B>,
|
||||||
current_buffer: Option<Slot<Dmabuf, BufferObject<FbHandle<D>>>>,
|
current_buffer: Option<(Slot<B, (Dmabuf, BufferObject<FbHandle<D>>)>, Dmabuf)>,
|
||||||
swapchain: Swapchain<A, B, BufferObject<FbHandle<D>>, Dmabuf>,
|
swapchain: Swapchain<A, B, (Dmabuf, BufferObject<FbHandle<D>>)>,
|
||||||
renderer: R,
|
renderer: R,
|
||||||
drm: Arc<DrmSurface<D>>,
|
drm: Arc<DrmSurface<D>>,
|
||||||
}
|
}
|
||||||
|
@ -43,7 +44,7 @@ impl<D, A, B, R, E1, E2, E3> DrmRenderSurface<D, A, R, B>
|
||||||
where
|
where
|
||||||
D: AsRawFd + 'static,
|
D: AsRawFd + 'static,
|
||||||
A: Allocator<B, Error = E1>,
|
A: Allocator<B, Error = E1>,
|
||||||
B: Buffer + TryInto<Dmabuf, Error = E2>,
|
B: Buffer + AsDmabuf<Error=E2>,
|
||||||
R: Bind<Dmabuf> + Renderer<Error = E3>,
|
R: Bind<Dmabuf> + Renderer<Error = E3>,
|
||||||
E1: std::error::Error + 'static,
|
E1: std::error::Error + 'static,
|
||||||
E2: std::error::Error + 'static,
|
E2: std::error::Error + 'static,
|
||||||
|
@ -160,12 +161,12 @@ where
|
||||||
let mut swapchain = Swapchain::new(allocator, mode.size().0 as u32, mode.size().1 as u32, format);
|
let mut swapchain = Swapchain::new(allocator, mode.size().0 as u32, mode.size().1 as u32, format);
|
||||||
|
|
||||||
// Test format
|
// Test format
|
||||||
let buffer = swapchain.acquire()?.unwrap();
|
let buffer = swapchain.acquire().map_err(Error::SwapchainError)?.unwrap();
|
||||||
|
let dmabuf = buffer.export().map_err(Error::AsDmabufError)?;
|
||||||
|
|
||||||
{
|
{
|
||||||
let dmabuf: Dmabuf = (*buffer).clone();
|
|
||||||
match renderer
|
match renderer
|
||||||
.bind(dmabuf)
|
.bind(dmabuf.clone())
|
||||||
.map_err(Error::<E1, E2, E3>::RenderError)
|
.map_err(Error::<E1, E2, E3>::RenderError)
|
||||||
.and_then(|_| {
|
.and_then(|_| {
|
||||||
renderer
|
renderer
|
||||||
|
@ -190,9 +191,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let bo = import_dmabuf(&drm, &gbm, &*buffer)?;
|
let bo = import_dmabuf(&drm, &gbm, &dmabuf)?;
|
||||||
let fb = bo.userdata().unwrap().unwrap().fb;
|
let fb = bo.userdata().unwrap().unwrap().fb;
|
||||||
buffer.set_userdata(bo);
|
buffer.set_userdata((dmabuf, bo));
|
||||||
|
|
||||||
match drm.test_buffer(fb, &mode, true) {
|
match drm.test_buffer(fb, &mode, true) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
|
@ -329,7 +330,7 @@ impl<D, A, B, T, R, E1, E2, E3> Renderer for DrmRenderSurface<D, A, R, B>
|
||||||
where
|
where
|
||||||
D: AsRawFd + 'static,
|
D: AsRawFd + 'static,
|
||||||
A: Allocator<B, Error = E1>,
|
A: Allocator<B, Error = E1>,
|
||||||
B: Buffer + TryInto<Dmabuf, Error = E2>,
|
B: Buffer + AsDmabuf<Error=E2>,
|
||||||
R: Bind<Dmabuf> + Renderer<Error = E3, TextureId = T>,
|
R: Bind<Dmabuf> + Renderer<Error = E3, TextureId = T>,
|
||||||
T: Texture,
|
T: Texture,
|
||||||
E1: std::error::Error + 'static,
|
E1: std::error::Error + 'static,
|
||||||
|
@ -371,9 +372,13 @@ where
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let slot = self.swapchain.acquire()?.ok_or(Error::NoFreeSlotsError)?;
|
let slot = self.swapchain.acquire().map_err(Error::SwapchainError)?.ok_or(Error::NoFreeSlotsError)?;
|
||||||
self.renderer.bind((*slot).clone()).map_err(Error::RenderError)?;
|
let dmabuf = match &*slot.userdata() {
|
||||||
self.current_buffer = Some(slot);
|
Some((buf, _)) => buf.clone(),
|
||||||
|
None => (*slot).export().map_err(Error::AsDmabufError)?,
|
||||||
|
};
|
||||||
|
self.renderer.bind(dmabuf.clone()).map_err(Error::RenderError)?;
|
||||||
|
self.current_buffer = Some((slot, dmabuf));
|
||||||
self.renderer
|
self.renderer
|
||||||
.begin(width, height, Transform::Flipped180 /* TODO: add Add<Transform> implementation to add and correct _transform here */)
|
.begin(width, height, Transform::Flipped180 /* TODO: add Add<Transform> implementation to add and correct _transform here */)
|
||||||
.map_err(Error::RenderError)
|
.map_err(Error::RenderError)
|
||||||
|
@ -401,9 +406,10 @@ where
|
||||||
|
|
||||||
let result = self.renderer.finish();
|
let result = self.renderer.finish();
|
||||||
if result.is_ok() {
|
if result.is_ok() {
|
||||||
|
let (slot, dmabuf) = self.current_buffer.take().unwrap();
|
||||||
match self
|
match self
|
||||||
.buffers
|
.buffers
|
||||||
.queue::<E1, E2, E3>(self.current_buffer.take().unwrap())
|
.queue::<E1, E2, E3>(slot, dmabuf)
|
||||||
{
|
{
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
Err(Error::DrmError(drm)) => return Err(drm.into()),
|
Err(Error::DrmError(drm)) => return Err(drm.into()),
|
||||||
|
@ -426,23 +432,24 @@ impl<A: AsRawFd + 'static> Drop for FbHandle<A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Buffers<D: AsRawFd + 'static> {
|
struct Buffers<D: AsRawFd + 'static, B: Buffer> {
|
||||||
gbm: GbmDevice<gbm::FdWrapper>,
|
gbm: GbmDevice<gbm::FdWrapper>,
|
||||||
drm: Arc<DrmSurface<D>>,
|
drm: Arc<DrmSurface<D>>,
|
||||||
_current_fb: Slot<Dmabuf, BufferObject<FbHandle<D>>>,
|
_current_fb: Slot<B, (Dmabuf, BufferObject<FbHandle<D>>)>,
|
||||||
pending_fb: Option<Slot<Dmabuf, BufferObject<FbHandle<D>>>>,
|
pending_fb: Option<Slot<B, (Dmabuf, BufferObject<FbHandle<D>>)>>,
|
||||||
queued_fb: Option<Slot<Dmabuf, BufferObject<FbHandle<D>>>>,
|
queued_fb: Option<Slot<B, (Dmabuf, BufferObject<FbHandle<D>>)>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D> Buffers<D>
|
impl<D, B> Buffers<D, B>
|
||||||
where
|
where
|
||||||
|
B: Buffer + AsDmabuf,
|
||||||
D: AsRawFd + 'static,
|
D: AsRawFd + 'static,
|
||||||
{
|
{
|
||||||
pub fn new(
|
pub fn new(
|
||||||
drm: Arc<DrmSurface<D>>,
|
drm: Arc<DrmSurface<D>>,
|
||||||
gbm: GbmDevice<gbm::FdWrapper>,
|
gbm: GbmDevice<gbm::FdWrapper>,
|
||||||
slot: Slot<Dmabuf, BufferObject<FbHandle<D>>>,
|
slot: Slot<B, (Dmabuf, BufferObject<FbHandle<D>>)>,
|
||||||
) -> Buffers<D> {
|
) -> Buffers<D, B> {
|
||||||
Buffers {
|
Buffers {
|
||||||
drm,
|
drm,
|
||||||
gbm,
|
gbm,
|
||||||
|
@ -454,16 +461,18 @@ where
|
||||||
|
|
||||||
pub fn queue<E1, E2, E3>(
|
pub fn queue<E1, E2, E3>(
|
||||||
&mut self,
|
&mut self,
|
||||||
slot: Slot<Dmabuf, BufferObject<FbHandle<D>>>,
|
slot: Slot<B, (Dmabuf, BufferObject<FbHandle<D>>)>,
|
||||||
|
dmabuf: Dmabuf,
|
||||||
) -> Result<(), Error<E1, E2, E3>>
|
) -> Result<(), Error<E1, E2, E3>>
|
||||||
where
|
where
|
||||||
|
B: AsDmabuf<Error=E2>,
|
||||||
E1: std::error::Error + 'static,
|
E1: std::error::Error + 'static,
|
||||||
E2: std::error::Error + 'static,
|
E2: std::error::Error + 'static,
|
||||||
E3: std::error::Error + 'static,
|
E3: std::error::Error + 'static,
|
||||||
{
|
{
|
||||||
if slot.userdata().is_none() {
|
if slot.userdata().is_none() {
|
||||||
let bo = import_dmabuf(&self.drm, &self.gbm, &*slot)?;
|
let bo = import_dmabuf(&self.drm, &self.gbm, &dmabuf)?;
|
||||||
slot.set_userdata(bo);
|
slot.set_userdata((dmabuf, bo));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.queued_fb = Some(slot);
|
self.queued_fb = Some(slot);
|
||||||
|
@ -499,7 +508,7 @@ where
|
||||||
{
|
{
|
||||||
// yes it does not look like it, but both of these lines should be safe in all cases.
|
// yes it does not look like it, but both of these lines should be safe in all cases.
|
||||||
let slot = self.queued_fb.take().unwrap();
|
let slot = self.queued_fb.take().unwrap();
|
||||||
let fb = slot.userdata().as_ref().unwrap().userdata().unwrap().unwrap().fb;
|
let fb = slot.userdata().as_ref().unwrap().1.userdata().unwrap().unwrap().fb;
|
||||||
|
|
||||||
let flip = if self.drm.commit_pending() {
|
let flip = if self.drm.commit_pending() {
|
||||||
self.drm.commit(fb, true)
|
self.drm.commit(fb, true)
|
||||||
|
@ -604,7 +613,10 @@ where
|
||||||
GbmError(#[from] std::io::Error),
|
GbmError(#[from] std::io::Error),
|
||||||
/// Error allocating or converting newly created buffers
|
/// Error allocating or converting newly created buffers
|
||||||
#[error("The swapchain encounted an error: {0}")]
|
#[error("The swapchain encounted an error: {0}")]
|
||||||
SwapchainError(#[from] SwapchainError<E1, E2>),
|
SwapchainError(#[source] E1),
|
||||||
|
/// Error exporting as Dmabuf
|
||||||
|
#[error("The allocated buffer could not be exported as a dmabuf: {0}")]
|
||||||
|
AsDmabufError(#[source] E2),
|
||||||
/// Error during rendering
|
/// Error during rendering
|
||||||
#[error("The renderer encounted an error: {0}")]
|
#[error("The renderer encounted an error: {0}")]
|
||||||
RenderError(#[source] E3),
|
RenderError(#[source] E3),
|
||||||
|
@ -626,6 +638,7 @@ impl<
|
||||||
Error::DrmError(err) => err.into(),
|
Error::DrmError(err) => err.into(),
|
||||||
Error::GbmError(err) => SwapBuffersError::ContextLost(Box::new(err)),
|
Error::GbmError(err) => SwapBuffersError::ContextLost(Box::new(err)),
|
||||||
Error::SwapchainError(err) => SwapBuffersError::ContextLost(Box::new(err)),
|
Error::SwapchainError(err) => SwapBuffersError::ContextLost(Box::new(err)),
|
||||||
|
Error::AsDmabufError(err) => SwapBuffersError::ContextLost(Box::new(err)),
|
||||||
Error::RenderError(err) => err.into(),
|
Error::RenderError(err) => err.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue