diff --git a/wayland/buffer.c b/wayland/buffer.c index 343be30..92c7448 100644 --- a/wayland/buffer.c +++ b/wayland/buffer.c @@ -14,16 +14,11 @@ #include "wayland.h" -static int commit_buffer_resize(struct ufkbd_wl_buffer *ctx); - static void on_buffer_release(void *data, struct wl_buffer *buf) { struct ufkbd_wl_buffer *ctx = data; - if (ctx->resize) - commit_buffer_resize(ctx); - - ctx->avail = true; + ufkbd_wl_buffer_release(ctx); } static const struct wl_buffer_listener buf_listener = { @@ -140,6 +135,14 @@ int ufkbd_wl_buffer_resize(struct ufkbd_wl_buffer *ctx, return 0; } +void ufkbd_wl_buffer_release(struct ufkbd_wl_buffer *ctx) +{ + if (ctx->resize) + commit_buffer_resize(ctx); + + ctx->avail = true; +} + int ufkbd_wl_buffer_init(struct ufkbd_wl_buffer *ctx, struct ufkbd_input_wayland *ufkbd_wl, unsigned int id) diff --git a/wayland/driver.c b/wayland/driver.c index 9c3a4cb..887f47e 100644 --- a/wayland/driver.c +++ b/wayland/driver.c @@ -150,8 +150,6 @@ static int ufkbd_wayland_draw_begin(void *data, size_t *stride, void **ptr) return ret; } - wl_surface_attach(ctx->surface->wl, buf, 0, 0); - // NOPUSH *stride = (size_t) ctx->surface->bufs[0].width * 4; @@ -170,6 +168,7 @@ static void ufkbd_wayland_draw_end(void *data) struct ufkbd_input_wayland *ctx = data; wl_surface_commit(ctx->surface->wl); + ufkbd_wl_surface_release_unused(ctx->surface); } static void *ufkbd_wayland_init(struct ufkbd_ctx *ufkbd) diff --git a/wayland/surface.c b/wayland/surface.c index d705303..22257ac 100644 --- a/wayland/surface.c +++ b/wayland/surface.c @@ -163,16 +163,22 @@ static void on_global_viewporter(void *data, int ufkbd_wl_surface_consume_buffer(struct ufkbd_wl_surface *ctx, struct wl_buffer **buf, void **ptr) { - int ret; + int ret, i; if (buf == NULL || ptr == NULL) return -EINVAL; - ret = ufkbd_wl_buffer_consume(&ctx->bufs[0], buf, ptr); - if (ret != -EBUSY) - return ret; + for (i = 0; i < 2; i++) { + ret = ufkbd_wl_buffer_consume(&ctx->bufs[i], buf, ptr); + if (!ret) { + wl_surface_attach(ctx->wl, *buf, 0, 0); + ctx->used_buf = i; + break; + } - ret = ufkbd_wl_buffer_consume(&ctx->bufs[1], buf, ptr); + if (ret != -EBUSY) + break; + } return ret; } @@ -195,6 +201,16 @@ static int ufkbd_wl_surface_resize_buffers(struct ufkbd_wl_surface *ctx, height * ctx->scale); } +void ufkbd_wl_surface_release_unused(struct ufkbd_wl_surface *ctx) +{ + int i; + + for (i = 0; i < 2; i++) { + if (i != ctx->used_buf) + ufkbd_wl_buffer_release(&ctx->bufs[i]); + } +} + int ufkbd_wl_surface_init(struct ufkbd_input_wayland *ufkbd_wl, struct ufkbd_wl_surface **out) { @@ -207,6 +223,7 @@ int ufkbd_wl_surface_init(struct ufkbd_input_wayland *ufkbd_wl, ctx->ufkbd_wl = ufkbd_wl; ctx->scale = 1; + ctx->used_buf = -1; ret = ufkbd_wl_buffer_init(&ctx->bufs[0], ufkbd_wl, 0); if (ret) diff --git a/wayland/wayland.h b/wayland/wayland.h index c8250c7..a409fc4 100644 --- a/wayland/wayland.h +++ b/wayland/wayland.h @@ -105,6 +105,7 @@ struct ufkbd_wl_surface { unsigned int scale; size_t stride; + int used_buf; struct ufkbd_wl_buffer bufs[2]; }; @@ -126,6 +127,7 @@ int ufkbd_wl_buffer_consume(struct ufkbd_wl_buffer *ctx, struct wl_buffer **buf, void **ptr); int ufkbd_wl_buffer_resize(struct ufkbd_wl_buffer *ctx, uint32_t width, uint32_t height); +void ufkbd_wl_buffer_release(struct ufkbd_wl_buffer *ctx); int ufkbd_wl_buffer_init(struct ufkbd_wl_buffer *ctx, struct ufkbd_input_wayland *ufkbd_wl, unsigned int id); @@ -133,6 +135,7 @@ void ufkbd_wl_buffer_uninit(struct ufkbd_wl_buffer *ctx); int ufkbd_wl_surface_consume_buffer(struct ufkbd_wl_surface *ctx, struct wl_buffer **buf, void **ptr); +void ufkbd_wl_surface_release_unused(struct ufkbd_wl_surface *ctx); int ufkbd_wl_surface_init(struct ufkbd_input_wayland *ufkbd_wl, struct ufkbd_wl_surface **out); void ufkbd_wl_surface_uninit(struct ufkbd_wl_surface *ctx);