1
0
Fork 0
forked from wry/wry

render: support shm screencopy from direct scanout

This commit is contained in:
Julian Orth 2024-02-28 15:59:20 +01:00
parent 9de63bddf3
commit 9fba5f9b45
13 changed files with 203 additions and 62 deletions

View file

@ -1,25 +1,53 @@
use {
crate::gfx_apis::gl::{
egl::{context::EglContext, image::EglImage},
gl::{
frame_buffer::GlFrameBuffer,
sys::{
GLeglImageOES, GLuint, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER,
GL_FRAMEBUFFER_COMPLETE, GL_RENDERBUFFER,
crate::{
format::Format,
gfx_apis::gl::{
egl::{context::EglContext, image::EglImage},
gl::{
frame_buffer::GlFrameBuffer,
sys::{
GLeglImageOES, GLuint, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER,
GL_FRAMEBUFFER_COMPLETE, GL_RENDERBUFFER,
},
},
RenderError,
},
RenderError,
},
std::rc::Rc,
};
pub struct GlRenderBuffer {
pub img: Rc<EglImage>,
pub _img: Option<Rc<EglImage>>,
pub ctx: Rc<EglContext>,
pub width: i32,
pub height: i32,
pub format: &'static Format,
rbo: GLuint,
}
impl GlRenderBuffer {
pub(in crate::gfx_apis::gl) unsafe fn new(
ctx: &Rc<EglContext>,
width: i32,
height: i32,
format: &'static Format,
) -> Result<Rc<GlRenderBuffer>, RenderError> {
let gles = &ctx.dpy.gles;
let mut rbo = 0;
(gles.glGenRenderbuffers)(1, &mut rbo);
(gles.glBindRenderbuffer)(GL_RENDERBUFFER, rbo);
(gles.glRenderbufferStorage)(GL_RENDERBUFFER, format.gl_internal_format, width, height);
(gles.glBindRenderbuffer)(GL_RENDERBUFFER, 0);
Ok(Rc::new(GlRenderBuffer {
_img: None,
ctx: ctx.clone(),
width,
height,
format,
rbo,
}))
}
pub(in crate::gfx_apis::gl) unsafe fn from_image(
img: &Rc<EglImage>,
ctx: &Rc<EglContext>,
@ -36,8 +64,11 @@ impl GlRenderBuffer {
.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, GLeglImageOES(img.img.0));
(gles.glBindRenderbuffer)(GL_RENDERBUFFER, 0);
Ok(Rc::new(GlRenderBuffer {
img: img.clone(),
_img: Some(img.clone()),
ctx: ctx.clone(),
width: img.dmabuf.width,
height: img.dmabuf.height,
format: img.dmabuf.format,
rbo,
}))
}
@ -62,8 +93,8 @@ impl GlRenderBuffer {
_tex: None,
ctx: self.ctx.clone(),
fbo,
width: self.img.dmabuf.width,
height: self.img.dmabuf.height,
width: self.width,
height: self.height,
};
if status != GL_FRAMEBUFFER_COMPLETE {
return Err(RenderError::CreateFramebuffer);

View file

@ -14,6 +14,7 @@ pub type GLuint = c::c_uint;
egl_transparent!(GLeglImageOES);
pub const GL_RGBA: GLint = 0x1908;
pub const GL_RGBA8: GLenum = 0x8058;
pub const GL_BGRA_EXT: GLint = 0x80E1;
pub const GL_CLAMP_TO_EDGE: GLint = 0x812F;
pub const GL_COLOR_ATTACHMENT0: GLenum = 0x8CE0;
@ -49,6 +50,7 @@ dynload! {
GLESV2: GlesV2 from "libGLESv2.so" {
glGetString: unsafe fn(name: GLenum) -> *const u8,
glGenRenderbuffers: unsafe fn(n: GLsizei, renderbuffers: *mut GLuint),
glRenderbufferStorage: unsafe fn(target: GLenum, format: GLenum, width: GLsizei, height: GLsizei),
glDeleteRenderbuffers: unsafe fn(n: GLsizei, renderbuffers: *const GLuint),
glBindRenderbuffer: unsafe fn(target: GLenum, renderbuffer: GLuint),
glGenFramebuffers: unsafe fn(n: GLsizei, framebuffers: *mut GLuint),

View file

@ -255,4 +255,17 @@ impl GfxContext for GlRenderContext {
fn gfx_api(&self) -> GfxApi {
GfxApi::OpenGl
}
fn create_fb(
self: Rc<Self>,
width: i32,
height: i32,
_stride: i32,
format: &'static Format,
) -> Result<Rc<dyn GfxFramebuffer>, GfxError> {
let fb = self.ctx.with_current(|| unsafe {
GlRenderBuffer::new(&self.ctx, width, height, format)?.create_framebuffer()
})?;
Ok(Rc::new(Framebuffer { ctx: self, gl: fb }))
}
}

View file

@ -120,6 +120,6 @@ impl GfxFramebuffer for Framebuffer {
}
fn format(&self) -> &'static Format {
self.gl.rb.img.dmabuf.format
self.gl.rb.format
}
}

View file

@ -18,7 +18,9 @@ use {
crate::{
async_engine::AsyncEngine,
format::Format,
gfx_api::{GfxContext, GfxError, GfxFormat, GfxImage, GfxTexture, ResetStatus},
gfx_api::{
GfxContext, GfxError, GfxFormat, GfxFramebuffer, GfxImage, GfxTexture, ResetStatus,
},
gfx_apis::vulkan::{
image::VulkanImageMemory, instance::VulkanInstance, renderer::VulkanRenderer,
},
@ -255,6 +257,19 @@ impl GfxContext for Context {
fn gfx_api(&self) -> GfxApi {
GfxApi::Vulkan
}
fn create_fb(
self: Rc<Self>,
width: i32,
height: i32,
stride: i32,
format: &'static Format,
) -> Result<Rc<dyn GfxFramebuffer>, GfxError> {
let fb = self
.0
.create_shm_texture(format, width, height, stride, &[], true)?;
Ok(fb)
}
}
impl Drop for Context {