Questions about an efficient SHM game loop
Philip Bizimis
bizimisphilip at gmail.com
Wed May 8 11:49:51 UTC 2024
I am currently working on a small Wayland Snake game to
learn about Wayland and game development. I am using SHM
double buffers for rendering.
My main game loop has two parts that run at different speeds so
that I can have a constant game speed independent of variable
FPS (based on https://dewitters.com/dewitters-gameloop):
```
game_loop() {
while(1) {
// wl_display_dispatch
while(at least X times a sec) {
update();
}
render();
}
```
In my case, there could be several game updates before a frame
is rendered. But there could also be hundreds of frames between
game updates if the hardware is good enough.
Currently, the game works fine if I use wl_display_dispatch.
However, I feel like for optimal performance a blocking call does not
make sense. Also, I would think that I would only want to process
events that I need for the updating in the update loop, and not only
once in the main loop. So my plan is to have something like:
```
game_loop() {
while(1) {
while(at least X times a sec) {
// receive all input changes
update(); // update game state based on
// LEFT RIGHT UP DOWN
}
// render where the snake is currently
render();
}
```
My render function at the moment looks like:
```
void render(...) {
struct buffer *free_buffer = find_free_buffer(...);
// set to available with a buffer_release callback
if (free_buffer != NULL) {
fill_frame(free_buffer->shm_data, state);
render_frame(state->wl_surface, free_buffer);
}
}
```
My update function does not interact with Wayland except using the
last pressed key as the direction of the snake.
I have attempted the following approaches without success:
```
game_loop() {
while(1) {
wl_display_dispatch_pending(d);
while(at least X times a sec) {
update();
}
render();
wl_display_flush(d);
}
```
```
struct pollfd pollfds[] = {
{
.fd = wl_display_get_fd(state->wl_display),
.events = POLLIN,
},
};
while (1) {
if (pollfds[0].revents & POLLIN) { // never true
wl_display_dispatch();
...
```
Both compiled but did not produce any client window.
I would greatly appreciate your help. I have spent a lot of hours
on this and seem to have hit a wall. In case you would like to take
a look at the whole code: github.com/pbizimis/snake
Thank you so much and have a great day,
Philip
More information about the wayland-devel
mailing list