Skip to content

Commit 049fe41

Browse files
committed
fix(wayland): buffer release proper timings
1 parent a8c4c91 commit 049fe41

File tree

2 files changed

+33
-4
lines changed

2 files changed

+33
-4
lines changed

src/wayland/core/buffer.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ pub enum BufferBacking {
1515
Dmabuf(DmabufBacking),
1616
}
1717

18+
impl BufferBacking {
19+
// Returns true if the buffer can be released immediately after texture update
20+
pub fn can_release_after_update(&self) -> bool {
21+
matches!(self, BufferBacking::Shm(_))
22+
}
23+
}
24+
1825
#[derive(Debug, Dispatcher)]
1926
pub struct Buffer {
2027
pub id: ObjectId,
@@ -30,6 +37,10 @@ impl Buffer {
3037
}
3138
}
3239

40+
pub fn can_release_after_update(&self) -> bool {
41+
self.backing.can_release_after_update()
42+
}
43+
3344
pub fn size(&self) -> Vector2<usize> {
3445
match &self.backing {
3546
BufferBacking::Shm(backing) => backing.size(),

src/wayland/core/surface.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,12 +143,16 @@ impl Surface {
143143
.0
144144
.get_all_param_info()
145145
.set_texture("diffuse", new_tex);
146+
147+
// For SHM buffers, we can release immediately after copying to GPU
148+
if buffer.can_release_after_update() {
149+
let _ = self
150+
.message_sink
151+
.send(Message::ReleaseBuffer(buffer.clone()));
152+
}
146153
}
147-
let _ = self
148-
.message_sink
149-
.send(Message::ReleaseBuffer(buffer.clone()));
150-
self.apply_surface_materials();
151154

155+
self.apply_surface_materials();
152156
let _ = state_lock.current().clean_lock.set(());
153157
}
154158

@@ -268,6 +272,20 @@ impl WlSurface for Surface {
268272
{
269273
let mut lock = self.state.lock();
270274

275+
// If we're getting a new buffer and the current one is DMA-BUF, release it
276+
if let Some(new_buffer) = &lock.pending.buffer {
277+
if let Some(current_buffer) = &lock.current().buffer {
278+
// Don't release if it's the same buffer being reused
279+
if !Arc::ptr_eq(new_buffer, current_buffer)
280+
&& !current_buffer.can_release_after_update()
281+
{
282+
let _ = self
283+
.message_sink
284+
.send(Message::ReleaseBuffer(current_buffer.clone()));
285+
}
286+
}
287+
}
288+
271289
let dirty = lock.current().clean_lock.get().is_none()
272290
|| lock.pending.clean_lock.take().is_none();
273291
lock.apply();

0 commit comments

Comments
 (0)