screencopy: add presentation timestamp

This commit is contained in:
emersion 2018-06-22 22:31:33 +01:00
parent 73755ad348
commit bd8be19b79
No known key found for this signature in database
GPG key ID: 0FDE7BE0E88F5E48
3 changed files with 50 additions and 11 deletions

View file

@ -113,7 +113,8 @@ static void frame_handle_buffer(void *data,
} }
static void frame_handle_ready(void *data, static void frame_handle_ready(void *data,
struct zwlr_screencopy_frame_v1 *frame) { struct zwlr_screencopy_frame_v1 *frame, uint32_t tv_sec_hi,
uint32_t tv_sec_lo, uint32_t tv_nsec) {
buffer_copy_done = true; buffer_copy_done = true;
} }
@ -217,7 +218,7 @@ int main(int argc, char *argv[]) {
} }
struct zwlr_screencopy_frame_v1 *frame = struct zwlr_screencopy_frame_v1 *frame =
zwlr_screencopy_manager_v1_capture_output(screencopy_manager, output); zwlr_screencopy_manager_v1_capture_output(screencopy_manager, 0, output);
zwlr_screencopy_frame_v1_add_listener(frame, &frame_listener, NULL); zwlr_screencopy_frame_v1_add_listener(frame, &frame_listener, NULL);
while (!buffer_copy_done) { while (!buffer_copy_done) {

View file

@ -26,6 +26,15 @@
<description summary="screen content capturing on client buffers"> <description summary="screen content capturing on client buffers">
This protocol allows clients to ask the compositor to copy part of the This protocol allows clients to ask the compositor to copy part of the
screen content to a client buffer. screen content to a client buffer.
Warning! The protocol described in this file is experimental and
backward incompatible changes may be made. Backward compatible changes
may be added together with the corresponding interface version bump.
Backward incompatible changes are done by bumping the version number in
the protocol and interface names and resetting the interface version.
Once the protocol is to be declared stable, the 'z' prefix and the
version number in the protocol and interface names are removed and the
interface version number is reset.
</description> </description>
<interface name="zwlr_screencopy_manager_v1" version="1"> <interface name="zwlr_screencopy_manager_v1" version="1">
@ -36,9 +45,11 @@
<request name="capture_output"> <request name="capture_output">
<description summary="start capturing"> <description summary="start capturing">
Request to start capturing from the given output. Capture the next frame of a an entire output.
</description> </description>
<arg name="frame" type="new_id" interface="zwlr_screencopy_frame_v1"/> <arg name="frame" type="new_id" interface="zwlr_screencopy_frame_v1"/>
<arg name="overlay_cursor" type="int"
summary="include custom client hardware cursor on top of the frame"/>
<arg name="output" type="object" interface="wl_output"/> <arg name="output" type="object" interface="wl_output"/>
</request> </request>
@ -52,8 +63,17 @@
<interface name="zwlr_screencopy_frame_v1" version="1"> <interface name="zwlr_screencopy_frame_v1" version="1">
<description summary="a frame ready for copy"> <description summary="a frame ready for copy">
This object represents a frame which is ready to have its resources This object represents a single frame.
fetched and used.
When created, a "buffer" event will be sent. The client will then be able
to send a "copy" request. If the capture is successful, the compositor
will finally a "ready" event.
If the capture failed, the "failed" event is sent. This can happen anytime
before the "ready" event.
Once either a "ready" or a "failed" event is received, the client should
destroy the frame.
</description> </description>
<enum name="flags" bitfield="true"> <enum name="flags" bitfield="true">
@ -99,23 +119,37 @@
<event name="ready"> <event name="ready">
<description summary="indicates frame is available for reading"> <description summary="indicates frame is available for reading">
Called as soon as the frame is copied, indicating it is available Called as soon as the frame is copied, indicating it is available
for reading. for reading. This event includes the time at which presentation happened
at.
Upon receiving this event, the client should destroy the object. The timestamp is expressed as tv_sec_hi, tv_sec_lo, tv_nsec triples,
each component being an unsigned 32-bit value. Whole seconds are in
tv_sec which is a 64-bit value combined from tv_sec_hi and tv_sec_lo,
and the additional fractional part in tv_nsec as nanoseconds. Hence,
for valid timestamps tv_nsec must be in [0, 999999999]. The seconds part
may have an arbitrary offset at start.
After receiving this event, the client should destroy the object.
</description> </description>
<arg name="tv_sec_hi" type="uint"
summary="high 32 bits of the seconds part of the timestamp"/>
<arg name="tv_sec_lo" type="uint"
summary="low 32 bits of the seconds part of the timestamp"/>
<arg name="tv_nsec" type="uint"
summary="nanoseconds part of the timestamp"/>
</event> </event>
<event name="failed"> <event name="failed">
<description summary="frame copy failed"> <description summary="frame copy failed">
This event indicates that the attempted frame copy has failed. This event indicates that the attempted frame copy has failed.
Upon receiving this event, the client should destroy the object. After receiving this event, the client should destroy the object.
</description> </description>
</event> </event>
<request name="destroy" type="destructor"> <request name="destroy" type="destructor">
<description summary="delete this object, used or not"> <description summary="delete this object, used or not">
Destroys the frame. Destroys the frame. This request can be sent at any time by the client.
</description> </description>
</request> </request>
</interface> </interface>

View file

@ -21,6 +21,7 @@ static void frame_handle_output_swap_buffers(struct wl_listener *listener,
void *_data) { void *_data) {
struct wlr_screencopy_frame_v1 *frame = struct wlr_screencopy_frame_v1 *frame =
wl_container_of(listener, frame, output_swap_buffers); wl_container_of(listener, frame, output_swap_buffers);
struct wlr_output_event_swap_buffers *event = _data;
struct wlr_output *output = frame->output; struct wlr_output *output = frame->output;
struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend); struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend);
@ -51,7 +52,10 @@ static void frame_handle_output_swap_buffers(struct wl_listener *listener,
return; return;
} }
zwlr_screencopy_frame_v1_send_ready(frame->resource); uint32_t tv_sec_hi = event->when->tv_sec >> 32;
uint32_t tv_sec_lo = event->when->tv_sec & 0xFFFFFFFF;
zwlr_screencopy_frame_v1_send_ready(frame->resource,
tv_sec_hi, tv_sec_lo, event->when->tv_nsec);
// TODO: make frame resource inert // TODO: make frame resource inert
} }
@ -134,7 +138,7 @@ static struct wlr_screencopy_manager_v1 *manager_from_resource(
static void manager_handle_capture_output(struct wl_client *client, static void manager_handle_capture_output(struct wl_client *client,
struct wl_resource *manager_resource, uint32_t id, struct wl_resource *manager_resource, uint32_t id,
struct wl_resource *output_resource) { int32_t overlay_cursor, struct wl_resource *output_resource) {
struct wlr_screencopy_manager_v1 *manager = struct wlr_screencopy_manager_v1 *manager =
manager_from_resource(manager_resource); manager_from_resource(manager_resource);
struct wlr_output *output = wlr_output_from_resource(output_resource); struct wlr_output *output = wlr_output_from_resource(output_resource);