wayland: release unused buffers after buffer swap
When the surface attaches to a buffer, all other buffers are available. Export the function used to release a buffer, track the buffer used by the surface, and release unused buffers when a new buffer is attached.
This commit is contained in:
parent
1c606d0274
commit
d43f61ec76
4 changed files with 35 additions and 13 deletions
|
|
@ -14,16 +14,11 @@
|
||||||
|
|
||||||
#include "wayland.h"
|
#include "wayland.h"
|
||||||
|
|
||||||
static int commit_buffer_resize(struct ufkbd_wl_buffer *ctx);
|
|
||||||
|
|
||||||
static void on_buffer_release(void *data, struct wl_buffer *buf)
|
static void on_buffer_release(void *data, struct wl_buffer *buf)
|
||||||
{
|
{
|
||||||
struct ufkbd_wl_buffer *ctx = data;
|
struct ufkbd_wl_buffer *ctx = data;
|
||||||
|
|
||||||
if (ctx->resize)
|
ufkbd_wl_buffer_release(ctx);
|
||||||
commit_buffer_resize(ctx);
|
|
||||||
|
|
||||||
ctx->avail = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wl_buffer_listener buf_listener = {
|
static const struct wl_buffer_listener buf_listener = {
|
||||||
|
|
@ -140,6 +135,14 @@ int ufkbd_wl_buffer_resize(struct ufkbd_wl_buffer *ctx,
|
||||||
return 0;
|
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,
|
int ufkbd_wl_buffer_init(struct ufkbd_wl_buffer *ctx,
|
||||||
struct ufkbd_input_wayland *ufkbd_wl,
|
struct ufkbd_input_wayland *ufkbd_wl,
|
||||||
unsigned int id)
|
unsigned int id)
|
||||||
|
|
|
||||||
|
|
@ -150,8 +150,6 @@ static int ufkbd_wayland_draw_begin(void *data, size_t *stride, void **ptr)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_surface_attach(ctx->surface->wl, buf, 0, 0);
|
|
||||||
|
|
||||||
// NOPUSH
|
// NOPUSH
|
||||||
*stride = (size_t) ctx->surface->bufs[0].width * 4;
|
*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;
|
struct ufkbd_input_wayland *ctx = data;
|
||||||
|
|
||||||
wl_surface_commit(ctx->surface->wl);
|
wl_surface_commit(ctx->surface->wl);
|
||||||
|
ufkbd_wl_surface_release_unused(ctx->surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *ufkbd_wayland_init(struct ufkbd_ctx *ufkbd)
|
static void *ufkbd_wayland_init(struct ufkbd_ctx *ufkbd)
|
||||||
|
|
|
||||||
|
|
@ -163,16 +163,22 @@ static void on_global_viewporter(void *data,
|
||||||
int ufkbd_wl_surface_consume_buffer(struct ufkbd_wl_surface *ctx,
|
int ufkbd_wl_surface_consume_buffer(struct ufkbd_wl_surface *ctx,
|
||||||
struct wl_buffer **buf, void **ptr)
|
struct wl_buffer **buf, void **ptr)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret, i;
|
||||||
|
|
||||||
if (buf == NULL || ptr == NULL)
|
if (buf == NULL || ptr == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
ret = ufkbd_wl_buffer_consume(&ctx->bufs[0], buf, ptr);
|
for (i = 0; i < 2; i++) {
|
||||||
if (ret != -EBUSY)
|
ret = ufkbd_wl_buffer_consume(&ctx->bufs[i], buf, ptr);
|
||||||
return ret;
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -195,6 +201,16 @@ static int ufkbd_wl_surface_resize_buffers(struct ufkbd_wl_surface *ctx,
|
||||||
height * ctx->scale);
|
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,
|
int ufkbd_wl_surface_init(struct ufkbd_input_wayland *ufkbd_wl,
|
||||||
struct ufkbd_wl_surface **out)
|
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->ufkbd_wl = ufkbd_wl;
|
||||||
ctx->scale = 1;
|
ctx->scale = 1;
|
||||||
|
ctx->used_buf = -1;
|
||||||
|
|
||||||
ret = ufkbd_wl_buffer_init(&ctx->bufs[0], ufkbd_wl, 0);
|
ret = ufkbd_wl_buffer_init(&ctx->bufs[0], ufkbd_wl, 0);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,7 @@ struct ufkbd_wl_surface {
|
||||||
unsigned int scale;
|
unsigned int scale;
|
||||||
size_t stride;
|
size_t stride;
|
||||||
|
|
||||||
|
int used_buf;
|
||||||
struct ufkbd_wl_buffer bufs[2];
|
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);
|
struct wl_buffer **buf, void **ptr);
|
||||||
int ufkbd_wl_buffer_resize(struct ufkbd_wl_buffer *ctx,
|
int ufkbd_wl_buffer_resize(struct ufkbd_wl_buffer *ctx,
|
||||||
uint32_t width, uint32_t height);
|
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,
|
int ufkbd_wl_buffer_init(struct ufkbd_wl_buffer *ctx,
|
||||||
struct ufkbd_input_wayland *ufkbd_wl,
|
struct ufkbd_input_wayland *ufkbd_wl,
|
||||||
unsigned int id);
|
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,
|
int ufkbd_wl_surface_consume_buffer(struct ufkbd_wl_surface *ctx,
|
||||||
struct wl_buffer **buf, void **ptr);
|
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,
|
int ufkbd_wl_surface_init(struct ufkbd_input_wayland *ufkbd_wl,
|
||||||
struct ufkbd_wl_surface **out);
|
struct ufkbd_wl_surface **out);
|
||||||
void ufkbd_wl_surface_uninit(struct ufkbd_wl_surface *ctx);
|
void ufkbd_wl_surface_uninit(struct ufkbd_wl_surface *ctx);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue