diff --git a/include/wlr/types/wlr_export_dmabuf_v1.h b/include/wlr/types/wlr_export_dmabuf_v1.h index 78db1e61..4cb3393f 100644 --- a/include/wlr/types/wlr_export_dmabuf_v1.h +++ b/include/wlr/types/wlr_export_dmabuf_v1.h @@ -11,6 +11,8 @@ struct wlr_export_dmabuf_frame_v1 { struct wl_list link; struct wlr_output *output; + + struct wl_listener output_swap_buffers; }; struct wlr_export_dmabuf_manager_v1 { diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index 669b96ed..96c98dc3 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -82,7 +82,7 @@ struct wlr_output { struct { struct wl_signal frame; struct wl_signal needs_swap; - struct wl_signal swap_buffers; + struct wl_signal swap_buffers; // wlr_output_event_swap_buffers struct wl_signal enable; struct wl_signal mode; struct wl_signal scale; @@ -108,6 +108,12 @@ struct wlr_output { void *data; }; +struct wlr_output_event_swap_buffers { + struct wlr_output *output; + struct timespec *when; + pixman_region32_t *damage; +}; + struct wlr_surface; void wlr_output_enable(struct wlr_output *output, bool enable); diff --git a/types/wlr_export_dmabuf_v1.c b/types/wlr_export_dmabuf_v1.c index fa732397..2f1c88f2 100644 --- a/types/wlr_export_dmabuf_v1.c +++ b/types/wlr_export_dmabuf_v1.c @@ -30,9 +30,25 @@ static const struct zwlr_export_dmabuf_frame_v1_interface frame_impl = { static void frame_handle_resource_destroy(struct wl_resource *resource) { struct wlr_export_dmabuf_frame_v1 *frame = frame_from_resource(resource); wl_list_remove(&frame->link); + wl_list_remove(&frame->output_swap_buffers.link); free(frame); } +static void frame_output_handle_swap_buffers(struct wl_listener *listener, + void *data) { + struct wlr_export_dmabuf_frame_v1 *frame = + wl_container_of(listener, frame, output_swap_buffers); + struct wlr_output_event_swap_buffers *event = data; + + wl_list_remove(&frame->output_swap_buffers.link); + wl_list_init(&frame->output_swap_buffers.link); + + uint32_t tv_sec_hi = event->when->tv_sec << 32; + uint32_t tv_sec_lo = event->when->tv_sec & 0xFFFFFFFF; + zwlr_export_dmabuf_frame_v1_send_ready(frame->resource, + tv_sec_hi, tv_sec_lo, event->when->tv_nsec); +} + static const struct zwlr_export_dmabuf_manager_v1_interface manager_impl; @@ -87,7 +103,7 @@ static void manager_handle_capture_output(struct wl_client *client, uint32_t frame_flags = 0; uint32_t mod_high = attribs.modifier[0] >> 32; - uint32_t mod_low = attribs.modifier[0]; + uint32_t mod_low = attribs.modifier[0] & 0xFFFFFFFF; zwlr_export_dmabuf_frame_v1_send_frame(frame->resource, output->width, output->height, output->scale, output->transform, @@ -106,9 +122,8 @@ static void manager_handle_capture_output(struct wl_client *client, attribs.offset[i], attribs.stride[i]); } - // TODO: wait for the frame to be ready - // TODO: timestamps - zwlr_export_dmabuf_frame_v1_send_ready(frame->resource, 0, 0, 0); + frame->output_swap_buffers.notify = frame_output_handle_swap_buffers; + wl_signal_add(&output->events.swap_buffers, &frame->output_swap_buffers); } static const struct zwlr_export_dmabuf_manager_v1_interface manager_impl = { diff --git a/types/wlr_output.c b/types/wlr_output.c index f7001b16..b0321d7f 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -467,7 +467,12 @@ bool wlr_output_swap_buffers(struct wlr_output *output, struct timespec *when, output->idle_frame = NULL; } - wlr_signal_emit_safe(&output->events.swap_buffers, damage); + struct wlr_output_event_swap_buffers event = { + .output = output, + .when = when, + .damage = damage, + }; + wlr_signal_emit_safe(&output->events.swap_buffers, &event); int width, height; wlr_output_transformed_resolution(output, &width, &height);