logo

bytemedia

Home to byte-level sounds, images, videos, … git clone https://hacktivis.me/git/bytemedia.git
commit: 9c1752c94d7d19b5ddab770e29d7163ff1b2a731
parent 6d72e874e75b7c9698e003b179e1e17b30cf6446
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Sat, 20 Feb 2021 17:32:35 +0100

C/wayland: mmap the buffer only once

Diffstat:

MC/wayland.c99++++++++++++++++++++++++++++++++++++-------------------------------------------
1 file changed, 45 insertions(+), 54 deletions(-)

diff --git a/C/wayland.c b/C/wayland.c @@ -11,6 +11,11 @@ #include <unistd.h> #include <wayland-client.h> +#define WIDTH 800 +#define HEIGHT 800 +#define STRIDE WIDTH * 4 +#define SIZE STRIDE *HEIGHT + /* Shared memory support code */ static void randname(char *buf) @@ -68,9 +73,11 @@ struct client_state /* Globals */ struct wl_display *wl_display; struct wl_registry *wl_registry; - struct wl_shm *wl_shm; struct wl_compositor *wl_compositor; struct xdg_wm_base *xdg_wm_base; + struct wl_buffer *wl_buffer; + int shm_fd; + uint32_t *shm_data; /* Objects */ struct wl_surface *wl_surface; struct xdg_surface *xdg_surface; @@ -81,67 +88,29 @@ struct client_state }; static void -wl_buffer_release(void *data, struct wl_buffer *wl_buffer) -{ - /* Sent by the compositor when it's no longer using this buffer */ - wl_buffer_destroy(wl_buffer); -} - -static const struct wl_buffer_listener wl_buffer_listener = { - .release = wl_buffer_release, -}; - -static struct wl_buffer * draw_frame(struct client_state *state) { - const int width = 800, height = 800; - int stride = width * 4; - int size = stride * height; - - int fd = allocate_shm_file(size); - if(fd == -1) - { - return NULL; - } - - uint32_t *data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if(data == MAP_FAILED) - { - close(fd); - return NULL; - } - - struct wl_shm_pool *pool = wl_shm_create_pool(state->wl_shm, fd, size); - struct wl_buffer *buffer = - wl_shm_pool_create_buffer(pool, 0, width, height, stride, WL_SHM_FORMAT_XRGB8888); - wl_shm_pool_destroy(pool); - close(fd); - int t = (int)state->offset; /* Let the fun begin! */ - for(int y = 0; y < height; ++y) + for(int y = 0; y < HEIGHT; ++y) { - for(int x = 0; x < width; ++x) + for(int x = 0; x < WIDTH; ++x) { //if (((x + offset) + (y + offset) / 8 * 8) % 16 < 8) - // data[y * width + x] = 0xFF666666; + // data[y * WIDTH + x] = 0xFF666666; //else - // data[y * width + x] = 0xFFEEEEEE; + // data[y * WIDTH + x] = 0xFFEEEEEE; // munching squares - data[y * width + x] = (x-t|y-t)+t<<t%16; + state->shm_data[y * WIDTH + x] = (x - t | y - t) + t << t % 16; //glichy munching squares - //data[y * width + x] = (x|y)*t; + //data[y * WIDTH + x] = (x|y)*t; // color enumeration - //data[y * width + x] = t*2|t*4<<8|t*8<<16; + //data[y * WIDTH + x] = t*2|t*4<<8|t*8<<16; } } - - munmap(data, size); - wl_buffer_add_listener(buffer, &wl_buffer_listener, NULL); - return buffer; } static void @@ -150,8 +119,8 @@ xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, uint32_t seri struct client_state *state = data; xdg_surface_ack_configure(xdg_surface, serial); - struct wl_buffer *buffer = draw_frame(state); - wl_surface_attach(state->wl_surface, buffer, 0, 0); + draw_frame(state); + wl_surface_attach(state->wl_surface, state->wl_buffer, 0, 0); wl_surface_commit(state->wl_surface); } @@ -178,18 +147,19 @@ wl_surface_frame_done(void *data, struct wl_callback *cb, uint32_t time) /* Request another frame */ struct client_state *state = data; - cb = wl_surface_frame(state->wl_surface); + cb = wl_surface_frame(state->wl_surface); wl_callback_add_listener(cb, &wl_surface_frame_listener, state); /* Update scroll amount at 24 pixels per second */ - if (state->last_frame != 0) { + if(state->last_frame != 0) + { int elapsed = time - state->last_frame; state->offset += elapsed / 1000.0 * 24; } /* Submit a frame for this event */ - struct wl_buffer *buffer = draw_frame(state); - wl_surface_attach(state->wl_surface, buffer, 0, 0); + draw_frame(state); + wl_surface_attach(state->wl_surface, state->wl_buffer, 0, 0); wl_surface_damage_buffer(state->wl_surface, 0, 0, INT32_MAX, INT32_MAX); wl_surface_commit(state->wl_surface); @@ -197,7 +167,7 @@ wl_surface_frame_done(void *data, struct wl_callback *cb, uint32_t time) } static const struct wl_callback_listener wl_surface_frame_listener = { - .done = wl_surface_frame_done, + .done = wl_surface_frame_done, }; static void @@ -211,7 +181,12 @@ registry_global(void *data, struct client_state *state = data; if(strcmp(interface, wl_shm_interface.name) == 0) { - state->wl_shm = wl_registry_bind(wl_registry, name, &wl_shm_interface, 1); + struct wl_shm *wl_shm = wl_registry_bind(wl_registry, name, &wl_shm_interface, 1); + struct wl_shm_pool *pool = wl_shm_create_pool(wl_shm, state->shm_fd, SIZE); + state->wl_buffer = + wl_shm_pool_create_buffer(pool, 0, WIDTH, HEIGHT, STRIDE, WL_SHM_FORMAT_XRGB8888); + wl_shm_pool_destroy(pool); + close(state->shm_fd); } else if(strcmp(interface, wl_compositor_interface.name) == 0) { @@ -241,6 +216,20 @@ main(int argc, char *argv[]) struct client_state state = {0}; state.wl_display = wl_display_connect(NULL); state.wl_registry = wl_display_get_registry(state.wl_display); + + state.shm_fd = allocate_shm_file(SIZE); + if(state.shm_fd == -1) + { + return 1; + } + + state.shm_data = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, state.shm_fd, 0); + if(state.shm_data == MAP_FAILED) + { + close(state.shm_fd); + return 1; + } + wl_registry_add_listener(state.wl_registry, &wl_registry_listener, &state); wl_display_roundtrip(state.wl_display); @@ -259,5 +248,7 @@ main(int argc, char *argv[]) /* This space deliberately left blank */ } + munmap(state.shm_data, SIZE); + return 0; }