Skip to content

Commit

Permalink
gfx: implement async shm downloads
Browse files Browse the repository at this point in the history
  • Loading branch information
mahkoh committed Oct 6, 2024
1 parent ce022d1 commit b463c17
Show file tree
Hide file tree
Showing 11 changed files with 199 additions and 203 deletions.
27 changes: 20 additions & 7 deletions src/gfx_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,11 +265,23 @@ pub trait GfxFramebuffer: Debug {
clear: Option<&Color>,
) -> Result<Option<SyncFile>, GfxError>;

fn copy_to_shm(self: Rc<Self>, shm: &[Cell<u8>]) -> Result<(), GfxError>;

fn format(&self) -> &'static Format;
}

pub trait GfxInternalFramebuffer: GfxFramebuffer {
fn into_fb(self: Rc<Self>) -> Rc<dyn GfxFramebuffer>;

fn staging_size(&self) -> usize;

fn download(
self: Rc<Self>,
staging: &Rc<dyn GfxStagingBuffer>,
callback: Rc<dyn AsyncShmGfxTextureCallback>,
mem: Rc<dyn ShmMemory>,
damage: Region,
) -> Result<Option<PendingShmTransfer>, GfxError>;
}

impl dyn GfxFramebuffer {
pub fn clear(
&self,
Expand Down Expand Up @@ -489,12 +501,12 @@ pub trait GfxStagingBuffer {
fn into_any(self: Rc<Self>) -> Rc<dyn Any>;
}

pub trait AsyncShmGfxTextureUploadCancellable {
pub trait AsyncShmGfxTextureTransferCancellable {
fn cancel(&self, id: u64);
}

pub struct PendingShmTransfer {
cancel: Rc<dyn AsyncShmGfxTextureUploadCancellable>,
cancel: Rc<dyn AsyncShmGfxTextureTransferCancellable>,
id: u64,
}

Expand Down Expand Up @@ -585,13 +597,14 @@ pub trait GfxContext: Debug {

fn gfx_api(&self) -> GfxApi;

fn create_fb(
fn create_internal_fb(
self: Rc<Self>,
cpu_worker: &Rc<CpuWorker>,
width: i32,
height: i32,
stride: i32,
format: &'static Format,
) -> Result<Rc<dyn GfxFramebuffer>, GfxError>;
) -> Result<Rc<dyn GfxInternalFramebuffer>, GfxError>;

fn sync_obj_ctx(&self) -> Option<&Rc<SyncObjCtx>>;

Expand Down Expand Up @@ -668,7 +681,7 @@ pub fn cross_intersect_formats(
}

impl PendingShmTransfer {
pub fn new(cancel: Rc<dyn AsyncShmGfxTextureUploadCancellable>, id: u64) -> Self {
pub fn new(cancel: Rc<dyn AsyncShmGfxTextureTransferCancellable>, id: u64) -> Self {
Self { cancel, id }
}
}
Expand Down
7 changes: 4 additions & 3 deletions src/gfx_apis/gl/renderer/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use {
format::{Format, XRGB8888},
gfx_api::{
AsyncShmGfxTexture, BufferResvUser, GfxContext, GfxError, GfxFormat, GfxFramebuffer,
GfxImage, GfxStagingBuffer, ResetStatus, ShmGfxTexture,
GfxImage, GfxInternalFramebuffer, GfxStagingBuffer, ResetStatus, ShmGfxTexture,
},
gfx_apis::gl::{
egl::{context::EglContext, display::EglDisplay, image::EglImage},
Expand Down Expand Up @@ -317,13 +317,14 @@ impl GfxContext for GlRenderContext {
GfxApi::OpenGl
}

fn create_fb(
fn create_internal_fb(
self: Rc<Self>,
_cpu_worker: &Rc<CpuWorker>,
width: i32,
height: i32,
_stride: i32,
format: &'static Format,
) -> Result<Rc<dyn GfxFramebuffer>, GfxError> {
) -> Result<Rc<dyn GfxInternalFramebuffer>, GfxError> {
let fb = self.ctx.with_current(|| unsafe {
GlRenderBuffer::new(&self.ctx, width, height, format)?.create_framebuffer()
})?;
Expand Down
35 changes: 30 additions & 5 deletions src/gfx_apis/gl/renderer/framebuffer.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
use {
crate::{
format::Format,
gfx_api::{AcquireSync, GfxApiOpt, GfxError, GfxFramebuffer, ReleaseSync, SyncFile},
gfx_api::{
AcquireSync, AsyncShmGfxTextureCallback, GfxApiOpt, GfxError, GfxFramebuffer,
GfxInternalFramebuffer, GfxStagingBuffer, PendingShmTransfer, ReleaseSync, ShmMemory,
SyncFile,
},
gfx_apis::gl::{
gl::{
frame_buffer::GlFrameBuffer,
Expand All @@ -13,6 +17,7 @@ use {
sys::{GL_ONE, GL_ONE_MINUS_SRC_ALPHA},
RenderError,
},
rect::Region,
theme::Color,
},
std::{
Expand Down Expand Up @@ -105,11 +110,31 @@ impl GfxFramebuffer for Framebuffer {
self.render(acquire_sync, ops, clear).map_err(|e| e.into())
}

fn copy_to_shm(self: Rc<Self>, shm: &[Cell<u8>]) -> Result<(), GfxError> {
(*self).copy_to_shm(shm).map_err(|e| e.into())
}

fn format(&self) -> &'static Format {
self.gl.rb.format
}
}

impl GfxInternalFramebuffer for Framebuffer {
fn into_fb(self: Rc<Self>) -> Rc<dyn GfxFramebuffer> {
self
}

fn staging_size(&self) -> usize {
0
}

fn download(
self: Rc<Self>,
_staging: &Rc<dyn GfxStagingBuffer>,
_callback: Rc<dyn AsyncShmGfxTextureCallback>,
mem: Rc<dyn ShmMemory>,
_damage: Region,
) -> Result<Option<PendingShmTransfer>, GfxError> {
let mut res = Ok(());
mem.access(&mut |mem| res = self.copy_to_shm(mem))
.map_err(RenderError::AccessFailed)?;
res?;
Ok(None)
}
}
19 changes: 13 additions & 6 deletions src/gfx_apis/vulkan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use {
cpu_worker::{jobs::read_write::ReadWriteJobError, CpuWorker},
format::Format,
gfx_api::{
AsyncShmGfxTexture, GfxContext, GfxError, GfxFormat, GfxFramebuffer, GfxImage,
AsyncShmGfxTexture, GfxContext, GfxError, GfxFormat, GfxImage, GfxInternalFramebuffer,
GfxStagingBuffer, ResetStatus, ShmGfxTexture,
},
gfx_apis::vulkan::{
Expand Down Expand Up @@ -315,16 +315,23 @@ impl GfxContext for Context {
GfxApi::Vulkan
}

fn create_fb(
fn create_internal_fb(
self: Rc<Self>,
cpu_worker: &Rc<CpuWorker>,
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, None)?;
) -> Result<Rc<dyn GfxInternalFramebuffer>, GfxError> {
let fb = self.0.create_shm_texture(
format,
width,
height,
stride,
&[],
true,
Some(cpu_worker),
)?;
Ok(fb)
}

Expand Down
49 changes: 39 additions & 10 deletions src/gfx_apis/vulkan/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use {
format::Format,
gfx_api::{
AcquireSync, AsyncShmGfxTexture, AsyncShmGfxTextureCallback,
AsyncShmGfxTextureUploadCancellable, GfxApiOpt, GfxError, GfxFramebuffer, GfxImage,
GfxStagingBuffer, GfxTexture, PendingShmTransfer, ReleaseSync, ShmGfxTexture,
ShmMemory, SyncFile,
AsyncShmGfxTextureTransferCancellable, GfxApiOpt, GfxError, GfxFramebuffer, GfxImage,
GfxInternalFramebuffer, GfxStagingBuffer, GfxTexture, PendingShmTransfer, ReleaseSync,
ShmGfxTexture, ShmMemory, SyncFile,
},
gfx_apis::vulkan::{
allocator::VulkanAllocation, device::VulkanDevice, format::VulkanModifierLimits,
Expand Down Expand Up @@ -510,17 +510,46 @@ impl GfxFramebuffer for VulkanImage {
.map_err(|e| e.into())
}

fn copy_to_shm(self: Rc<Self>, shm: &[Cell<u8>]) -> Result<(), GfxError> {
self.renderer
.read_all_pixels(&self, shm)
.map_err(|e| e.into())
}

fn format(&self) -> &'static Format {
self.format
}
}

impl GfxInternalFramebuffer for VulkanImage {
fn into_fb(self: Rc<Self>) -> Rc<dyn GfxFramebuffer> {
self
}

fn staging_size(&self) -> usize {
let VulkanImageMemory::Internal(shm) = &self.ty else {
unreachable!();
};
shm.size as _
}

fn download(
self: Rc<Self>,
staging: &Rc<dyn GfxStagingBuffer>,
callback: Rc<dyn AsyncShmGfxTextureCallback>,
mem: Rc<dyn ShmMemory>,
damage: Region,
) -> Result<Option<PendingShmTransfer>, GfxError> {
let VulkanImageMemory::Internal(shm) = &self.ty else {
unreachable!();
};
let staging = staging.clone().into_vk(&self.renderer.device.device);
let pending = shm.async_transfer(
&self,
staging,
&mem,
damage,
callback,
TransferType::Download,
)?;
Ok(pending)
}
}

impl GfxTexture for VulkanImage {
fn size(&self) -> (i32, i32) {
(self.width as _, self.height as _)
Expand Down Expand Up @@ -605,7 +634,7 @@ impl AsyncShmGfxTexture for VulkanImage {
}
}

impl AsyncShmGfxTextureUploadCancellable for VulkanImage {
impl AsyncShmGfxTextureTransferCancellable for VulkanImage {
fn cancel(&self, id: u64) {
let VulkanImageMemory::Internal(shm) = &self.ty else {
unreachable!();
Expand Down
Loading

0 comments on commit b463c17

Please sign in to comment.