From f0945e112f3f4e50021f55d59572526ff9fee847 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 4 Nov 2020 14:38:56 +0100 Subject: [PATCH] export-dmabuf: export DMA-BUF on output commit We were previously exporting DMA-BUFs when receiving the capture_output request, and sending a done event on wlr_output.events.precommit. Instead, export and send done on wlr_output.events.commit. --- include/wlr/types/wlr_export_dmabuf_v1.h | 3 +- types/wlr_export_dmabuf_v1.c | 69 ++++++++++++------------ 2 files changed, 35 insertions(+), 37 deletions(-) diff --git a/include/wlr/types/wlr_export_dmabuf_v1.h b/include/wlr/types/wlr_export_dmabuf_v1.h index 817bb1a0..344e6cbf 100644 --- a/include/wlr/types/wlr_export_dmabuf_v1.h +++ b/include/wlr/types/wlr_export_dmabuf_v1.h @@ -29,12 +29,11 @@ struct wlr_export_dmabuf_frame_v1 { struct wlr_export_dmabuf_manager_v1 *manager; struct wl_list link; // wlr_export_dmabuf_manager_v1::frames - struct wlr_dmabuf_attributes attribs; struct wlr_output *output; bool cursor_locked; - struct wl_listener output_precommit; + struct wl_listener output_commit; }; struct wlr_export_dmabuf_manager_v1 *wlr_export_dmabuf_manager_v1_create( diff --git a/types/wlr_export_dmabuf_v1.c b/types/wlr_export_dmabuf_v1.c index c2ec34c8..a8e2a4bd 100644 --- a/types/wlr_export_dmabuf_v1.c +++ b/types/wlr_export_dmabuf_v1.c @@ -41,8 +41,7 @@ static void frame_destroy(struct wlr_export_dmabuf_frame_v1 *frame) { } } wl_list_remove(&frame->link); - wl_list_remove(&frame->output_precommit.link); - wlr_dmabuf_attributes_finish(&frame->attribs); + wl_list_remove(&frame->output_commit.link); // Make the frame resource inert wl_resource_set_user_data(frame->resource, NULL); free(frame); @@ -53,18 +52,41 @@ static void frame_handle_resource_destroy(struct wl_resource *resource) { frame_destroy(frame); } -static void frame_output_handle_precommit(struct wl_listener *listener, +static void frame_output_handle_commit(struct wl_listener *listener, void *data) { struct wlr_export_dmabuf_frame_v1 *frame = - wl_container_of(listener, frame, output_precommit); - struct wlr_output_event_precommit *event = data; + wl_container_of(listener, frame, output_commit); + struct wlr_output_event_commit *event = data; - if (!(event->output->pending.committed & WLR_OUTPUT_STATE_BUFFER)) { + if (!(event->committed & WLR_OUTPUT_STATE_BUFFER)) { return; } - wl_list_remove(&frame->output_precommit.link); - wl_list_init(&frame->output_precommit.link); + wl_list_remove(&frame->output_commit.link); + wl_list_init(&frame->output_commit.link); + + struct wlr_dmabuf_attributes attribs = {0}; + if (!wlr_output_export_dmabuf(frame->output, &attribs)) { + zwlr_export_dmabuf_frame_v1_send_cancel(frame->resource, + ZWLR_EXPORT_DMABUF_FRAME_V1_CANCEL_REASON_TEMPORARY); + frame_destroy(frame); + return; + } + + uint32_t frame_flags = ZWLR_EXPORT_DMABUF_FRAME_V1_FLAGS_TRANSIENT; + uint32_t mod_high = attribs.modifier >> 32; + uint32_t mod_low = attribs.modifier & 0xFFFFFFFF; + zwlr_export_dmabuf_frame_v1_send_frame(frame->resource, + attribs.width, attribs.height, 0, 0, attribs.flags, frame_flags, + attribs.format, mod_high, mod_low, attribs.n_planes); + + for (int i = 0; i < attribs.n_planes; ++i) { + off_t size = lseek(attribs.fd[i], 0, SEEK_END); + zwlr_export_dmabuf_frame_v1_send_object(frame->resource, i, + attribs.fd[i], size, attribs.offset[i], attribs.stride[i], i); + } + + wlr_dmabuf_attributes_finish(&attribs); time_t tv_sec = event->when->tv_sec; uint32_t tv_sec_hi = (sizeof(tv_sec) > 4) ? tv_sec >> 32 : 0; @@ -98,7 +120,7 @@ static void manager_handle_capture_output(struct wl_client *client, return; } frame->manager = manager; - wl_list_init(&frame->output_precommit.link); + wl_list_init(&frame->output_commit.link); uint32_t version = wl_resource_get_version(manager_resource); frame->resource = wl_resource_create(client, @@ -120,14 +142,6 @@ static void manager_handle_capture_output(struct wl_client *client, return; } - struct wlr_dmabuf_attributes *attribs = &frame->attribs; - if (!wlr_output_export_dmabuf(output, attribs)) { - zwlr_export_dmabuf_frame_v1_send_cancel(frame->resource, - ZWLR_EXPORT_DMABUF_FRAME_V1_CANCEL_REASON_TEMPORARY); - frame_destroy(frame); - return; - } - frame->output = output; wlr_output_lock_attach_render(frame->output, true); @@ -136,26 +150,11 @@ static void manager_handle_capture_output(struct wl_client *client, frame->cursor_locked = true; } - uint32_t frame_flags = ZWLR_EXPORT_DMABUF_FRAME_V1_FLAGS_TRANSIENT; - uint32_t mod_high = attribs->modifier >> 32; - uint32_t mod_low = attribs->modifier & 0xFFFFFFFF; - - zwlr_export_dmabuf_frame_v1_send_frame(frame->resource, - output->width, output->height, 0, 0, attribs->flags, frame_flags, - attribs->format, mod_high, mod_low, attribs->n_planes); - - for (int i = 0; i < attribs->n_planes; ++i) { - off_t size = lseek(attribs->fd[i], 0, SEEK_END); - - zwlr_export_dmabuf_frame_v1_send_object(frame->resource, i, - attribs->fd[i], size, attribs->offset[i], attribs->stride[i], i); - } + wl_list_remove(&frame->output_commit.link); + wl_signal_add(&output->events.commit, &frame->output_commit); + frame->output_commit.notify = frame_output_handle_commit; wlr_output_schedule_frame(output); - - wl_list_remove(&frame->output_precommit.link); - wl_signal_add(&output->events.precommit, &frame->output_precommit); - frame->output_precommit.notify = frame_output_handle_precommit; } static void manager_handle_destroy(struct wl_client *client,