From 738bbf01ee1b3f12116d6de956cd70c30f3637dd Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 10 May 2024 18:32:04 +0200 Subject: [PATCH] cursor: add support for linux-drm-syncobj-v1 --- include/types/wlr_output.h | 3 ++- include/wlr/types/wlr_output.h | 2 ++ types/output/cursor.c | 21 ++++++++++++++++++--- types/wlr_cursor.c | 20 ++++++++++++++++++-- 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/include/types/wlr_output.h b/include/types/wlr_output.h index 09be3551..bd095d8f 100644 --- a/include/types/wlr_output.h +++ b/include/types/wlr_output.h @@ -18,7 +18,8 @@ bool output_ensure_buffer(struct wlr_output *output, bool output_cursor_set_texture(struct wlr_output_cursor *cursor, struct wlr_texture *texture, bool own_texture, const struct wlr_fbox *src_box, int dst_width, int dst_height, enum wl_output_transform transform, - int32_t hotspot_x, int32_t hotspot_y); + int32_t hotspot_x, int32_t hotspot_y, struct wlr_drm_syncobj_timeline *wait_timeline, + uint64_t wait_point); void output_defer_present(struct wlr_output *output, struct wlr_output_event_present event); diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index 1dae4b7d..f32e15ef 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -45,6 +45,8 @@ struct wlr_output_cursor { int32_t hotspot_x, hotspot_y; struct wlr_texture *texture; bool own_texture; + struct wlr_drm_syncobj_timeline *wait_timeline; + uint64_t wait_point; struct wl_listener renderer_destroy; struct wl_list link; }; diff --git a/types/output/cursor.c b/types/output/cursor.c index 2bf78528..95793a39 100644 --- a/types/output/cursor.c +++ b/types/output/cursor.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -271,6 +272,8 @@ static struct wlr_buffer *render_cursor_buffer(struct wlr_output_cursor *cursor) .src_box = cursor->src_box, .dst_box = dst_box, .transform = transform, + .wait_timeline = cursor->wait_timeline, + .wait_point = cursor->wait_point, }); if (!wlr_render_pass_submit(pass)) { @@ -355,20 +358,22 @@ bool wlr_output_cursor_set_buffer(struct wlr_output_cursor *cursor, hotspot_y /= cursor->output->scale; return output_cursor_set_texture(cursor, texture, true, &src_box, - dst_width, dst_height, WL_OUTPUT_TRANSFORM_NORMAL, hotspot_x, hotspot_y); + dst_width, dst_height, WL_OUTPUT_TRANSFORM_NORMAL, hotspot_x, hotspot_y, + NULL, 0); } static void output_cursor_handle_renderer_destroy(struct wl_listener *listener, void *data) { struct wlr_output_cursor *cursor = wl_container_of(listener, cursor, renderer_destroy); output_cursor_set_texture(cursor, NULL, false, NULL, 0, 0, - WL_OUTPUT_TRANSFORM_NORMAL, 0, 0); + WL_OUTPUT_TRANSFORM_NORMAL, 0, 0, NULL, 0); } bool output_cursor_set_texture(struct wlr_output_cursor *cursor, struct wlr_texture *texture, bool own_texture, const struct wlr_fbox *src_box, int dst_width, int dst_height, enum wl_output_transform transform, - int32_t hotspot_x, int32_t hotspot_y) { + int32_t hotspot_x, int32_t hotspot_y, + struct wlr_drm_syncobj_timeline *wait_timeline, uint64_t wait_point) { struct wlr_output *output = cursor->output; output_cursor_reset(cursor); @@ -395,6 +400,15 @@ bool output_cursor_set_texture(struct wlr_output_cursor *cursor, cursor->texture = texture; cursor->own_texture = own_texture; + wlr_drm_syncobj_timeline_unref(cursor->wait_timeline); + if (wait_timeline != NULL) { + cursor->wait_timeline = wlr_drm_syncobj_timeline_ref(wait_timeline); + cursor->wait_point = wait_point; + } else { + cursor->wait_timeline = NULL; + cursor->wait_point = 0; + } + wl_list_remove(&cursor->renderer_destroy.link); if (texture != NULL) { cursor->renderer_destroy.notify = output_cursor_handle_renderer_destroy; @@ -471,6 +485,7 @@ void wlr_output_cursor_destroy(struct wlr_output_cursor *cursor) { if (cursor->own_texture) { wlr_texture_destroy(cursor->texture); } + wlr_drm_syncobj_timeline_unref(cursor->wait_timeline); wl_list_remove(&cursor->link); free(cursor); } diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c index 77ab2fb7..a2489fbd 100644 --- a/types/wlr_cursor.c +++ b/types/wlr_cursor.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -534,7 +535,7 @@ static void cursor_output_cursor_update(struct wlr_cursor_output_cursor *output_ output_cursor_set_texture(output_cursor->output_cursor, texture, true, &src_box, dst_width, dst_height, WL_OUTPUT_TRANSFORM_NORMAL, - hotspot_x, hotspot_y); + hotspot_x, hotspot_y, NULL, 0); } else if (cur->state->surface != NULL) { struct wlr_surface *surface = cur->state->surface; @@ -547,9 +548,24 @@ static void cursor_output_cursor_update(struct wlr_cursor_output_cursor *output_ int dst_width = surface->current.width; int dst_height = surface->current.height; + struct wlr_linux_drm_syncobj_surface_v1_state *syncobj_surface_state = + wlr_linux_drm_syncobj_v1_get_surface_state(surface); + struct wlr_drm_syncobj_timeline *wait_timeline = NULL; + uint64_t wait_point = 0; + if (syncobj_surface_state != NULL) { + wait_timeline = syncobj_surface_state->acquire_timeline; + wait_point = syncobj_surface_state->acquire_point; + } + output_cursor_set_texture(output_cursor->output_cursor, texture, false, &src_box, dst_width, dst_height, surface->current.transform, - hotspot_x, hotspot_y); + hotspot_x, hotspot_y, wait_timeline, wait_point); + + if (syncobj_surface_state != NULL && surface->buffer != NULL && + (surface->current.committed & WLR_SURFACE_STATE_BUFFER)) { + wlr_linux_drm_syncobj_v1_state_signal_release_with_buffer(syncobj_surface_state, + &surface->buffer->base); + } if (output_cursor->output_cursor->visible) { wlr_surface_send_enter(surface, output);