mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2025-12-23 08:56:29 -05:00
output: always use hardware cursors if available
This changes the `wlr_output_impl.set_cursor` function to take a `wlr_texture` instead of a byte buffer. This simplifies the DRM and Wayland backends since they were creating textures from the byte buffer anyway. With this commit, performance should be improved when moving the cursor since outputs don't need to be re-rendered anymore.
This commit is contained in:
parent
509d38425c
commit
225d182765
6 changed files with 113 additions and 140 deletions
|
|
@ -698,6 +698,27 @@ static void output_cursor_update_visible(struct wlr_output_cursor *cursor) {
|
|||
cursor->visible = visible;
|
||||
}
|
||||
|
||||
static bool output_cursor_attempt_hardware(struct wlr_output_cursor *cursor) {
|
||||
struct wlr_texture *texture = cursor->texture;
|
||||
if (cursor->surface != NULL) {
|
||||
texture = cursor->surface->texture;
|
||||
}
|
||||
|
||||
struct wlr_output_cursor *hwcur = cursor->output->hardware_cursor;
|
||||
if (cursor->output->impl->set_cursor && (hwcur == NULL || hwcur == cursor)) {
|
||||
if (cursor->output->impl->move_cursor && hwcur != cursor) {
|
||||
cursor->output->impl->move_cursor(cursor->output,
|
||||
(int)cursor->x, (int)cursor->y);
|
||||
}
|
||||
if (cursor->output->impl->set_cursor(cursor->output, texture,
|
||||
cursor->hotspot_x, cursor->hotspot_y, true)) {
|
||||
cursor->output->hardware_cursor = cursor;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool wlr_output_cursor_set_image(struct wlr_output_cursor *cursor,
|
||||
const uint8_t *pixels, int32_t stride, uint32_t width, uint32_t height,
|
||||
int32_t hotspot_x, int32_t hotspot_y) {
|
||||
|
|
@ -713,33 +734,26 @@ bool wlr_output_cursor_set_image(struct wlr_output_cursor *cursor,
|
|||
cursor->hotspot_y = hotspot_y;
|
||||
output_cursor_update_visible(cursor);
|
||||
|
||||
struct wlr_output_cursor *hwcur = cursor->output->hardware_cursor;
|
||||
if (cursor->output->impl->set_cursor && (hwcur == NULL || hwcur == cursor)) {
|
||||
if (cursor->output->impl->move_cursor && hwcur != cursor) {
|
||||
cursor->output->impl->move_cursor(cursor->output,
|
||||
(int)cursor->x, (int)cursor->y);
|
||||
}
|
||||
int ok = cursor->output->impl->set_cursor(cursor->output, pixels,
|
||||
stride, width, height, hotspot_x, hotspot_y, true);
|
||||
if (ok) {
|
||||
cursor->output->hardware_cursor = cursor;
|
||||
return true;
|
||||
wlr_texture_destroy(cursor->texture);
|
||||
cursor->texture = NULL;
|
||||
|
||||
cursor->enabled = false;
|
||||
if (pixels != NULL) {
|
||||
cursor->texture = wlr_texture_from_pixels(renderer,
|
||||
WL_SHM_FORMAT_ARGB8888, stride, width, height, pixels);
|
||||
if (cursor->texture == NULL) {
|
||||
return false;
|
||||
}
|
||||
cursor->enabled = true;
|
||||
}
|
||||
|
||||
if (output_cursor_attempt_hardware(cursor)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
wlr_log(L_DEBUG, "Falling back to software cursor");
|
||||
output_cursor_damage_whole(cursor);
|
||||
|
||||
cursor->enabled = pixels != NULL;
|
||||
if (!cursor->enabled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
wlr_texture_destroy(cursor->texture);
|
||||
|
||||
cursor->texture = wlr_texture_from_pixels(renderer, WL_SHM_FORMAT_ARGB8888,
|
||||
stride, width, height, pixels);
|
||||
return cursor->texture != NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void output_cursor_commit(struct wlr_output_cursor *cursor) {
|
||||
|
|
@ -752,15 +766,15 @@ static void output_cursor_commit(struct wlr_output_cursor *cursor) {
|
|||
cursor->width = cursor->surface->current->width * cursor->output->scale;
|
||||
cursor->height = cursor->surface->current->height * cursor->output->scale;
|
||||
|
||||
if (cursor->output->hardware_cursor != cursor) {
|
||||
output_cursor_damage_whole(cursor);
|
||||
} else {
|
||||
// TODO: upload pixels
|
||||
|
||||
if (output_cursor_attempt_hardware(cursor)) {
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
wlr_surface_send_frame_done(cursor->surface, &now);
|
||||
return;
|
||||
}
|
||||
|
||||
// Fallback to software cursor
|
||||
output_cursor_damage_whole(cursor);
|
||||
}
|
||||
|
||||
static void output_cursor_handle_commit(struct wl_listener *listener,
|
||||
|
|
@ -800,7 +814,7 @@ void wlr_output_cursor_set_surface(struct wlr_output_cursor *cursor,
|
|||
|
||||
if (cursor->output->hardware_cursor == cursor &&
|
||||
cursor->output->impl->set_cursor) {
|
||||
cursor->output->impl->set_cursor(cursor->output, NULL, 0, 0, 0,
|
||||
cursor->output->impl->set_cursor(cursor->output, NULL,
|
||||
hotspot_x, hotspot_y, false);
|
||||
}
|
||||
return;
|
||||
|
|
@ -808,15 +822,6 @@ void wlr_output_cursor_set_surface(struct wlr_output_cursor *cursor,
|
|||
|
||||
output_cursor_reset(cursor);
|
||||
|
||||
// Disable hardware cursor for surfaces
|
||||
// TODO: support hardware cursors
|
||||
if (cursor->output->hardware_cursor == cursor &&
|
||||
cursor->output->impl->set_cursor) {
|
||||
cursor->output->impl->set_cursor(cursor->output, NULL, 0, 0, 0, 0, 0,
|
||||
true);
|
||||
cursor->output->hardware_cursor = NULL;
|
||||
}
|
||||
|
||||
cursor->surface = surface;
|
||||
cursor->hotspot_x = hotspot_x;
|
||||
cursor->hotspot_y = hotspot_y;
|
||||
|
|
@ -833,7 +838,10 @@ void wlr_output_cursor_set_surface(struct wlr_output_cursor *cursor,
|
|||
cursor->width = 0;
|
||||
cursor->height = 0;
|
||||
|
||||
// TODO: if hardware cursor, disable cursor
|
||||
if (cursor->output->hardware_cursor == cursor &&
|
||||
cursor->output->impl->set_cursor) {
|
||||
cursor->output->impl->set_cursor(cursor->output, NULL, 0, 0, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -896,8 +904,7 @@ void wlr_output_cursor_destroy(struct wlr_output_cursor *cursor) {
|
|||
if (cursor->output->hardware_cursor == cursor) {
|
||||
// If this cursor was the hardware cursor, disable it
|
||||
if (cursor->output->impl->set_cursor) {
|
||||
cursor->output->impl->set_cursor(cursor->output, NULL, 0, 0, 0, 0,
|
||||
0, true);
|
||||
cursor->output->impl->set_cursor(cursor->output, NULL, 0, 0, true);
|
||||
}
|
||||
cursor->output->hardware_cursor = NULL;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue