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.
pull/3/head
Andri Yngvason 2020-12-06 21:04:56 +00:00
parent 977f34224c
commit 2414e23dd6
1 changed files with 26 additions and 9 deletions

View File

@ -51,7 +51,8 @@ struct window {
struct xdg_surface* xdg_surface; struct xdg_surface* xdg_surface;
struct xdg_toplevel* xdg_toplevel; struct xdg_toplevel* xdg_toplevel;
struct buffer* buffer; struct buffer* front_buffer;
struct buffer* back_buffer;
}; };
static struct wl_display* wl_display; 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) static void window_attach(struct window* w, int x, int y)
{ {
w->buffer->is_attached = true; w->back_buffer->is_attached = true;
wl_surface_attach(w->wl_surface, w->buffer->wl_buffer, x, y); wl_surface_attach(w->wl_surface, w->back_buffer->wl_buffer, x, y);
} }
static void window_commit(struct window* w) static void window_commit(struct window* w)
@ -287,6 +288,14 @@ static void window_commit(struct window* w)
wl_surface_commit(w->wl_surface); 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) 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); wl_surface_damage(w->wl_surface, x, y, width, height);
@ -364,8 +373,11 @@ wl_surface_failure:
static void window_destroy(struct window* w) static void window_destroy(struct window* w)
{ {
if (w->buffer) if (w->front_buffer)
buffer_destroy(w->buffer); buffer_destroy(w->front_buffer);
if (w->back_buffer)
buffer_destroy(w->back_buffer);
xdg_toplevel_destroy(w->xdg_toplevel); xdg_toplevel_destroy(w->xdg_toplevel);
xdg_surface_destroy(w->xdg_surface); xdg_surface_destroy(w->xdg_surface);
@ -442,8 +454,12 @@ int on_vnc_client_alloc_fb(struct vnc_client* client)
if (!window) if (!window)
return -1; return -1;
window->buffer = buffer_create(width, height, stride, wl_shm_format); window->front_buffer = buffer_create(width, height, stride,
vnc_client_set_fb(client, window->buffer->pixels); 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; return 0;
} }
@ -452,8 +468,8 @@ void on_vnc_client_update_fb(struct vnc_client* client)
if (!pixman_region_not_empty(&client->damage)) if (!pixman_region_not_empty(&client->damage))
return; return;
if (window->buffer->is_attached) if (window->back_buffer->is_attached)
fprintf(stderr, "Oops, buffer is still attached.\n"); fprintf(stderr, "Oops, back-buffer is still attached.\n");
window_attach(window, 0, 0); window_attach(window, 0, 0);
@ -471,6 +487,7 @@ void on_vnc_client_update_fb(struct vnc_client* client)
} }
window_commit(window); window_commit(window);
window_swap(window, client);
} }
void on_vnc_client_event(void* obj) void on_vnc_client_event(void* obj)