renderer: Implement import_egl for wl_drm

This commit is contained in:
Victor Brekenfeld 2021-04-26 21:43:30 +02:00
parent 348c63b350
commit 50b0083269
5 changed files with 60 additions and 6 deletions

View File

@ -13,6 +13,7 @@ use wayland_server::protocol::{wl_shm, wl_buffer};
use crate::backend::SwapBuffersError; use crate::backend::SwapBuffersError;
use crate::backend::allocator::{Allocator, Format, Fourcc, Modifier, Swapchain, SwapchainError, Slot, Buffer, dmabuf::Dmabuf}; use crate::backend::allocator::{Allocator, Format, Fourcc, Modifier, Swapchain, SwapchainError, Slot, Buffer, dmabuf::Dmabuf};
use crate::backend::renderer::{Renderer, Bind, Transform, Texture}; use crate::backend::renderer::{Renderer, Bind, Transform, Texture};
use crate::backend::egl::EGLBuffer;
use super::{DrmSurface, DrmError, device::DevPath, surface::DrmSurfaceInternal}; use super::{DrmSurface, DrmError, device::DevPath, surface::DrmSurfaceInternal};
pub struct DrmRenderSurface< pub struct DrmRenderSurface<
@ -246,6 +247,11 @@ where
self.renderer.import_shm(buffer).map_err(Error::RenderError) self.renderer.import_shm(buffer).map_err(Error::RenderError)
} }
#[cfg(feature = "wayland_frontend")]
fn import_egl(&mut self, buffer: &EGLBuffer) -> Result<Self::Texture, Self::Error> {
self.renderer.import_egl(buffer).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(());

View File

@ -212,7 +212,7 @@ pub enum TextureCreationError {
/// Texture format types /// Texture format types
#[repr(i32)] #[repr(i32)]
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
#[derive(Debug)] #[derive(Debug, PartialEq, Eq)]
pub enum Format { pub enum Format {
/// RGB format /// RGB format
RGB = ffi::egl::TEXTURE_RGB as i32, RGB = ffi::egl::TEXTURE_RGB as i32,

View File

@ -8,7 +8,7 @@ use cgmath::{prelude::*, Matrix3, Vector2};
mod shaders; mod shaders;
use crate::backend::SwapBuffersError; use crate::backend::SwapBuffersError;
use crate::backend::allocator::{dmabuf::{Dmabuf, WeakDmabuf}, Format}; use crate::backend::allocator::{dmabuf::{Dmabuf, WeakDmabuf}, Format};
use crate::backend::egl::{EGLContext, EGLSurface, ffi::egl::types::EGLImage, MakeCurrentError}; use crate::backend::egl::{EGLContext, EGLSurface, EGLBuffer, Format as EGLFormat, ffi::egl::types::EGLImage, MakeCurrentError};
use super::{Renderer, Bind, Unbind, Transform, Texture}; use super::{Renderer, Bind, Unbind, Transform, Texture};
#[cfg(feature = "wayland_frontend")] #[cfg(feature = "wayland_frontend")]
@ -461,7 +461,7 @@ impl Renderer for Gles2Renderer {
height: image.height(), height: image.height(),
}; };
self.egl.unbind()?; self.egl.unbind()?;
Ok(texture) Ok(texture)
} }
@ -521,6 +521,45 @@ impl Renderer for Gles2Renderer {
}).map_err(Gles2Error::BufferAccessError)? }).map_err(Gles2Error::BufferAccessError)?
} }
#[cfg(feature = "wayland_frontend")]
fn import_egl(&mut self, buffer: &EGLBuffer) -> Result<Self::Texture, Self::Error> {
if !self.extensions.iter().any(|ext| ext == "GL_OES_EGL_image") {
return Err(Gles2Error::GLExtensionNotSupported(&["GL_OES_EGL_image"]));
}
self.make_current()?;
let mut tex = 0;
let target = if buffer.format == EGLFormat::External { ffi::TEXTURE_EXTERNAL_OES } else { ffi::TEXTURE_2D };
unsafe {
self.gl.GenTextures(1, &mut tex);
self.gl.BindTexture(target, tex);
self.gl.EGLImageTargetTexture2DOES(
target,
buffer.image(0).unwrap(),
);
}
let texture = Gles2Texture {
texture: tex,
texture_kind: match buffer.format {
EGLFormat::RGB => 3,
EGLFormat::RGBA => 2,
EGLFormat::External => 4,
_ => unreachable!("EGLBuffer currenly does not expose multi-planar buffers to us"),
},
is_external: buffer.format == EGLFormat::External,
y_inverted: buffer.y_inverted,
width: buffer.width,
height: buffer.height,
};
self.egl.unbind()?;
Ok(texture)
}
fn begin(&mut self, width: u32, height: u32, transform: Transform) -> Result<(), Gles2Error> { fn begin(&mut self, width: u32, height: u32, transform: Transform) -> Result<(), Gles2Error> {
self.make_current()?; self.make_current()?;
unsafe { unsafe {

View File

@ -8,6 +8,8 @@ use wayland_server::protocol::{wl_shm, wl_buffer};
use crate::backend::SwapBuffersError; use crate::backend::SwapBuffersError;
#[cfg(feature = "renderer_gl")] #[cfg(feature = "renderer_gl")]
pub mod gles2; pub mod gles2;
#[cfg(feature = "wayland_frontend")]
use crate::backend::egl::EGLBuffer;
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
pub enum Transform { pub enum Transform {
@ -143,7 +145,9 @@ pub trait Renderer {
} }
#[cfg(feature = "wayland_frontend")] #[cfg(feature = "wayland_frontend")]
fn import_shm(&mut self, buffer: &wl_buffer::WlBuffer) -> Result<Self::Texture, Self::Error>; fn import_shm(&mut self, buffer: &wl_buffer::WlBuffer) -> Result<Self::Texture, Self::Error>;
#[cfg(feature = "wayland_frontend")]
fn import_egl(&mut self, buffer: &EGLBuffer) -> Result<Self::Texture, Self::Error>;
fn begin(&mut self, width: u32, height: u32, transform: Transform) -> Result<(), <Self as Renderer>::Error>; fn begin(&mut self, width: u32, height: u32, transform: Transform) -> Result<(), <Self as Renderer>::Error>;
fn finish(&mut self) -> Result<(), SwapBuffersError>; fn finish(&mut self) -> Result<(), SwapBuffersError>;

View File

@ -2,7 +2,7 @@
use crate::backend::egl::display::EGLDisplay; use crate::backend::egl::display::EGLDisplay;
use crate::backend::{ use crate::backend::{
egl::{context::GlAttributes, native, EGLContext, EGLSurface, Error as EGLError}, egl::{context::GlAttributes, native, EGLContext, EGLSurface, EGLBuffer, Error as EGLError},
renderer::{ renderer::{
Renderer, Bind, Transform, Renderer, Bind, Transform,
gles2::{Gles2Renderer, Gles2Error, Gles2Texture}, gles2::{Gles2Renderer, Gles2Error, Gles2Texture},
@ -259,7 +259,7 @@ impl WinitGraphicsBackend {
impl Renderer for WinitGraphicsBackend { impl Renderer for WinitGraphicsBackend {
type Error = Gles2Error; type Error = Gles2Error;
type Texture = Gles2Texture; type Texture = Gles2Texture;
#[cfg(feature = "image")] #[cfg(feature = "image")]
fn import_bitmap<C: std::ops::Deref<Target=[u8]>>(&mut self, image: &image::ImageBuffer<image::Rgba<u8>, C>) -> Result<Self::Texture, Self::Error> { fn import_bitmap<C: std::ops::Deref<Target=[u8]>>(&mut self, image: &image::ImageBuffer<image::Rgba<u8>, C>) -> Result<Self::Texture, Self::Error> {
self.renderer.import_bitmap(image) self.renderer.import_bitmap(image)
@ -274,6 +274,11 @@ impl Renderer for WinitGraphicsBackend {
fn import_shm(&mut self, buffer: &wl_buffer::WlBuffer) -> Result<Self::Texture, Self::Error> { fn import_shm(&mut self, buffer: &wl_buffer::WlBuffer) -> Result<Self::Texture, Self::Error> {
self.renderer.import_shm(buffer) self.renderer.import_shm(buffer)
} }
#[cfg(feature = "wayland_frontend")]
fn import_egl(&mut self, buffer: &EGLBuffer) -> Result<Self::Texture, Self::Error> {
self.renderer.import_egl(buffer)
}
fn begin(&mut self, width: u32, height: u32, transform: Transform) -> Result<(), <Self as Renderer>::Error> { fn begin(&mut self, width: u32, height: u32, transform: Transform) -> Result<(), <Self as Renderer>::Error> {
self.renderer.bind(self.egl.clone())?; self.renderer.bind(self.egl.clone())?;