cargo fmt
This commit is contained in:
parent
b4f216d7b8
commit
149c923876
|
@ -9,7 +9,10 @@ use smithay::{
|
||||||
renderer::{Renderer, Texture, Transform},
|
renderer::{Renderer, Texture, Transform},
|
||||||
SwapBuffersError,
|
SwapBuffersError,
|
||||||
},
|
},
|
||||||
reexports::{calloop::LoopHandle, wayland_server::protocol::{wl_buffer,wl_surface}},
|
reexports::{
|
||||||
|
calloop::LoopHandle,
|
||||||
|
wayland_server::protocol::{wl_buffer, wl_surface},
|
||||||
|
},
|
||||||
utils::Rectangle,
|
utils::Rectangle,
|
||||||
wayland::{
|
wayland::{
|
||||||
compositor::{roles::Role, SubsurfaceRole, TraversalAction},
|
compositor::{roles::Role, SubsurfaceRole, TraversalAction},
|
||||||
|
@ -54,14 +57,7 @@ where
|
||||||
(0, 0)
|
(0, 0)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
draw_surface_tree(
|
draw_surface_tree(renderer, surface, egl_buffer_reader, (x - dx, y - dy), token, log)
|
||||||
renderer,
|
|
||||||
surface,
|
|
||||||
egl_buffer_reader,
|
|
||||||
(x - dx, y - dy),
|
|
||||||
token,
|
|
||||||
log,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_surface_tree<R, E, T>(
|
fn draw_surface_tree<R, E, T>(
|
||||||
|
@ -89,7 +85,10 @@ where
|
||||||
if data.texture.is_none() {
|
if data.texture.is_none() {
|
||||||
if let Some(buffer) = data.current_state.buffer.take() {
|
if let Some(buffer) = data.current_state.buffer.take() {
|
||||||
match renderer.import_buffer(&buffer, egl_buffer_reader) {
|
match renderer.import_buffer(&buffer, egl_buffer_reader) {
|
||||||
Ok(m) => data.texture = Some(Box::new(BufferTextures { buffer, texture: m }) as Box<dyn std::any::Any + 'static>),
|
Ok(m) => {
|
||||||
|
data.texture = Some(Box::new(BufferTextures { buffer, texture: m })
|
||||||
|
as Box<dyn std::any::Any + 'static>)
|
||||||
|
}
|
||||||
// there was an error reading the buffer, release it, we
|
// there was an error reading the buffer, release it, we
|
||||||
// already logged the error
|
// already logged the error
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
@ -154,9 +153,12 @@ where
|
||||||
x += sub_x;
|
x += sub_x;
|
||||||
y += sub_y;
|
y += sub_y;
|
||||||
}
|
}
|
||||||
if let Err(err) =
|
if let Err(err) = renderer.render_texture_at(
|
||||||
renderer.render_texture_at(&texture.texture, (x, y), Transform::Normal /* TODO */, 1.0)
|
&texture.texture,
|
||||||
{
|
(x, y),
|
||||||
|
Transform::Normal, /* TODO */
|
||||||
|
1.0,
|
||||||
|
) {
|
||||||
result = Err(err.into());
|
result = Err(err.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -229,14 +231,7 @@ where
|
||||||
"Trying to display as a dnd icon a surface that does not have the DndIcon role."
|
"Trying to display as a dnd icon a surface that does not have the DndIcon role."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
draw_surface_tree(
|
draw_surface_tree(renderer, surface, egl_buffer_reader, (x, y), token, log)
|
||||||
renderer,
|
|
||||||
surface,
|
|
||||||
egl_buffer_reader,
|
|
||||||
(x, y),
|
|
||||||
token,
|
|
||||||
log,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn schedule_initial_render<R: Renderer + 'static, Data: 'static>(
|
pub fn schedule_initial_render<R: Renderer + 'static, Data: 'static>(
|
||||||
|
|
|
@ -4,6 +4,8 @@ use std::{
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(feature = "egl")]
|
||||||
|
use smithay::backend::egl::display::EGLBufferReader;
|
||||||
use smithay::{
|
use smithay::{
|
||||||
backend::renderer::buffer_dimensions,
|
backend::renderer::buffer_dimensions,
|
||||||
reexports::{
|
reexports::{
|
||||||
|
@ -33,8 +35,6 @@ use smithay::{
|
||||||
Serial,
|
Serial,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
#[cfg(feature = "egl")]
|
|
||||||
use smithay::backend::egl::display::EGLBufferReader;
|
|
||||||
|
|
||||||
use crate::window_map::{Kind as SurfaceKind, WindowMap};
|
use crate::window_map::{Kind as SurfaceKind, WindowMap};
|
||||||
|
|
||||||
|
@ -310,9 +310,8 @@ pub struct ShellHandles {
|
||||||
|
|
||||||
pub fn init_shell(
|
pub fn init_shell(
|
||||||
display: &mut Display,
|
display: &mut Display,
|
||||||
#[cfg(feature = "egl")]
|
#[cfg(feature = "egl")] egl_reader: Rc<RefCell<Option<EGLBufferReader>>>,
|
||||||
egl_reader: Rc<RefCell<Option<EGLBufferReader>>>,
|
log: ::slog::Logger,
|
||||||
log: ::slog::Logger
|
|
||||||
) -> ShellHandles {
|
) -> ShellHandles {
|
||||||
// TODO: this is awkward...
|
// TODO: this is awkward...
|
||||||
let almost_window_map = Rc::new(RefCell::new(None::<Rc<RefCell<MyWindowMap>>>));
|
let almost_window_map = Rc::new(RefCell::new(None::<Rc<RefCell<MyWindowMap>>>));
|
||||||
|
@ -794,8 +793,7 @@ impl SurfaceData {
|
||||||
fn surface_commit(
|
fn surface_commit(
|
||||||
surface: &wl_surface::WlSurface,
|
surface: &wl_surface::WlSurface,
|
||||||
token: CompositorToken<Roles>,
|
token: CompositorToken<Roles>,
|
||||||
#[cfg(feature = "egl")]
|
#[cfg(feature = "egl")] egl_reader: Option<&EGLBufferReader>,
|
||||||
egl_reader: Option<&EGLBufferReader>,
|
|
||||||
window_map: &RefCell<MyWindowMap>,
|
window_map: &RefCell<MyWindowMap>,
|
||||||
) {
|
) {
|
||||||
#[cfg(feature = "xwayland")]
|
#[cfg(feature = "xwayland")]
|
||||||
|
|
|
@ -23,18 +23,18 @@ use smithay::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(feature = "egl")]
|
||||||
|
use smithay::backend::egl::display::EGLBufferReader;
|
||||||
#[cfg(feature = "udev")]
|
#[cfg(feature = "udev")]
|
||||||
use smithay::backend::session::{auto::AutoSession, Session};
|
use smithay::backend::session::{auto::AutoSession, Session};
|
||||||
#[cfg(feature = "xwayland")]
|
#[cfg(feature = "xwayland")]
|
||||||
use smithay::xwayland::XWayland;
|
use smithay::xwayland::XWayland;
|
||||||
#[cfg(feature = "egl")]
|
|
||||||
use smithay::backend::egl::display::EGLBufferReader;
|
|
||||||
|
|
||||||
|
use crate::shell::init_shell;
|
||||||
#[cfg(feature = "udev")]
|
#[cfg(feature = "udev")]
|
||||||
use crate::udev::MyOutput;
|
use crate::udev::MyOutput;
|
||||||
#[cfg(feature = "xwayland")]
|
#[cfg(feature = "xwayland")]
|
||||||
use crate::xwayland::XWm;
|
use crate::xwayland::XWm;
|
||||||
use crate::shell::init_shell;
|
|
||||||
|
|
||||||
pub struct AnvilState {
|
pub struct AnvilState {
|
||||||
pub socket_name: String,
|
pub socket_name: String,
|
||||||
|
|
|
@ -12,6 +12,8 @@ use std::{
|
||||||
use image::{ImageBuffer, Rgba};
|
use image::{ImageBuffer, Rgba};
|
||||||
use slog::Logger;
|
use slog::Logger;
|
||||||
|
|
||||||
|
#[cfg(feature = "egl")]
|
||||||
|
use smithay::backend::{drm::DevPath, egl::display::EGLBufferReader, udev::primary_gpu};
|
||||||
use smithay::{
|
use smithay::{
|
||||||
backend::{
|
backend::{
|
||||||
drm::{device_bind, DeviceHandler, DrmDevice, DrmError, DrmRenderSurface},
|
drm::{device_bind, DeviceHandler, DrmDevice, DrmError, DrmRenderSurface},
|
||||||
|
@ -56,10 +58,6 @@ use smithay::{
|
||||||
seat::CursorImageStatus,
|
seat::CursorImageStatus,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
#[cfg(feature = "egl")]
|
|
||||||
use smithay::{
|
|
||||||
backend::{drm::DevPath, egl::display::EGLBufferReader, udev::primary_gpu},
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::drawing::*;
|
use crate::drawing::*;
|
||||||
use crate::shell::{MyWindowMap, Roles};
|
use crate::shell::{MyWindowMap, Roles};
|
||||||
|
@ -501,7 +499,11 @@ impl<Data: 'static> UdevHandlerImpl<Data> {
|
||||||
let renderer = Rc::new(DrmRenderer {
|
let renderer = Rc::new(DrmRenderer {
|
||||||
device_id,
|
device_id,
|
||||||
#[cfg(feature = "egl")]
|
#[cfg(feature = "egl")]
|
||||||
egl_buffer_reader: if is_primary { self.egl_buffer_reader.borrow().clone() } else { None },
|
egl_buffer_reader: if is_primary {
|
||||||
|
self.egl_buffer_reader.borrow().clone()
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
compositor_token: self.compositor_token,
|
compositor_token: self.compositor_token,
|
||||||
backends: backends.clone(),
|
backends: backends.clone(),
|
||||||
window_map: self.window_map.clone(),
|
window_map: self.window_map.clone(),
|
||||||
|
@ -741,8 +743,7 @@ impl DrmRenderer {
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn render_surface(
|
fn render_surface(
|
||||||
surface: &mut RenderSurface,
|
surface: &mut RenderSurface,
|
||||||
#[cfg(feature = "egl")]
|
#[cfg(feature = "egl")] egl_buffer_reader: Option<&EGLBufferReader>,
|
||||||
egl_buffer_reader: Option<&EGLBufferReader>,
|
|
||||||
device_id: dev_t,
|
device_id: dev_t,
|
||||||
crtc: crtc::Handle,
|
crtc: crtc::Handle,
|
||||||
window_map: &mut MyWindowMap,
|
window_map: &mut MyWindowMap,
|
||||||
|
|
|
@ -132,8 +132,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DrmHandlerImpl {
|
pub struct DrmHandlerImpl {
|
||||||
swapchain:
|
swapchain: Swapchain<DrmDevice<FdWrapper>, DumbBuffer<FdWrapper>, framebuffer::Handle>,
|
||||||
Swapchain<DrmDevice<FdWrapper>, DumbBuffer<FdWrapper>, framebuffer::Handle>,
|
|
||||||
current: Slot<DumbBuffer<FdWrapper>, framebuffer::Handle>,
|
current: Slot<DumbBuffer<FdWrapper>, framebuffer::Handle>,
|
||||||
surface: Rc<DrmSurface<FdWrapper>>,
|
surface: Rc<DrmSurface<FdWrapper>>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,9 @@ pub struct DumbBuffer<A: AsRawFd + 'static> {
|
||||||
impl<A: AsRawFd + 'static> fmt::Debug for DumbBuffer<A> {
|
impl<A: AsRawFd + 'static> fmt::Debug for DumbBuffer<A> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("DumbBuffer")
|
f.debug_struct("DumbBuffer")
|
||||||
.field("handle", &self.handle)
|
.field("handle", &self.handle)
|
||||||
.field("format", &self.format)
|
.field("format", &self.format)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
//! Module for Buffers created using [libgbm](reexports::gbm)
|
//! Module for Buffers created using [libgbm](reexports::gbm)
|
||||||
|
|
||||||
use super::{dmabuf::{AsDmabuf, Dmabuf}, Allocator, Buffer, Format, Fourcc, Modifier};
|
use super::{
|
||||||
|
dmabuf::{AsDmabuf, Dmabuf},
|
||||||
|
Allocator, Buffer, Format, Fourcc, Modifier,
|
||||||
|
};
|
||||||
use gbm::{BufferObject as GbmBuffer, BufferObjectFlags, Device as GbmDevice};
|
use gbm::{BufferObject as GbmBuffer, BufferObjectFlags, Device as GbmDevice};
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
|
|
||||||
|
|
|
@ -132,10 +132,11 @@ where
|
||||||
pub fn acquire(&mut self) -> Result<Option<Slot<B, U>>, A::Error> {
|
pub fn acquire(&mut self) -> Result<Option<Slot<B, U>>, A::Error> {
|
||||||
if let Some(free_slot) = self.slots.iter_mut().find(|s| !s.acquired.load(Ordering::SeqCst)) {
|
if let Some(free_slot) = self.slots.iter_mut().find(|s| !s.acquired.load(Ordering::SeqCst)) {
|
||||||
if free_slot.buffer.is_none() {
|
if free_slot.buffer.is_none() {
|
||||||
free_slot.buffer = Arc::new(Some(
|
free_slot.buffer = Arc::new(Some(self.allocator.create_buffer(
|
||||||
self.allocator
|
self.width,
|
||||||
.create_buffer(self.width, self.height, self.format)?
|
self.height,
|
||||||
));
|
self.format,
|
||||||
|
)?));
|
||||||
}
|
}
|
||||||
assert!(free_slot.buffer.is_some());
|
assert!(free_slot.buffer.is_some());
|
||||||
|
|
||||||
|
|
|
@ -10,12 +10,15 @@ 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::{dmabuf::{AsDmabuf, Dmabuf}, Allocator, Buffer, Format, Fourcc, Modifier, Slot, Swapchain},
|
|
||||||
egl::display::EGLBufferReader,
|
|
||||||
};
|
|
||||||
use crate::backend::renderer::{Bind, Renderer, Texture, Transform};
|
use crate::backend::renderer::{Bind, Renderer, Texture, Transform};
|
||||||
use crate::backend::SwapBuffersError;
|
use crate::backend::SwapBuffersError;
|
||||||
|
use crate::backend::{
|
||||||
|
allocator::{
|
||||||
|
dmabuf::{AsDmabuf, Dmabuf},
|
||||||
|
Allocator, Buffer, Format, Fourcc, Modifier, Slot, Swapchain,
|
||||||
|
},
|
||||||
|
egl::display::EGLBufferReader,
|
||||||
|
};
|
||||||
|
|
||||||
/// Simplified by limited abstraction to link single [`DrmSurface`]s to renderers.
|
/// Simplified by limited abstraction to link single [`DrmSurface`]s to renderers.
|
||||||
///
|
///
|
||||||
|
@ -24,12 +27,7 @@ use crate::backend::SwapBuffersError;
|
||||||
/// In some scenarios it might be enough to use of a drm-surface as the one and only target
|
/// In some scenarios it might be enough to use of a drm-surface as the one and only target
|
||||||
/// of a single renderer. In these cases `DrmRenderSurface` provides a way to quickly
|
/// of a single renderer. In these cases `DrmRenderSurface` provides a way to quickly
|
||||||
/// get up and running without manually handling and binding buffers.
|
/// get up and running without manually handling and binding buffers.
|
||||||
pub struct DrmRenderSurface<
|
pub struct DrmRenderSurface<D: AsRawFd + 'static, A: Allocator<B>, R: Bind<Dmabuf>, B: Buffer> {
|
||||||
D: AsRawFd + 'static,
|
|
||||||
A: Allocator<B>,
|
|
||||||
R: Bind<Dmabuf>,
|
|
||||||
B: Buffer,
|
|
||||||
> {
|
|
||||||
_format: Format,
|
_format: Format,
|
||||||
buffers: Buffers<D, B>,
|
buffers: Buffers<D, B>,
|
||||||
current_buffer: Option<(Slot<B, (Dmabuf, BufferObject<FbHandle<D>>)>, Dmabuf)>,
|
current_buffer: Option<(Slot<B, (Dmabuf, BufferObject<FbHandle<D>>)>, Dmabuf)>,
|
||||||
|
@ -42,7 +40,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 + AsDmabuf<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,
|
||||||
|
@ -328,7 +326,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 + AsDmabuf<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,
|
||||||
|
@ -352,19 +350,29 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "wayland_frontend")]
|
#[cfg(feature = "wayland_frontend")]
|
||||||
fn import_buffer(&mut self, buffer: &wl_buffer::WlBuffer, egl: Option<&EGLBufferReader>) -> Result<Self::TextureId, Self::Error> {
|
fn import_buffer(
|
||||||
self.renderer.import_buffer(buffer, egl).map_err(Error::RenderError)
|
&mut self,
|
||||||
|
buffer: &wl_buffer::WlBuffer,
|
||||||
|
egl: Option<&EGLBufferReader>,
|
||||||
|
) -> Result<Self::TextureId, Self::Error> {
|
||||||
|
self.renderer
|
||||||
|
.import_buffer(buffer, egl)
|
||||||
|
.map_err(Error::RenderError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn begin(&mut self, width: u32, height: u32, _transform: Transform) -> Result<(), Error<E1, E2, E3>> {
|
fn begin(&mut self, width: u32, height: u32, _transform: Transform) -> Result<(), Error<E1, E2, E3>> {
|
||||||
if self.current_buffer.is_some() {
|
if self.current_buffer.is_some() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let slot = self.swapchain.acquire().map_err(Error::SwapchainError)?.ok_or(Error::NoFreeSlotsError)?;
|
let slot = self
|
||||||
|
.swapchain
|
||||||
|
.acquire()
|
||||||
|
.map_err(Error::SwapchainError)?
|
||||||
|
.ok_or(Error::NoFreeSlotsError)?;
|
||||||
let dmabuf = match &*slot.userdata() {
|
let dmabuf = match &*slot.userdata() {
|
||||||
Some((buf, _)) => buf.clone(),
|
Some((buf, _)) => buf.clone(),
|
||||||
None => (*slot).export().map_err(Error::AsDmabufError)?,
|
None => (*slot).export().map_err(Error::AsDmabufError)?,
|
||||||
};
|
};
|
||||||
self.renderer.bind(dmabuf.clone()).map_err(Error::RenderError)?;
|
self.renderer.bind(dmabuf.clone()).map_err(Error::RenderError)?;
|
||||||
self.current_buffer = Some((slot, dmabuf));
|
self.current_buffer = Some((slot, dmabuf));
|
||||||
|
@ -396,10 +404,7 @@ 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();
|
let (slot, dmabuf) = self.current_buffer.take().unwrap();
|
||||||
match self
|
match self.buffers.queue::<E1, E2, E3>(slot, dmabuf) {
|
||||||
.buffers
|
|
||||||
.queue::<E1, E2, E3>(slot, dmabuf)
|
|
||||||
{
|
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
Err(Error::DrmError(drm)) => return Err(drm.into()),
|
Err(Error::DrmError(drm)) => return Err(drm.into()),
|
||||||
Err(Error::GbmError(err)) => return Err(SwapBuffersError::ContextLost(Box::new(err))),
|
Err(Error::GbmError(err)) => return Err(SwapBuffersError::ContextLost(Box::new(err))),
|
||||||
|
@ -454,7 +459,7 @@ where
|
||||||
dmabuf: Dmabuf,
|
dmabuf: Dmabuf,
|
||||||
) -> Result<(), Error<E1, E2, E3>>
|
) -> Result<(), Error<E1, E2, E3>>
|
||||||
where
|
where
|
||||||
B: AsDmabuf<Error=E2>,
|
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,
|
||||||
|
@ -497,7 +502,15 @@ 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().1.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)
|
||||||
|
|
|
@ -617,7 +617,10 @@ pub struct EGLBufferReader {
|
||||||
#[cfg(feature = "use_system_lib")]
|
#[cfg(feature = "use_system_lib")]
|
||||||
impl EGLBufferReader {
|
impl EGLBufferReader {
|
||||||
fn new(display: Arc<EGLDisplayHandle>, wayland: *mut wl_display) -> Self {
|
fn new(display: Arc<EGLDisplayHandle>, wayland: *mut wl_display) -> Self {
|
||||||
Self { display, wayland: Some(Arc::new(wayland)) }
|
Self {
|
||||||
|
display,
|
||||||
|
wayland: Some(Arc::new(wayland)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Try to receive [`EGLImages`] from a given [`WlBuffer`].
|
/// Try to receive [`EGLImages`] from a given [`WlBuffer`].
|
||||||
|
|
|
@ -29,14 +29,14 @@ pub struct EGLSurface {
|
||||||
impl fmt::Debug for EGLSurface {
|
impl fmt::Debug for EGLSurface {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("EGLSurface")
|
f.debug_struct("EGLSurface")
|
||||||
.field("display", &self.display)
|
.field("display", &self.display)
|
||||||
// native does not necessarily implement Debug
|
// native does not necessarily implement Debug
|
||||||
.field("surface", &self.surface)
|
.field("surface", &self.surface)
|
||||||
.field("config_id", &self.config_id)
|
.field("config_id", &self.config_id)
|
||||||
.field("pixel_format", &self.pixel_format)
|
.field("pixel_format", &self.pixel_format)
|
||||||
.field("surface_attributes", &self.surface_attributes)
|
.field("surface_attributes", &self.surface_attributes)
|
||||||
.field("logger", &self.logger)
|
.field("logger", &self.logger)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
//! Implementation of the rendering traits using OpenGL ES 2
|
//! Implementation of the rendering traits using OpenGL ES 2
|
||||||
|
|
||||||
use std::{collections::HashSet, os::raw::c_char};
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::fmt;
|
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
|
use std::fmt;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::{
|
use std::sync::{
|
||||||
atomic::{Ordering, AtomicUsize},
|
atomic::{AtomicUsize, Ordering},
|
||||||
mpsc::{Sender, Receiver, channel}
|
mpsc::{channel, Receiver, Sender},
|
||||||
};
|
};
|
||||||
|
use std::{collections::HashSet, os::raw::c_char};
|
||||||
|
|
||||||
use cgmath::{prelude::*, Matrix3};
|
use cgmath::{prelude::*, Matrix3};
|
||||||
|
|
||||||
|
@ -20,7 +20,8 @@ use crate::backend::allocator::{
|
||||||
Format,
|
Format,
|
||||||
};
|
};
|
||||||
use crate::backend::egl::{
|
use crate::backend::egl::{
|
||||||
ffi::egl::types::EGLImage, EGLBuffer, EGLContext, EGLSurface, Format as EGLFormat, MakeCurrentError, display::EGLBufferReader,
|
display::EGLBufferReader, ffi::egl::types::EGLImage, EGLBuffer, EGLContext, EGLSurface,
|
||||||
|
Format as EGLFormat, MakeCurrentError,
|
||||||
};
|
};
|
||||||
use crate::backend::SwapBuffersError;
|
use crate::backend::SwapBuffersError;
|
||||||
|
|
||||||
|
@ -109,17 +110,17 @@ pub struct Gles2Renderer {
|
||||||
impl fmt::Debug for Gles2Renderer {
|
impl fmt::Debug for Gles2Renderer {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("Gles2Renderer")
|
f.debug_struct("Gles2Renderer")
|
||||||
.field("id", &self.id)
|
.field("id", &self.id)
|
||||||
.field("buffers", &self.buffers)
|
.field("buffers", &self.buffers)
|
||||||
.field("target_buffer", &self.target_buffer)
|
.field("target_buffer", &self.target_buffer)
|
||||||
.field("target_surface", &self.target_surface)
|
.field("target_surface", &self.target_surface)
|
||||||
.field("current_projection", &self.current_projection)
|
.field("current_projection", &self.current_projection)
|
||||||
.field("extensions", &self.extensions)
|
.field("extensions", &self.extensions)
|
||||||
.field("programs", &self.programs)
|
.field("programs", &self.programs)
|
||||||
// ffi::Gles2 does not implement Debug
|
// ffi::Gles2 does not implement Debug
|
||||||
.field("egl", &self.egl)
|
.field("egl", &self.egl)
|
||||||
.field("logger", &self.logger)
|
.field("logger", &self.logger)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -409,8 +410,8 @@ struct BufferCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
enum BufferCacheVariant {
|
enum BufferCacheVariant {
|
||||||
Egl(Option<EglCache>),
|
Egl(Option<EglCache>),
|
||||||
Shm(Option<ShmCache>),
|
Shm(Option<ShmCache>),
|
||||||
}
|
}
|
||||||
|
|
||||||
struct EglCache {
|
struct EglCache {
|
||||||
|
@ -424,7 +425,11 @@ struct ShmCache {
|
||||||
|
|
||||||
impl Gles2Renderer {
|
impl Gles2Renderer {
|
||||||
#[cfg(feature = "wayland_frontend")]
|
#[cfg(feature = "wayland_frontend")]
|
||||||
fn import_shm(&mut self, buffer: &wl_buffer::WlBuffer, cache: &mut Option<ShmCache>) -> Result<Gles2Texture, Gles2Error> {
|
fn import_shm(
|
||||||
|
&mut self,
|
||||||
|
buffer: &wl_buffer::WlBuffer,
|
||||||
|
cache: &mut Option<ShmCache>,
|
||||||
|
) -> Result<Gles2Texture, Gles2Error> {
|
||||||
use crate::wayland::shm::with_buffer_contents;
|
use crate::wayland::shm::with_buffer_contents;
|
||||||
|
|
||||||
with_buffer_contents(&buffer, |slice, data| {
|
with_buffer_contents(&buffer, |slice, data| {
|
||||||
|
@ -500,22 +505,34 @@ impl Gles2Renderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "wayland_frontend")]
|
#[cfg(feature = "wayland_frontend")]
|
||||||
fn import_egl(&mut self, buffer: &wl_buffer::WlBuffer, reader: &EGLBufferReader, cache: &mut Option<EglCache>) -> Result<Gles2Texture, Gles2Error> {
|
fn import_egl(
|
||||||
|
&mut self,
|
||||||
|
buffer: &wl_buffer::WlBuffer,
|
||||||
|
reader: &EGLBufferReader,
|
||||||
|
cache: &mut Option<EglCache>,
|
||||||
|
) -> Result<Gles2Texture, Gles2Error> {
|
||||||
if !self.extensions.iter().any(|ext| ext == "GL_OES_EGL_image") {
|
if !self.extensions.iter().any(|ext| ext == "GL_OES_EGL_image") {
|
||||||
return Err(Gles2Error::GLExtensionNotSupported(&["GL_OES_EGL_image"]));
|
return Err(Gles2Error::GLExtensionNotSupported(&["GL_OES_EGL_image"]));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.make_current()?;
|
self.make_current()?;
|
||||||
let egl_buffer = cache.as_mut().and_then(|x| x.buf.take()).map(Ok).unwrap_or_else(|| {
|
let egl_buffer = cache
|
||||||
reader.egl_buffer_contents(&buffer)
|
.as_mut()
|
||||||
}).map_err(Gles2Error::EGLBufferAccessError)?;
|
.and_then(|x| x.buf.take())
|
||||||
|
.map(Ok)
|
||||||
|
.unwrap_or_else(|| reader.egl_buffer_contents(&buffer))
|
||||||
|
.map_err(Gles2Error::EGLBufferAccessError)?;
|
||||||
|
|
||||||
// we do not need to re-import external textures
|
// we do not need to re-import external textures
|
||||||
if egl_buffer.format == EGLFormat::External && cache.is_some() {
|
if egl_buffer.format == EGLFormat::External && cache.is_some() {
|
||||||
return Ok(cache.as_ref().map(|x| x.texture.clone()).unwrap());
|
return Ok(cache.as_ref().map(|x| x.texture.clone()).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
let tex = self.import_egl_image(egl_buffer.image(0).unwrap(), egl_buffer.format == EGLFormat::External, cache.as_ref().map(|x| x.texture.0.texture))?;
|
let tex = self.import_egl_image(
|
||||||
|
egl_buffer.image(0).unwrap(),
|
||||||
|
egl_buffer.format == EGLFormat::External,
|
||||||
|
cache.as_ref().map(|x| x.texture.0.texture),
|
||||||
|
)?;
|
||||||
let texture = cache.as_ref().map(|x| x.texture.clone()).unwrap_or_else(|| {
|
let texture = cache.as_ref().map(|x| x.texture.clone()).unwrap_or_else(|| {
|
||||||
Gles2Texture(Rc::new(Gles2TextureInternal {
|
Gles2Texture(Rc::new(Gles2TextureInternal {
|
||||||
texture: tex,
|
texture: tex,
|
||||||
|
@ -542,7 +559,12 @@ impl Gles2Renderer {
|
||||||
Ok(texture)
|
Ok(texture)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn import_egl_image(&self, image: EGLImage, is_external: bool, tex: Option<u32>) -> Result<u32, Gles2Error> {
|
fn import_egl_image(
|
||||||
|
&self,
|
||||||
|
image: EGLImage,
|
||||||
|
is_external: bool,
|
||||||
|
tex: Option<u32>,
|
||||||
|
) -> Result<u32, Gles2Error> {
|
||||||
let tex = tex.unwrap_or_else(|| unsafe {
|
let tex = tex.unwrap_or_else(|| unsafe {
|
||||||
let mut tex = 0;
|
let mut tex = 0;
|
||||||
self.gl.GenTextures(1, &mut tex);
|
self.gl.GenTextures(1, &mut tex);
|
||||||
|
@ -556,8 +578,7 @@ impl Gles2Renderer {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.gl.BindTexture(target, tex);
|
self.gl.BindTexture(target, tex);
|
||||||
|
|
||||||
self.gl
|
self.gl.EGLImageTargetTexture2DOES(target, image);
|
||||||
.EGLImageTargetTexture2DOES(target, image);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(tex)
|
Ok(tex)
|
||||||
|
@ -593,7 +614,13 @@ impl Bind<Dmabuf> for Gles2Renderer {
|
||||||
let buffer = self
|
let buffer = self
|
||||||
.buffers
|
.buffers
|
||||||
.iter()
|
.iter()
|
||||||
.find(|buffer| if let Some(dma) = buffer.dmabuf.upgrade() { dma == dmabuf } else { false })
|
.find(|buffer| {
|
||||||
|
if let Some(dma) = buffer.dmabuf.upgrade() {
|
||||||
|
dma == dmabuf
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
})
|
||||||
.map(|buf| {
|
.map(|buf| {
|
||||||
let dmabuf = buf
|
let dmabuf = buf
|
||||||
.dmabuf
|
.dmabuf
|
||||||
|
@ -773,15 +800,18 @@ impl Renderer for Gles2Renderer {
|
||||||
Ok(texture)
|
Ok(texture)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[cfg(feature = "wayland_frontend")]
|
#[cfg(feature = "wayland_frontend")]
|
||||||
fn import_buffer(&mut self, buffer: &wl_buffer::WlBuffer, egl: Option<&EGLBufferReader>) -> Result<Self::TextureId, Self::Error> {
|
fn import_buffer(
|
||||||
|
&mut self,
|
||||||
|
buffer: &wl_buffer::WlBuffer,
|
||||||
|
egl: Option<&EGLBufferReader>,
|
||||||
|
) -> Result<Self::TextureId, Self::Error> {
|
||||||
// init cache if not existing
|
// init cache if not existing
|
||||||
let cache_cell = match buffer.as_ref().user_data().get::<Rc<RefCell<BufferCache>>>() {
|
let cache_cell = match buffer.as_ref().user_data().get::<Rc<RefCell<BufferCache>>>() {
|
||||||
Some(cache) => cache.clone(),
|
Some(cache) => cache.clone(),
|
||||||
None => {
|
None => {
|
||||||
let cache = BufferCache {
|
let cache = BufferCache {
|
||||||
cache: Vec::with_capacity(self.id+1),
|
cache: Vec::with_capacity(self.id + 1),
|
||||||
};
|
};
|
||||||
|
|
||||||
let data: Rc<RefCell<BufferCache>> = Rc::new(RefCell::new(cache));
|
let data: Rc<RefCell<BufferCache>> = Rc::new(RefCell::new(cache));
|
||||||
|
@ -790,7 +820,7 @@ impl Renderer for Gles2Renderer {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// init cache
|
// init cache
|
||||||
let mut cache = cache_cell.borrow_mut();
|
let mut cache = cache_cell.borrow_mut();
|
||||||
while cache.cache.len() < self.id {
|
while cache.cache.len() < self.id {
|
||||||
|
@ -805,10 +835,10 @@ impl Renderer for Gles2Renderer {
|
||||||
BufferCacheVariant::Shm(None)
|
BufferCacheVariant::Shm(None)
|
||||||
} else {
|
} else {
|
||||||
unreachable!("Completely unknown buffer format. How did we got here?");
|
unreachable!("Completely unknown buffer format. How did we got here?");
|
||||||
}
|
},
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// delegate for different buffer types
|
// delegate for different buffer types
|
||||||
match cache.cache[self.id].as_mut() {
|
match cache.cache[self.id].as_mut() {
|
||||||
Some(BufferCacheVariant::Egl(cache)) => self.import_egl(&buffer, egl.unwrap(), cache),
|
Some(BufferCacheVariant::Egl(cache)) => self.import_egl(&buffer, egl.unwrap(), cache),
|
||||||
|
@ -889,7 +919,8 @@ impl Renderer for Gles2Renderer {
|
||||||
.TexParameteri(target, ffi::TEXTURE_MIN_FILTER, ffi::LINEAR as i32);
|
.TexParameteri(target, ffi::TEXTURE_MIN_FILTER, ffi::LINEAR as i32);
|
||||||
self.gl.UseProgram(self.programs[tex.0.texture_kind].program);
|
self.gl.UseProgram(self.programs[tex.0.texture_kind].program);
|
||||||
|
|
||||||
self.gl.Uniform1i(self.programs[tex.0.texture_kind].uniform_tex, 0);
|
self.gl
|
||||||
|
.Uniform1i(self.programs[tex.0.texture_kind].uniform_tex, 0);
|
||||||
self.gl.UniformMatrix3fv(
|
self.gl.UniformMatrix3fv(
|
||||||
self.programs[tex.0.texture_kind].uniform_matrix,
|
self.programs[tex.0.texture_kind].uniform_matrix,
|
||||||
1,
|
1,
|
||||||
|
|
|
@ -164,7 +164,6 @@ pub trait Renderer {
|
||||||
&[wl_shm::Format::Argb8888, wl_shm::Format::Xrgb8888]
|
&[wl_shm::Format::Argb8888, wl_shm::Format::Xrgb8888]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Import a given buffer into the renderer.
|
/// Import a given buffer into the renderer.
|
||||||
///
|
///
|
||||||
/// Returns a texture_id, which can be used with `render_texture(_at)` or implementation-specific functions.
|
/// Returns a texture_id, which can be used with `render_texture(_at)` or implementation-specific functions.
|
||||||
|
@ -176,7 +175,11 @@ pub trait Renderer {
|
||||||
/// The implementation defines, if the id keeps being valid, if the buffer is released,
|
/// The implementation defines, if the id keeps being valid, if the buffer is released,
|
||||||
/// to avoid relying on implementation details, keep the buffer alive, until you destroyed this texture again.
|
/// to avoid relying on implementation details, keep the buffer alive, until you destroyed this texture again.
|
||||||
#[cfg(feature = "wayland_frontend")]
|
#[cfg(feature = "wayland_frontend")]
|
||||||
fn import_buffer(&mut self, buffer: &wl_buffer::WlBuffer, egl: Option<&EGLBufferReader>) -> Result<Self::TextureId, Self::Error>;
|
fn import_buffer(
|
||||||
|
&mut self,
|
||||||
|
buffer: &wl_buffer::WlBuffer,
|
||||||
|
egl: Option<&EGLBufferReader>,
|
||||||
|
) -> Result<Self::TextureId, Self::Error>;
|
||||||
|
|
||||||
/// Initialize a rendering context on the current rendering target with given dimensions and transformation.
|
/// Initialize a rendering context on the current rendering target with given dimensions and transformation.
|
||||||
///
|
///
|
||||||
|
@ -248,10 +251,18 @@ pub trait Renderer {
|
||||||
|
|
||||||
/// Returns the dimensions of a wl_buffer
|
/// Returns the dimensions of a wl_buffer
|
||||||
#[cfg(all(feature = "wayland_frontend", feature = "backend_egl"))]
|
#[cfg(all(feature = "wayland_frontend", feature = "backend_egl"))]
|
||||||
pub fn buffer_dimensions(buffer: &wl_buffer::WlBuffer, egl_buffer_reader: Option<&EGLBufferReader>) -> Option<(i32, i32)> {
|
pub fn buffer_dimensions(
|
||||||
if let Some((w, h)) = egl_buffer_reader.as_ref().and_then(|x| x.egl_buffer_dimensions(&buffer)) {
|
buffer: &wl_buffer::WlBuffer,
|
||||||
|
egl_buffer_reader: Option<&EGLBufferReader>,
|
||||||
|
) -> Option<(i32, i32)> {
|
||||||
|
if let Some((w, h)) = egl_buffer_reader
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|x| x.egl_buffer_dimensions(&buffer))
|
||||||
|
{
|
||||||
Some((w, h))
|
Some((w, h))
|
||||||
} else if let Ok((w, h)) = crate::wayland::shm::with_buffer_contents(&buffer, |_, data| (data.width, data.height)) {
|
} else if let Ok((w, h)) =
|
||||||
|
crate::wayland::shm::with_buffer_contents(&buffer, |_, data| (data.width, data.height))
|
||||||
|
{
|
||||||
Some((w, h))
|
Some((w, h))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -263,9 +274,11 @@ pub fn buffer_dimensions(buffer: &wl_buffer::WlBuffer, egl_buffer_reader: Option
|
||||||
pub fn buffer_dimensions(buffer: &wl_buffer::WlBuffer) -> Option<(i32, i32)> {
|
pub fn buffer_dimensions(buffer: &wl_buffer::WlBuffer) -> Option<(i32, i32)> {
|
||||||
use crate::backend::allocator::Buffer;
|
use crate::backend::allocator::Buffer;
|
||||||
|
|
||||||
if let Ok((w, h)) = crate::wayland::shm::with_buffer_contents(&buffer, |_, data| (data.width, data.height)) {
|
if let Ok((w, h)) =
|
||||||
|
crate::wayland::shm::with_buffer_contents(&buffer, |_, data| (data.width, data.height))
|
||||||
|
{
|
||||||
Some((w, h))
|
Some((w, h))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -291,7 +291,11 @@ impl Renderer for WinitGraphicsBackend {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "wayland_frontend")]
|
#[cfg(feature = "wayland_frontend")]
|
||||||
fn import_buffer(&mut self, buffer: &wl_buffer::WlBuffer, egl: Option<&EGLBufferReader>) -> Result<Self::TextureId, Self::Error> {
|
fn import_buffer(
|
||||||
|
&mut self,
|
||||||
|
buffer: &wl_buffer::WlBuffer,
|
||||||
|
egl: Option<&EGLBufferReader>,
|
||||||
|
) -> Result<Self::TextureId, Self::Error> {
|
||||||
self.renderer.import_buffer(buffer, egl)
|
self.renderer.import_buffer(buffer, egl)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue