1
0
Fork 0
forked from wry/wry

gfx: add GfxStagingBuffer

This commit is contained in:
Julian Orth 2024-10-05 16:49:22 +02:00
parent 1462933ef4
commit 3619a51fbd
11 changed files with 215 additions and 43 deletions

View file

@ -175,6 +175,7 @@ impl WlBuffer {
WlBufferStorage::Shm { .. } => {
return match surface {
Some(s) => {
s.shm_staging.take();
s.shm_textures.back().tex.take();
s.shm_textures.front().tex.take().is_some()
}

View file

@ -23,8 +23,8 @@ use {
drm_feedback::DrmFeedback,
fixed::Fixed,
gfx_api::{
AsyncShmGfxTexture, BufferResv, BufferResvUser, GfxError, ReleaseSync, SampleRect,
SyncFile,
AsyncShmGfxTexture, BufferResv, BufferResvUser, GfxError, GfxStagingBuffer,
ReleaseSync, SampleRect, SyncFile,
},
ifs::{
wl_buffer::WlBuffer,
@ -276,6 +276,7 @@ pub struct WlSurface {
pub buffer_abs_pos: Cell<Rect>,
pub need_extents_update: Cell<bool>,
pub buffer: CloneCell<Option<Rc<SurfaceBuffer>>>,
pub shm_staging: CloneCell<Option<Rc<dyn GfxStagingBuffer>>>,
pub shm_textures: DoubleBuffered<SurfaceShmTexture>,
pub buf_x: NumCell<i32>,
pub buf_y: NumCell<i32>,
@ -593,6 +594,7 @@ impl WlSurface {
buffer_abs_pos: Cell::new(Default::default()),
need_extents_update: Default::default(),
buffer: Default::default(),
shm_staging: Default::default(),
shm_textures: DoubleBuffered::new(DamageQueue::new().map(|damage| SurfaceShmTexture {
tex: Default::default(),
damage,
@ -1327,6 +1329,7 @@ impl WlSurface {
}
pub fn reset_shm_textures(&self) {
self.shm_staging.take();
for tex in &*self.shm_textures {
tex.tex.take();
tex.damage.clear();

View file

@ -1,6 +1,6 @@
use {
crate::{
gfx_api::{AsyncShmGfxTextureCallback, GfxError, PendingShmUpload},
gfx_api::{AsyncShmGfxTextureCallback, GfxError, PendingShmUpload, STAGING_UPLOAD},
ifs::{
wl_buffer::WlBufferStorage,
wl_surface::{PendingState, WlSurface, WlSurfaceError},
@ -459,8 +459,28 @@ fn schedule_async_upload(
back_tex
}
};
let mut staging_opt = surface.shm_staging.get();
if let Some(staging) = &staging_opt {
if staging.size() != back_tex.staging_size() {
staging_opt = None;
}
}
let staging = match staging_opt {
Some(s) => s,
None => {
let s = surface
.client
.state
.render_ctx
.get()
.ok_or(WlSurfaceError::NoRenderContext)?
.create_staging_buffer(back_tex.staging_size(), STAGING_UPLOAD);
surface.shm_staging.set(Some(s.clone()));
s
}
};
back_tex
.async_upload(node_ref.clone(), mem.clone(), back.damage.get())
.async_upload(&staging, node_ref.clone(), mem.clone(), back.damage.get())
.map_err(WlSurfaceError::PrepareAsyncUpload)
}