export-dmabuf: Implement release semantics

This implements release semantics so that clients can hold onto buffers
while encoding.
This commit is contained in:
Andri Yngvason 2025-04-07 18:08:01 +00:00
parent a30c102163
commit cded7797f7
3 changed files with 18 additions and 6 deletions

View file

@ -32,6 +32,7 @@ struct wlr_export_dmabuf_frame_v1 {
struct wl_list link; // wlr_export_dmabuf_manager_v1.frames struct wl_list link; // wlr_export_dmabuf_manager_v1.frames
struct wlr_output *output; struct wlr_output *output;
struct wlr_buffer *buffer;
bool cursor_locked; bool cursor_locked;

View file

@ -36,14 +36,14 @@
interface version number is reset. interface version number is reset.
</description> </description>
<interface name="zwlr_export_dmabuf_manager_v1" version="1"> <interface name="zwlr_export_dmabuf_manager_v1" version="2">
<description summary="manager to inform clients and begin capturing"> <description summary="manager to inform clients and begin capturing">
This object is a manager with which to start capturing from sources. This object is a manager with which to start capturing from sources.
</description> </description>
<request name="capture_output"> <request name="capture_output">
<description summary="capture a frame from an output"> <description summary="capture a frame from an output">
Capture the next frame of a an entire output. Capture the next frame of an entire output.
</description> </description>
<arg name="frame" type="new_id" interface="zwlr_export_dmabuf_frame_v1"/> <arg name="frame" type="new_id" interface="zwlr_export_dmabuf_frame_v1"/>
<arg name="overlay_cursor" type="int" <arg name="overlay_cursor" type="int"
@ -59,7 +59,7 @@
</request> </request>
</interface> </interface>
<interface name="zwlr_export_dmabuf_frame_v1" version="1"> <interface name="zwlr_export_dmabuf_frame_v1" version="2">
<description summary="a DMA-BUF frame"> <description summary="a DMA-BUF frame">
This object represents a single DMA-BUF frame. This object represents a single DMA-BUF frame.
@ -136,7 +136,7 @@
<arg name="stride" type="uint" <arg name="stride" type="uint"
summary="line size in bytes"/> summary="line size in bytes"/>
<arg name="plane_index" type="uint" <arg name="plane_index" type="uint"
summary="index of the the plane the data in the object applies to"/> summary="index of the plane the data in the object applies to"/>
</event> </event>
<event name="ready"> <event name="ready">
@ -195,6 +195,10 @@
Unreferences the frame. This request must be called as soon as its no Unreferences the frame. This request must be called as soon as its no
longer used. longer used.
Starting from version 2, this indicates that the client has finished
processing the frame. The client must not access the underlying buffer
after destroying the zwlr_export_dmabuf_frame_v1 object.
It can be called at any time by the client. The client will still have It can be called at any time by the client. The client will still have
to close any FDs it has been given. to close any FDs it has been given.
</description> </description>

View file

@ -7,7 +7,7 @@
#include <wlr/util/log.h> #include <wlr/util/log.h>
#include "wlr-export-dmabuf-unstable-v1-protocol.h" #include "wlr-export-dmabuf-unstable-v1-protocol.h"
#define EXPORT_DMABUF_MANAGER_VERSION 1 #define EXPORT_DMABUF_MANAGER_VERSION 2
static const struct zwlr_export_dmabuf_frame_v1_interface frame_impl; static const struct zwlr_export_dmabuf_frame_v1_interface frame_impl;
@ -32,6 +32,7 @@ static void frame_destroy(struct wlr_export_dmabuf_frame_v1 *frame) {
if (frame == NULL) { if (frame == NULL) {
return; return;
} }
wlr_buffer_unlock(frame->buffer);
if (frame->output != NULL) { if (frame->output != NULL) {
wlr_output_lock_attach_render(frame->output, false); wlr_output_lock_attach_render(frame->output, false);
if (frame->cursor_locked) { if (frame->cursor_locked) {
@ -90,7 +91,13 @@ static void frame_output_handle_commit(struct wl_listener *listener,
uint32_t tv_sec_lo = tv_sec & 0xFFFFFFFF; uint32_t tv_sec_lo = tv_sec & 0xFFFFFFFF;
zwlr_export_dmabuf_frame_v1_send_ready(frame->resource, zwlr_export_dmabuf_frame_v1_send_ready(frame->resource,
tv_sec_hi, tv_sec_lo, event->when.tv_nsec); tv_sec_hi, tv_sec_lo, event->when.tv_nsec);
uint32_t version = wl_resource_get_version(frame->resource);
if (version < 2) {
frame_destroy(frame); frame_destroy(frame);
} else {
frame->buffer = wlr_buffer_lock(event->state->buffer);
}
} }
static void frame_output_handle_destroy(struct wl_listener *listener, void *data) { static void frame_output_handle_destroy(struct wl_listener *listener, void *data) {