In some extreme cases with animated cursors at a high frame rate we could end up filling the wl_display outgoing buffer and end up with wl_display_flush() failing.
In any case, using the frame callback to throttle ourselves is the right thing to do. Signed-off-by: Rui Matos <tiagoma...@gmail.com> --- v2: ensure that we don't lose cursor updates requested while a frame callback is pending hw/xwayland/xwayland-cursor.c | 26 ++++++++++++++++++++++++++ hw/xwayland/xwayland-input.c | 2 ++ hw/xwayland/xwayland.h | 4 +++- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/hw/xwayland/xwayland-cursor.c b/hw/xwayland/xwayland-cursor.c index 5a9d1fe..c137e1e 100644 --- a/hw/xwayland/xwayland-cursor.c +++ b/hw/xwayland/xwayland-cursor.c @@ -82,6 +82,23 @@ xwl_unrealize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor) return xwl_shm_destroy_pixmap(pixmap); } +static void +frame_callback(void *data, + struct wl_callback *callback, + uint32_t time) +{ + struct xwl_seat *xwl_seat = data; + xwl_seat->cursor_frame_cb = NULL; + if (xwl_seat->cursor_needs_update) { + xwl_seat->cursor_needs_update = FALSE; + xwl_seat_set_cursor(xwl_seat); + } +} + +static const struct wl_callback_listener frame_listener = { + frame_callback +}; + void xwl_seat_set_cursor(struct xwl_seat *xwl_seat) { @@ -98,6 +115,11 @@ xwl_seat_set_cursor(struct xwl_seat *xwl_seat) return; } + if (xwl_seat->cursor_frame_cb) { + xwl_seat->cursor_needs_update = TRUE; + return; + } + cursor = xwl_seat->x_cursor; pixmap = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key); stride = cursor->bits->width * 4; @@ -117,6 +139,10 @@ xwl_seat_set_cursor(struct xwl_seat *xwl_seat) wl_surface_damage(xwl_seat->cursor, 0, 0, xwl_seat->x_cursor->bits->width, xwl_seat->x_cursor->bits->height); + + xwl_seat->cursor_frame_cb = wl_surface_frame(xwl_seat->cursor); + wl_callback_add_listener(xwl_seat->cursor_frame_cb, &frame_listener, xwl_seat); + wl_surface_commit(xwl_seat->cursor); } diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c index 5230d8c..a3142f4 100644 --- a/hw/xwayland/xwayland-input.c +++ b/hw/xwayland/xwayland-input.c @@ -586,6 +586,8 @@ xwl_seat_destroy(struct xwl_seat *xwl_seat) RemoveDevice(xwl_seat->keyboard, FALSE); wl_seat_destroy(xwl_seat->seat); wl_surface_destroy(xwl_seat->cursor); + if (xwl_seat->cursor_frame_cb) + wl_callback_destroy(xwl_seat->cursor_frame_cb); wl_array_release(&xwl_seat->keys); free(xwl_seat); } diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h index bfffa71..a31c040 100644 --- a/hw/xwayland/xwayland.h +++ b/hw/xwayland/xwayland.h @@ -115,12 +115,14 @@ struct xwl_seat { struct wl_pointer *wl_pointer; struct wl_keyboard *wl_keyboard; struct wl_array keys; - struct wl_surface *cursor; struct xwl_window *focus_window; uint32_t id; uint32_t pointer_enter_serial; struct xorg_list link; CursorPtr x_cursor; + struct wl_surface *cursor; + struct wl_callback *cursor_frame_cb; + Bool cursor_needs_update; wl_fixed_t horizontal_scroll; wl_fixed_t vertical_scroll; -- 2.4.0 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel