From 2414e23dd6e144be521688915038b236c0aef6ff Mon Sep 17 00:00:00 2001 From: Andri Yngvason Date: Sun, 6 Dec 2020 21:04:56 +0000 Subject: [PATCH] Use double-buffering Without double-buffering there's a slight chance that the vnc code could start writing to the buffer before the compositor is done with it. --- src/main.c | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/main.c b/src/main.c index 00c1913..859692d 100644 --- a/src/main.c +++ b/src/main.c @@ -51,7 +51,8 @@ struct window { struct xdg_surface* xdg_surface; struct xdg_toplevel* xdg_toplevel; - struct buffer* buffer; + struct buffer* front_buffer; + struct buffer* back_buffer; }; static struct wl_display* wl_display; @@ -278,8 +279,8 @@ static int init_signal_handler(void) static void window_attach(struct window* w, int x, int y) { - w->buffer->is_attached = true; - wl_surface_attach(w->wl_surface, w->buffer->wl_buffer, x, y); + w->back_buffer->is_attached = true; + wl_surface_attach(w->wl_surface, w->back_buffer->wl_buffer, x, y); } static void window_commit(struct window* w) @@ -287,6 +288,14 @@ static void window_commit(struct window* w) wl_surface_commit(w->wl_surface); } +static void window_swap(struct window* w, struct vnc_client* client) +{ + struct buffer* tmp = w->front_buffer; + w->front_buffer = w->back_buffer; + w->back_buffer = tmp; + vnc_client_set_fb(client, window->back_buffer->pixels); +} + static void window_damage(struct window* w, int x, int y, int width, int height) { wl_surface_damage(w->wl_surface, x, y, width, height); @@ -364,8 +373,11 @@ wl_surface_failure: static void window_destroy(struct window* w) { - if (w->buffer) - buffer_destroy(w->buffer); + if (w->front_buffer) + buffer_destroy(w->front_buffer); + + if (w->back_buffer) + buffer_destroy(w->back_buffer); xdg_toplevel_destroy(w->xdg_toplevel); xdg_surface_destroy(w->xdg_surface); @@ -442,8 +454,12 @@ int on_vnc_client_alloc_fb(struct vnc_client* client) if (!window) return -1; - window->buffer = buffer_create(width, height, stride, wl_shm_format); - vnc_client_set_fb(client, window->buffer->pixels); + window->front_buffer = buffer_create(width, height, stride, + wl_shm_format); + window->back_buffer = buffer_create(width, height, stride, + wl_shm_format); + + vnc_client_set_fb(client, window->back_buffer->pixels); return 0; } @@ -452,8 +468,8 @@ void on_vnc_client_update_fb(struct vnc_client* client) if (!pixman_region_not_empty(&client->damage)) return; - if (window->buffer->is_attached) - fprintf(stderr, "Oops, buffer is still attached.\n"); + if (window->back_buffer->is_attached) + fprintf(stderr, "Oops, back-buffer is still attached.\n"); window_attach(window, 0, 0); @@ -471,6 +487,7 @@ void on_vnc_client_update_fb(struct vnc_client* client) } window_commit(window); + window_swap(window, client); } void on_vnc_client_event(void* obj)