wayland: implement a proper repaint cycle

This commit is contained in:
Ilia Bozhinov 2019-03-24 20:18:59 +01:00
parent 33e540a2b0
commit ab82afab7f
3 changed files with 27 additions and 7 deletions

View File

@ -25,6 +25,13 @@ render(const struct bm_menu *menu)
return; return;
} }
struct window *window;
wl_list_for_each(window, &wayland->windows, link) {
if (window->render_pending)
bm_wl_window_render(window, wayland->display, menu);
}
wl_display_flush(wayland->display);
struct epoll_event ep[16]; struct epoll_event ep[16];
uint32_t num = epoll_wait(efd, ep, 16, -1); uint32_t num = epoll_wait(efd, ep, 16, -1);
for (uint32_t i = 0; i < num; ++i) { for (uint32_t i = 0; i < num; ++i) {
@ -38,10 +45,10 @@ render(const struct bm_menu *menu)
} }
if (wayland->input.code != wayland->input.last_code) { if (wayland->input.code != wayland->input.last_code) {
struct window *window; wl_list_for_each(window, &wayland->windows, link) {
wl_list_for_each(window, &wayland->windows, link) { bm_wl_window_schedule_render(window);
bm_wl_window_render(window, wayland->display, menu);
} }
wayland->input.last_code = wayland->input.code; wayland->input.last_code = wayland->input.code;
} }
} }
@ -263,6 +270,7 @@ constructor(struct bm_menu *menu)
goto fail; goto fail;
window->notify.render = bm_cairo_paint; window->notify.render = bm_cairo_paint;
window->max_height = output->height; window->max_height = output->height;
window->render_pending = true;
wl_list_insert(&wayland->windows, &window->link); wl_list_insert(&wayland->windows, &window->link);
} }

View File

@ -84,6 +84,7 @@ struct window {
uint32_t displayed; uint32_t displayed;
struct wl_list link; struct wl_list link;
bool bottom; bool bottom;
bool render_pending;
struct { struct {
void (*render)(struct cairo *cairo, uint32_t width, uint32_t height, uint32_t max_height, const struct bm_menu *menu, struct cairo_paint_result *result); void (*render)(struct cairo *cairo, uint32_t width, uint32_t height, uint32_t max_height, const struct bm_menu *menu, struct cairo_paint_result *result);
@ -117,6 +118,7 @@ struct wayland {
void bm_wl_repeat(struct wayland *wayland); void bm_wl_repeat(struct wayland *wayland);
bool bm_wl_registry_register(struct wayland *wayland); bool bm_wl_registry_register(struct wayland *wayland);
void bm_wl_registry_destroy(struct wayland *wayland); void bm_wl_registry_destroy(struct wayland *wayland);
void bm_wl_window_schedule_render(struct window *window);
void bm_wl_window_render(struct window *window, struct wl_display *display, const struct bm_menu *menu); void bm_wl_window_render(struct window *window, struct wl_display *display, const struct bm_menu *menu);
void bm_wl_window_set_bottom(struct window *window, struct wl_display *display, bool bottom); void bm_wl_window_set_bottom(struct window *window, struct wl_display *display, bool bottom);
void bm_wl_window_grab_keyboard(struct window *window, struct wl_display *display, bool grab); void bm_wl_window_grab_keyboard(struct window *window, struct wl_display *display, bool grab);

View File

@ -197,17 +197,29 @@ frame_callback(void *data, struct wl_callback *callback, uint32_t time)
struct window *window = data; struct window *window = data;
wl_callback_destroy(callback); wl_callback_destroy(callback);
window->frame_cb = NULL; window->frame_cb = NULL;
window->render_pending = true;
} }
static const struct wl_callback_listener listener = { static const struct wl_callback_listener listener = {
frame_callback frame_callback
}; };
void
bm_wl_window_schedule_render(struct window *window)
{
assert(window);
if (window->frame_cb)
return;
window->frame_cb = wl_surface_frame(window->surface);
wl_callback_add_listener(window->frame_cb, &listener, window);
wl_surface_commit(window->surface);
}
void void
bm_wl_window_render(struct window *window, struct wl_display *display, const struct bm_menu *menu) bm_wl_window_render(struct window *window, struct wl_display *display, const struct bm_menu *menu)
{ {
assert(window && menu); assert(window && menu);
struct buffer *buffer; struct buffer *buffer;
for (int tries = 0; tries < 2; ++tries) { for (int tries = 0; tries < 2; ++tries) {
if (!(buffer = next_buffer(window))) { if (!(buffer = next_buffer(window))) {
@ -232,13 +244,11 @@ bm_wl_window_render(struct window *window, struct wl_display *display, const str
destroy_buffer(buffer); destroy_buffer(buffer);
} }
window->frame_cb = wl_surface_frame(window->surface);
wl_callback_add_listener(window->frame_cb, &listener, window);
wl_surface_damage(window->surface, 0, 0, buffer->width, buffer->height); wl_surface_damage(window->surface, 0, 0, buffer->width, buffer->height);
wl_surface_attach(window->surface, buffer->buffer, 0, 0); wl_surface_attach(window->surface, buffer->buffer, 0, 0);
wl_surface_commit(window->surface); wl_surface_commit(window->surface);
buffer->busy = true; buffer->busy = true;
window->render_pending = false;
} }
void void