cursor: add support for linux-drm-syncobj-v1

This commit is contained in:
Simon Ser 2024-05-10 18:32:04 +02:00
parent 5f88635118
commit 738bbf01ee
4 changed files with 40 additions and 6 deletions

View File

@ -18,7 +18,8 @@ bool output_ensure_buffer(struct wlr_output *output,
bool output_cursor_set_texture(struct wlr_output_cursor *cursor, bool output_cursor_set_texture(struct wlr_output_cursor *cursor,
struct wlr_texture *texture, bool own_texture, const struct wlr_fbox *src_box, struct wlr_texture *texture, bool own_texture, const struct wlr_fbox *src_box,
int dst_width, int dst_height, enum wl_output_transform transform, 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); void output_defer_present(struct wlr_output *output, struct wlr_output_event_present event);

View File

@ -45,6 +45,8 @@ struct wlr_output_cursor {
int32_t hotspot_x, hotspot_y; int32_t hotspot_x, hotspot_y;
struct wlr_texture *texture; struct wlr_texture *texture;
bool own_texture; bool own_texture;
struct wlr_drm_syncobj_timeline *wait_timeline;
uint64_t wait_point;
struct wl_listener renderer_destroy; struct wl_listener renderer_destroy;
struct wl_list link; struct wl_list link;
}; };

View File

@ -3,6 +3,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <wlr/interfaces/wlr_output.h> #include <wlr/interfaces/wlr_output.h>
#include <wlr/render/swapchain.h> #include <wlr/render/swapchain.h>
#include <wlr/render/drm_syncobj.h>
#include <wlr/render/wlr_renderer.h> #include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_compositor.h> #include <wlr/types/wlr_compositor.h>
#include <wlr/util/log.h> #include <wlr/util/log.h>
@ -271,6 +272,8 @@ static struct wlr_buffer *render_cursor_buffer(struct wlr_output_cursor *cursor)
.src_box = cursor->src_box, .src_box = cursor->src_box,
.dst_box = dst_box, .dst_box = dst_box,
.transform = transform, .transform = transform,
.wait_timeline = cursor->wait_timeline,
.wait_point = cursor->wait_point,
}); });
if (!wlr_render_pass_submit(pass)) { 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; hotspot_y /= cursor->output->scale;
return output_cursor_set_texture(cursor, texture, true, &src_box, 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, static void output_cursor_handle_renderer_destroy(struct wl_listener *listener,
void *data) { void *data) {
struct wlr_output_cursor *cursor = wl_container_of(listener, cursor, renderer_destroy); struct wlr_output_cursor *cursor = wl_container_of(listener, cursor, renderer_destroy);
output_cursor_set_texture(cursor, NULL, false, NULL, 0, 0, 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, bool output_cursor_set_texture(struct wlr_output_cursor *cursor,
struct wlr_texture *texture, bool own_texture, const struct wlr_fbox *src_box, struct wlr_texture *texture, bool own_texture, const struct wlr_fbox *src_box,
int dst_width, int dst_height, enum wl_output_transform transform, 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; struct wlr_output *output = cursor->output;
output_cursor_reset(cursor); output_cursor_reset(cursor);
@ -395,6 +400,15 @@ bool output_cursor_set_texture(struct wlr_output_cursor *cursor,
cursor->texture = texture; cursor->texture = texture;
cursor->own_texture = own_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); wl_list_remove(&cursor->renderer_destroy.link);
if (texture != NULL) { if (texture != NULL) {
cursor->renderer_destroy.notify = output_cursor_handle_renderer_destroy; 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) { if (cursor->own_texture) {
wlr_texture_destroy(cursor->texture); wlr_texture_destroy(cursor->texture);
} }
wlr_drm_syncobj_timeline_unref(cursor->wait_timeline);
wl_list_remove(&cursor->link); wl_list_remove(&cursor->link);
free(cursor); free(cursor);
} }

View File

@ -7,6 +7,7 @@
#include <wlr/types/wlr_cursor.h> #include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_fractional_scale_v1.h> #include <wlr/types/wlr_fractional_scale_v1.h>
#include <wlr/types/wlr_input_device.h> #include <wlr/types/wlr_input_device.h>
#include <wlr/types/wlr_linux_drm_syncobj_v1.h>
#include <wlr/types/wlr_output_layout.h> #include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_output.h> #include <wlr/types/wlr_output.h>
#include <wlr/types/wlr_pointer.h> #include <wlr/types/wlr_pointer.h>
@ -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, output_cursor_set_texture(output_cursor->output_cursor, texture, true,
&src_box, dst_width, dst_height, WL_OUTPUT_TRANSFORM_NORMAL, &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) { } else if (cur->state->surface != NULL) {
struct wlr_surface *surface = cur->state->surface; 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_width = surface->current.width;
int dst_height = surface->current.height; 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, output_cursor_set_texture(output_cursor->output_cursor, texture, false,
&src_box, dst_width, dst_height, surface->current.transform, &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) { if (output_cursor->output_cursor->visible) {
wlr_surface_send_enter(surface, output); wlr_surface_send_enter(surface, output);