xwayland: Throttle our cursor surface updates with a frame callback
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 <tiagomatos@gmail.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Signed-off-by: Keith Packard <keithp@keithp.com>
This commit is contained in:
parent
806470b9f6
commit
cbb7eb73b5
|
@ -82,6 +82,23 @@ xwl_unrealize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor)
|
||||||
return xwl_shm_destroy_pixmap(pixmap);
|
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
|
void
|
||||||
xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
|
xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
|
||||||
{
|
{
|
||||||
|
@ -98,6 +115,11 @@ xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (xwl_seat->cursor_frame_cb) {
|
||||||
|
xwl_seat->cursor_needs_update = TRUE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
cursor = xwl_seat->x_cursor;
|
cursor = xwl_seat->x_cursor;
|
||||||
pixmap = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key);
|
pixmap = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key);
|
||||||
stride = cursor->bits->width * 4;
|
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,
|
wl_surface_damage(xwl_seat->cursor, 0, 0,
|
||||||
xwl_seat->x_cursor->bits->width,
|
xwl_seat->x_cursor->bits->width,
|
||||||
xwl_seat->x_cursor->bits->height);
|
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);
|
wl_surface_commit(xwl_seat->cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -563,6 +563,8 @@ xwl_seat_destroy(struct xwl_seat *xwl_seat)
|
||||||
RemoveDevice(xwl_seat->keyboard, FALSE);
|
RemoveDevice(xwl_seat->keyboard, FALSE);
|
||||||
wl_seat_destroy(xwl_seat->seat);
|
wl_seat_destroy(xwl_seat->seat);
|
||||||
wl_surface_destroy(xwl_seat->cursor);
|
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);
|
wl_array_release(&xwl_seat->keys);
|
||||||
free(xwl_seat);
|
free(xwl_seat);
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,12 +115,14 @@ struct xwl_seat {
|
||||||
struct wl_pointer *wl_pointer;
|
struct wl_pointer *wl_pointer;
|
||||||
struct wl_keyboard *wl_keyboard;
|
struct wl_keyboard *wl_keyboard;
|
||||||
struct wl_array keys;
|
struct wl_array keys;
|
||||||
struct wl_surface *cursor;
|
|
||||||
struct xwl_window *focus_window;
|
struct xwl_window *focus_window;
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
uint32_t pointer_enter_serial;
|
uint32_t pointer_enter_serial;
|
||||||
struct xorg_list link;
|
struct xorg_list link;
|
||||||
CursorPtr x_cursor;
|
CursorPtr x_cursor;
|
||||||
|
struct wl_surface *cursor;
|
||||||
|
struct wl_callback *cursor_frame_cb;
|
||||||
|
Bool cursor_needs_update;
|
||||||
|
|
||||||
size_t keymap_size;
|
size_t keymap_size;
|
||||||
char *keymap;
|
char *keymap;
|
||||||
|
|
Loading…
Reference in New Issue