export-dmabuf: correctly finish wlr_linux_dmabuf_attribs

master
emersion 7 years ago
parent 1377e551ef
commit 00e108f2fc
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48

@ -2,6 +2,7 @@
#define WLR_TYPES_WLR_EXPORT_DMABUF_V1_H #define WLR_TYPES_WLR_EXPORT_DMABUF_V1_H
#include <wayland-server.h> #include <wayland-server.h>
#include <wlr/types/wlr_linux_dmabuf.h>
struct wlr_export_dmabuf_manager_v1; struct wlr_export_dmabuf_manager_v1;
@ -10,6 +11,7 @@ struct wlr_export_dmabuf_frame_v1 {
struct wlr_export_dmabuf_manager_v1 *manager; struct wlr_export_dmabuf_manager_v1 *manager;
struct wl_list link; struct wl_list link;
struct wlr_dmabuf_buffer_attribs attribs;
struct wlr_output *output; struct wlr_output *output;
struct wl_listener output_swap_buffers; struct wl_listener output_swap_buffers;

@ -37,6 +37,12 @@ struct wlr_dmabuf_buffer {
struct wlr_dmabuf_buffer_attribs attributes; struct wlr_dmabuf_buffer_attribs attributes;
}; };
/**
* Closes all file descriptors in the DMA-BUF attributes.
*/
void wlr_dmabuf_buffer_attribs_finish(
struct wlr_dmabuf_buffer_attribs *attribs);
/** /**
* Returns true if the given resource was created via the linux-dmabuf * Returns true if the given resource was created via the linux-dmabuf
* buffer protocol, false otherwise * buffer protocol, false otherwise

@ -5,6 +5,7 @@
#include <wlr/types/wlr_linux_dmabuf.h> #include <wlr/types/wlr_linux_dmabuf.h>
#include <wlr/types/wlr_output.h> #include <wlr/types/wlr_output.h>
#include "wlr-export-dmabuf-unstable-v1-protocol.h" #include "wlr-export-dmabuf-unstable-v1-protocol.h"
#include <wlr/util/log.h>
#define EXPORT_DMABUF_MANAGER_VERSION 1 #define EXPORT_DMABUF_MANAGER_VERSION 1
@ -31,6 +32,7 @@ static void frame_handle_resource_destroy(struct wl_resource *resource) {
struct wlr_export_dmabuf_frame_v1 *frame = frame_from_resource(resource); struct wlr_export_dmabuf_frame_v1 *frame = frame_from_resource(resource);
wl_list_remove(&frame->link); wl_list_remove(&frame->link);
wl_list_remove(&frame->output_swap_buffers.link); wl_list_remove(&frame->output_swap_buffers.link);
wlr_dmabuf_buffer_attribs_finish(&frame->attribs);
free(frame); free(frame);
} }
@ -80,6 +82,7 @@ static void manager_handle_capture_output(struct wl_client *client,
} }
frame->manager = manager; frame->manager = manager;
frame->output = output; frame->output = output;
wl_list_init(&frame->output_swap_buffers.link);
uint32_t version = wl_resource_get_version(manager_resource); uint32_t version = wl_resource_get_version(manager_resource);
frame->resource = wl_resource_create(client, frame->resource = wl_resource_create(client,
@ -93,9 +96,8 @@ static void manager_handle_capture_output(struct wl_client *client,
wl_list_insert(&manager->frames, &frame->link); wl_list_insert(&manager->frames, &frame->link);
struct wlr_dmabuf_buffer_attribs attribs; struct wlr_dmabuf_buffer_attribs *attribs = &frame->attribs;
if (!wlr_output_export_dmabuf(output, &attribs)) { if (!wlr_output_export_dmabuf(output, attribs)) {
wl_list_init(&frame->output_swap_buffers.link);
// TODO: abort reason // TODO: abort reason
zwlr_export_dmabuf_frame_v1_send_abort(frame->resource, 0); zwlr_export_dmabuf_frame_v1_send_abort(frame->resource, 0);
return; return;
@ -104,28 +106,29 @@ static void manager_handle_capture_output(struct wl_client *client,
// TODO: multiple layers support // TODO: multiple layers support
uint32_t frame_flags = 0; uint32_t frame_flags = 0;
uint32_t mod_high = attribs.modifier[0] >> 32; uint32_t mod_high = attribs->modifier[0] >> 32;
uint32_t mod_low = attribs.modifier[0] & 0xFFFFFFFF; uint32_t mod_low = attribs->modifier[0] & 0xFFFFFFFF;
zwlr_export_dmabuf_frame_v1_send_frame(frame->resource, zwlr_export_dmabuf_frame_v1_send_frame(frame->resource,
output->width, output->height, output->scale, output->transform, output->width, output->height, output->scale, output->transform,
attribs.flags, frame_flags, mod_high, mod_low, attribs.n_planes, 1); attribs->flags, frame_flags, mod_high, mod_low, attribs->n_planes, 1);
zwlr_export_dmabuf_frame_v1_send_layer(frame->resource, 0, zwlr_export_dmabuf_frame_v1_send_layer(frame->resource, 0,
attribs.format, 1); attribs->format, 1);
for (int i = 0; i < attribs.n_planes; ++i) { for (int i = 0; i < attribs->n_planes; ++i) {
// TODO: what to do if the kernel doesn't support seek on buffer // TODO: what to do if the kernel doesn't support seek on buffer
off_t size = lseek(attribs.fd[i], 0, SEEK_END); off_t size = lseek(attribs->fd[i], 0, SEEK_END);
zwlr_export_dmabuf_frame_v1_send_object(frame->resource, i, zwlr_export_dmabuf_frame_v1_send_object(frame->resource, i,
attribs.fd[i], size); attribs->fd[i], size);
zwlr_export_dmabuf_frame_v1_send_plane(frame->resource, i, 0, i, zwlr_export_dmabuf_frame_v1_send_plane(frame->resource, i, 0, i,
attribs.offset[i], attribs.stride[i]); attribs->offset[i], attribs->stride[i]);
} }
frame->output_swap_buffers.notify = frame_output_handle_swap_buffers; wl_list_remove(&frame->output_swap_buffers.link);
wl_signal_add(&output->events.swap_buffers, &frame->output_swap_buffers); wl_signal_add(&output->events.swap_buffers, &frame->output_swap_buffers);
frame->output_swap_buffers.notify = frame_output_handle_swap_buffers;
} }
static const struct zwlr_export_dmabuf_manager_v1_interface manager_impl = { static const struct zwlr_export_dmabuf_manager_v1_interface manager_impl = {

@ -51,12 +51,17 @@ struct wlr_dmabuf_buffer *wlr_dmabuf_buffer_from_buffer_resource(
return buffer; return buffer;
} }
static void linux_dmabuf_buffer_destroy(struct wlr_dmabuf_buffer *buffer) { void wlr_dmabuf_buffer_attribs_finish(
for (int i = 0; i < buffer->attributes.n_planes; i++) { struct wlr_dmabuf_buffer_attribs *attribs) {
close(buffer->attributes.fd[i]); for (int i = 0; i < attribs->n_planes; ++i) {
buffer->attributes.fd[i] = -1; close(attribs->fd[i]);
attribs->fd[i] = -1;
} }
buffer->attributes.n_planes = 0; attribs->n_planes = 0;
}
static void linux_dmabuf_buffer_destroy(struct wlr_dmabuf_buffer *buffer) {
wlr_dmabuf_buffer_attribs_finish(&buffer->attributes);
free(buffer); free(buffer);
} }

Loading…
Cancel
Save