1
0
Fork 0
forked from wry/wry

vulkan: implement async shm textures

This commit is contained in:
Julian Orth 2024-09-07 17:48:08 +02:00
parent b57d86c1bc
commit c712efcd35
10 changed files with 551 additions and 39 deletions

View file

@ -1,13 +1,17 @@
use {
crate::{
clientmem::ClientMemOffset,
format::Format,
gfx_api::{
GfxApiOpt, GfxError, GfxFramebuffer, GfxImage, GfxTexture, ShmGfxTexture, SyncFile,
AsyncShmGfxTexture, AsyncShmGfxTextureCallback, AsyncShmGfxTextureUploadCancellable,
GfxApiOpt, GfxError, GfxFramebuffer, GfxImage, GfxTexture, PendingShmUpload,
ShmGfxTexture, SyncFile,
},
gfx_apis::vulkan::{
allocator::VulkanAllocation, device::VulkanDevice, format::VulkanModifierLimits,
renderer::VulkanRenderer, shm_image::VulkanShmImage, VulkanError,
},
rect::Region,
theme::Color,
utils::{clonecell::CloneCell, on_drop::OnDrop},
video::dmabuf::{DmaBuf, PlaneVec},
@ -53,6 +57,7 @@ pub struct VulkanImage {
pub(super) render_view: Option<ImageView>,
pub(super) image: Image,
pub(super) is_undefined: Cell<bool>,
pub(super) contents_are_undefined: Cell<bool>,
pub(super) ty: VulkanImageMemory,
pub(super) render_ops: CloneCell<Vec<GfxApiOpt>>,
pub(super) bridge: Option<VulkanFramebufferBridge>,
@ -380,6 +385,7 @@ impl VulkanDmaBufImageTemplate {
}),
format: self.dmabuf.format,
is_undefined: Cell::new(true),
contents_are_undefined: Cell::new(false),
bridge,
}))
}
@ -538,3 +544,58 @@ impl ShmGfxTexture for VulkanImage {
self
}
}
impl AsyncShmGfxTexture for VulkanImage {
fn async_upload(
self: Rc<Self>,
callback: Rc<dyn AsyncShmGfxTextureCallback>,
mem: &Rc<ClientMemOffset>,
damage: Region,
) -> Result<Option<PendingShmUpload>, GfxError> {
let VulkanImageMemory::Internal(shm) = &self.ty else {
unreachable!();
};
let pending = shm.async_upload(&self, mem, damage, callback)?;
Ok(pending)
}
fn sync_upload(self: Rc<Self>, mem: &[Cell<u8>], damage: Region) -> Result<(), GfxError> {
let VulkanImageMemory::Internal(shm) = &self.ty else {
unreachable!();
};
if shm.async_data.as_ref().unwrap().busy.get() {
return Err(VulkanError::AsyncCopyBusy.into());
}
shm.upload(&self, mem, Some(damage.rects()))?;
Ok(())
}
fn compatible_with(
&self,
format: &'static Format,
width: i32,
height: i32,
stride: i32,
) -> bool {
self.format == format
&& self.width == width as u32
&& self.height == height as u32
&& self.stride == stride as u32
}
fn into_texture(self: Rc<Self>) -> Rc<dyn GfxTexture> {
self
}
}
impl AsyncShmGfxTextureUploadCancellable for VulkanImage {
fn cancel(&self, id: u64) {
let VulkanImageMemory::Internal(shm) = &self.ty else {
unreachable!();
};
let data = shm.async_data.as_ref().unwrap();
if data.callback_id.get() == id {
data.callback.take();
}
}
}