Skip to content

Commit

Permalink
wayland: Block dispatching if back buffer isn't released
Browse files Browse the repository at this point in the history
rust-windowing#41

If `set_buffer` can just be called in a loop without waiting for buffers
to be released or a frame callback, but can also be called in other
ways, I don't know if there's a better solution than blocking.

Should fix rust-windowing#48. The
animation example could probably be implemented better, but this is at
least better.

I guess it should be documented that `set_buffer` may block? I don't
know how this compares to other backends.
  • Loading branch information
ids1024 committed Dec 27, 2022
1 parent a800ca4 commit b44ae34
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 18 deletions.
6 changes: 6 additions & 0 deletions examples/animation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ fn main() {
Event::MainEventsCleared => {
window.request_redraw();
}
Event::WindowEvent {
event: WindowEvent::Resized(_),
window_id,
} if window_id == window.id() => {
window.request_redraw();
}
Event::WindowEvent {
event: WindowEvent::CloseRequested,
window_id,
Expand Down
32 changes: 14 additions & 18 deletions src/wayland/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::{error::unwrap, SoftBufferError};
use raw_window_handle::{WaylandDisplayHandle, WaylandWindowHandle};
use std::collections::VecDeque;
use wayland_client::{
backend::{Backend, ObjectId},
globals::{registry_queue_init, GlobalListContents},
Expand All @@ -18,8 +17,7 @@ pub struct WaylandImpl {
qh: QueueHandle<State>,
surface: wl_surface::WlSurface,
shm: wl_shm::WlShm,
// 0-2 buffers
buffers: VecDeque<WaylandBuffer>,
buffers: Option<(WaylandBuffer, WaylandBuffer)>,
}

impl WaylandImpl {
Expand Down Expand Up @@ -61,24 +59,22 @@ impl WaylandImpl {
})
}

// Allocate or reuse a buffer of the given size
fn buffer(&mut self, width: i32, height: i32) -> &WaylandBuffer {
let buffer = if let Some(mut buffer) = self.buffers.pop_front() {
if buffer.released() {
buffer.resize(width, height);
buffer
} else {
// If we have more than 1 unreleased buffer, destroy it
if self.buffers.is_empty() {
self.buffers.push_back(buffer);
}
WaylandBuffer::new(&self.shm, width, height, &self.qh)
self.buffers = Some(if let Some((front, mut back)) = self.buffers.take() {
// Swap buffers; block if back buffer not released yet
while !back.released() {
self.event_queue.blocking_dispatch(&mut State).unwrap();
}
back.resize(width, height);
(back, front)
} else {
WaylandBuffer::new(&self.shm, width, height, &self.qh)
};
self.buffers.push_back(buffer);
self.buffers.back().unwrap()
// Allocate front and back buffer
(
WaylandBuffer::new(&self.shm, width, height, &self.qh),
WaylandBuffer::new(&self.shm, width, height, &self.qh),
)
});
&self.buffers.as_ref().unwrap().0
}

pub(super) unsafe fn set_buffer(&mut self, buffer: &[u32], width: u16, height: u16) {
Expand Down

0 comments on commit b44ae34

Please sign in to comment.