opengl: implement AsyncShmGfxTexture
This commit is contained in:
parent
f213372b8e
commit
0a0caf3800
5 changed files with 111 additions and 8 deletions
|
|
@ -537,8 +537,8 @@ pub trait ShmGfxTexture: GfxTexture {
|
|||
fn into_texture(self: Rc<Self>) -> Rc<dyn GfxTexture>;
|
||||
}
|
||||
|
||||
#[expect(dead_code)]
|
||||
pub trait AsyncShmGfxTextureCallback {
|
||||
#[expect(dead_code)]
|
||||
fn completed(self: Rc<Self>, res: Result<(), GfxError>);
|
||||
}
|
||||
|
||||
|
|
@ -560,7 +560,6 @@ pub trait AsyncShmGfxTexture: GfxTexture {
|
|||
damage: Region,
|
||||
) -> Result<Option<PendingShmUpload>, GfxError>;
|
||||
|
||||
#[expect(dead_code)]
|
||||
fn sync_upload(self: Rc<Self>, shm: &[Cell<u8>], damage: Region) -> Result<(), GfxError>;
|
||||
|
||||
#[expect(dead_code)]
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ macro_rules! dynload {
|
|||
|
||||
use {
|
||||
crate::{
|
||||
clientmem::ClientMemError,
|
||||
gfx_api::{
|
||||
AcquireSync, CopyTexture, FillRect, GfxApiOpt, GfxContext, GfxError, GfxTexture,
|
||||
ReleaseSync, SyncFile,
|
||||
|
|
@ -196,6 +197,8 @@ enum RenderError {
|
|||
WaitSync,
|
||||
#[error("Buffer format {0} is not supported for shm buffers in OpenGL context")]
|
||||
UnsupportedShmFormat(&'static str),
|
||||
#[error("Could not access the client memory")]
|
||||
AccessFailed(#[source] ClientMemError),
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
|
|
@ -318,6 +321,10 @@ fn fill_boxes3(ctx: &GlRenderContext, boxes: &[[f32; 2]], color: &Color) {
|
|||
|
||||
fn render_texture(ctx: &GlRenderContext, tex: &CopyTexture) {
|
||||
let texture = tex.tex.as_gl();
|
||||
if !texture.gl.contents_valid.get() {
|
||||
log::error!("Ignoring texture with invalid contents");
|
||||
return;
|
||||
}
|
||||
assert!(rc_eq(&ctx.ctx, &texture.ctx.ctx));
|
||||
let gles = ctx.ctx.dpy.gles;
|
||||
unsafe {
|
||||
|
|
|
|||
|
|
@ -21,8 +21,10 @@ pub struct GlTexture {
|
|||
pub tex: GLuint,
|
||||
pub width: i32,
|
||||
pub height: i32,
|
||||
pub stride: i32,
|
||||
pub external_only: bool,
|
||||
pub format: &'static Format,
|
||||
pub contents_valid: Cell<bool>,
|
||||
}
|
||||
|
||||
pub fn image_target(external_only: bool) -> GLenum {
|
||||
|
|
@ -60,8 +62,10 @@ impl GlTexture {
|
|||
tex,
|
||||
width: img.dmabuf.width,
|
||||
height: img.dmabuf.height,
|
||||
stride: 0,
|
||||
external_only: img.external_only,
|
||||
format: img.dmabuf.format,
|
||||
contents_valid: Cell::new(true),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -108,8 +112,10 @@ impl GlTexture {
|
|||
tex,
|
||||
width,
|
||||
height,
|
||||
stride,
|
||||
external_only: false,
|
||||
format,
|
||||
contents_valid: Cell::new(true),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -282,13 +282,32 @@ impl GfxContext for GlRenderContext {
|
|||
|
||||
fn async_shmem_texture(
|
||||
self: Rc<Self>,
|
||||
_format: &'static Format,
|
||||
_width: i32,
|
||||
_height: i32,
|
||||
_stride: i32,
|
||||
format: &'static Format,
|
||||
width: i32,
|
||||
height: i32,
|
||||
stride: i32,
|
||||
_cpu_worker: &Rc<CpuWorker>,
|
||||
) -> Result<Rc<dyn AsyncShmGfxTexture>, GfxError> {
|
||||
todo!()
|
||||
let tex = self.ctx.with_current(|| unsafe {
|
||||
let mut tex = 0;
|
||||
(self.ctx.dpy.gles.glGenTextures)(1, &mut tex);
|
||||
Ok(tex)
|
||||
})?;
|
||||
Ok(Rc::new(Texture {
|
||||
gl: GlTexture {
|
||||
ctx: self.ctx.clone(),
|
||||
img: None,
|
||||
tex,
|
||||
width,
|
||||
height,
|
||||
stride,
|
||||
external_only: false,
|
||||
format,
|
||||
contents_valid: Cell::new(false),
|
||||
},
|
||||
ctx: self,
|
||||
format,
|
||||
}))
|
||||
}
|
||||
|
||||
fn allocator(&self) -> Rc<dyn Allocator> {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,21 @@
|
|||
use {
|
||||
crate::{
|
||||
clientmem::ClientMemOffset,
|
||||
format::Format,
|
||||
gfx_api::{GfxError, GfxTexture, ShmGfxTexture},
|
||||
gfx_api::{
|
||||
AsyncShmGfxTexture, AsyncShmGfxTextureCallback, GfxError, GfxTexture, PendingShmUpload,
|
||||
ShmGfxTexture,
|
||||
},
|
||||
gfx_apis::gl::{
|
||||
gl::texture::GlTexture,
|
||||
renderer::{context::GlRenderContext, framebuffer::Framebuffer},
|
||||
sys::{
|
||||
GLint, GL_CLAMP_TO_EDGE, GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_T,
|
||||
GL_UNPACK_ROW_LENGTH_EXT,
|
||||
},
|
||||
RenderError,
|
||||
},
|
||||
rect::Region,
|
||||
video::dmabuf::DmaBuf,
|
||||
},
|
||||
std::{
|
||||
|
|
@ -88,3 +97,66 @@ impl ShmGfxTexture for Texture {
|
|||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl AsyncShmGfxTexture for Texture {
|
||||
fn async_upload(
|
||||
self: Rc<Self>,
|
||||
_callback: Rc<dyn AsyncShmGfxTextureCallback>,
|
||||
mem: &Rc<ClientMemOffset>,
|
||||
damage: Region,
|
||||
) -> Result<Option<PendingShmUpload>, GfxError> {
|
||||
mem.access(|data| self.clone().sync_upload(data, damage))
|
||||
.map_err(RenderError::AccessFailed)??;
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn sync_upload(self: Rc<Self>, data: &[Cell<u8>], _damage: Region) -> Result<(), GfxError> {
|
||||
let shm_info = self.format.shm_info.as_ref().unwrap();
|
||||
if (self.gl.stride * self.gl.height) as usize > data.len() {
|
||||
return Err(RenderError::SmallImageBuffer.into());
|
||||
}
|
||||
let gles = self.ctx.ctx.dpy.gles;
|
||||
self.ctx.ctx.with_current(|| unsafe {
|
||||
(gles.glBindTexture)(GL_TEXTURE_2D, self.gl.tex);
|
||||
(gles.glTexParameteri)(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
(gles.glTexParameteri)(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
(gles.glPixelStorei)(
|
||||
GL_UNPACK_ROW_LENGTH_EXT,
|
||||
self.gl.stride / shm_info.bpp as GLint,
|
||||
);
|
||||
(gles.glTexImage2D)(
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
shm_info.gl_format,
|
||||
self.gl.width,
|
||||
self.gl.height,
|
||||
0,
|
||||
shm_info.gl_format as _,
|
||||
shm_info.gl_type as _,
|
||||
data.as_ptr() as _,
|
||||
);
|
||||
(gles.glPixelStorei)(GL_UNPACK_ROW_LENGTH_EXT, 0);
|
||||
(gles.glBindTexture)(GL_TEXTURE_2D, 0);
|
||||
Ok(())
|
||||
})?;
|
||||
self.gl.contents_valid.set(true);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn compatible_with(
|
||||
&self,
|
||||
format: &'static Format,
|
||||
width: i32,
|
||||
height: i32,
|
||||
stride: i32,
|
||||
) -> bool {
|
||||
format == self.gl.format
|
||||
&& width == self.gl.width
|
||||
&& height == self.gl.height
|
||||
&& stride == self.gl.stride
|
||||
}
|
||||
|
||||
fn into_texture(self: Rc<Self>) -> Rc<dyn GfxTexture> {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue