Skip to content

Commit

Permalink
Implement zext-screencopy-unstable-v1
Browse files Browse the repository at this point in the history
  • Loading branch information
any1 committed Oct 31, 2021
1 parent 87d6edf commit 84bbbef
Show file tree
Hide file tree
Showing 5 changed files with 1,073 additions and 0 deletions.
78 changes: 78 additions & 0 deletions include/wlr/types/wlr_zext_screencopy_v1.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* This an unstable interface of wlroots. No guarantees are made regarding the
* future consistency of this API.
*/
#ifndef WLR_USE_UNSTABLE
#error "Add -DWLR_USE_UNSTABLE to enable unstable wlroots features"
#endif

#ifndef WLR_TYPES_WLR_ZEXT_SCREENCOPY_V1_H
#define WLR_TYPES_WLR_ZEXT_SCREENCOPY_V1_H

#include <wayland-server-core.h>
#include <pixman.h>
#include <stdbool.h>

struct wlr_buffer;

struct wlr_zext_screencopy_manager_v1 {
struct wl_global *global;

struct wl_listener display_destroy;

struct {
struct wl_signal destroy;
} events;

void *data;
};

enum wlr_zext_screencopy_surface_v1_type {
WLR_ZEXT_SCREENCOPY_SURFACE_V1_TYPE_OUTPUT,
WLR_ZEXT_SCREENCOPY_SURFACE_V1_TYPE_OUTPUT_CURSOR,
};

enum wlr_zext_screencopy_surface_v1_state {
WLR_ZEXT_SCREENCOPY_SURFACE_V1_STATE_WAITING_FOR_BUFFER_FORMATS,
WLR_ZEXT_SCREENCOPY_SURFACE_V1_STATE_READY,
};

struct wlr_zext_screencopy_surface_v1 {
struct wl_resource *resource;

enum wlr_zext_screencopy_surface_v1_type type;
enum wlr_zext_screencopy_surface_v1_state state;

uint32_t wl_shm_format;
int wl_shm_stride;

uint32_t dmabuf_format;

/* Buffer and info staged for next commit */
struct wl_resource *staged_buffer_resource;
struct pixman_region32 staged_buffer_damage;
struct wl_listener staged_buffer_destroy;

uint32_t options;

/* Currently attached buffer and info */
struct wl_resource *buffer_resource;
struct pixman_region32 buffer_damage;
struct wl_listener buffer_destroy;

/* Accumulated frame damage for the surface */
struct pixman_region32 frame_damage;

struct wlr_output *output;

struct wl_listener output_precommit;
struct wl_listener output_commit;
struct wl_listener output_destroy;

void *data;
};

struct wlr_zext_screencopy_manager_v1 *wlr_zext_screencopy_manager_v1_create(
struct wl_display *display);

#endif
1 change: 1 addition & 0 deletions protocol/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ protocols = {
'wlr-output-power-management-unstable-v1': 'wlr-output-power-management-unstable-v1.xml',
'wlr-screencopy-unstable-v1': 'wlr-screencopy-unstable-v1.xml',
'wlr-virtual-pointer-unstable-v1': 'wlr-virtual-pointer-unstable-v1.xml',
'screencopy-unstable-v1': 'screencopy-unstable-v1.xml',
}

protocols_code = {}
Expand Down
234 changes: 234 additions & 0 deletions protocol/screencopy-unstable-v1.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="screencopy_unstable_v1">
<copyright>
Copyright © 2021 Andri Yngvason

Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
</copyright>

<description summary="screen content capturing on client buffers">
This protocol allows clients to ask the compositor to copy part of the
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>

<interface name="zext_screencopy_manager_v1" version="1">
<description summary="manager to inform clients and begin capturing">
This object is a manager which offers requests to start capturing from a
source.
</description>

<request name="capture_output">
<description summary="capture an output">
Create a capturing surface for an output
</description>
<arg name="surface" type="new_id" interface="zext_screencopy_surface_v1"/>
<arg name="output" type="object" interface="wl_output"/>
</request>

<request name="capture_output_cursor">
<description summary="capture an output's cursor">
Create a capturing surface for an output's cursor
</description>
<arg name="surface" type="new_id" interface="zext_screencopy_surface_v1"/>
<arg name="output" type="object" interface="wl_output"/>
</request>
</interface>

<interface name="zext_screencopy_surface_v1" version="1">
<description summary="a frame ready for copy">
This object represents a surface that's being captured.

After a screencopy surface is created, buffer_info events will be emitted
from the compositor to tell the client which buffer types and formats are
supported for reading from the surface.

When the client knows all the buffer attributes, it can create a buffer,
attach it to the screencopy surface using the "attach_buffer" request,
set the buffer damage using the "damage_buffer" request and then call
the "commit" request.

After "commit" has been called, the next time that a buffer is committed
by the compositor, the contents of that buffer will be copied to the one
committed to the screencopy surface. A series of events will be generated,
ending with the "ready" event, which means that the buffer is ready to be
used and a buffer may be committed to the surface again.

The "failed" event may be sent at any time. When this happens, the client
must destroy the surface. Depending on the failure reason, the client can
create a new surface to replace it.
</description>

<enum name="failure_reason">
<entry name="unspec" value="0"/>
<entry name="invalid_buffer" value="1"/>
<entry name="output_missing" value="2"/>
<entry name="output_disabled" value="3"/>
<entry name="cursor_missing" value="4"/>
</enum>

<enum name="options" bitfield="true">
<entry name="none" value="0"/>
<entry name="wait_for_damage" value="1"/>
<entry name="schedule_frame" value="2"/>
</enum>

<enum name="buffer_type">
<entry name="none" value="0"/>
<entry name="wl_shm" value="1"/>
<entry name="dmabuf" value="2"/>
</enum>

<event name="buffer_info">
<description summary="buffer information">
Provides information about buffer parameters that need to be used for
this surface. This event is sent for every supported buffer type after
the surface is created. After all supported buffers have been
enumerated, an event with type = none is sent. All other parameters
should be set to 0.

The stride parameter is invalid for dmabuf and may be set to 0.
</description>
<arg name="type" type="uint" enum="buffer_type" summary="buffer type"/>
<arg name="format" type="uint" summary="buffer drm format"/>
<arg name="width" type="uint" summary="buffer width"/>
<arg name="height" type="uint" summary="buffer height"/>
<arg name="stride" type="uint" summary="buffer stride"/>
</event>

<request name="attach_buffer">
<description summary="attach buffer to surface">
Attach a buffer to the surface.
</description>
<arg name="buffer" type="object" interface="wl_buffer"/>
</request>

<request name="damage_buffer">
<description summary="attach buffer to surface">
Apply damage to the buffer which is to be committed next.

This is for optimisation purposes. The compositor may use this
information to reduce copying.

The client must submit damage if it's using multiple buffers. Otherwise,
the server might not copy into damaged regions of the buffer.
</description>
<arg name="x" type="uint" summary="region x coordinates"/>
<arg name="y" type="uint" summary="region y coordinates"/>
<arg name="width" type="uint" summary="region width"/>
<arg name="height" type="uint" summary="region height"/>
</request>

<request name="commit">
<description summary="commit surface">
Commit the screencopy surface. The frame will be copied to the surface
on next frame commit.

If the "copy_on_damage" flag is set, no copies are carried out until the
source surface is damaged.
</description>
<arg name="options" type="uint" enum="options"/>
</request>

<request name="destroy" type="destructor">
<description summary="delete this object">
Destroys the surface. This request can be sent at any time by the
client.
</description>
</request>

<event name="transform">
<description summary="carries the output transform">
This event is sent before the ready event and holds the output transform
of the source buffer.
</description>
<arg name="transform" type="int" enum="wl_output.transform"/>
</event>

<event name="damage">
<description summary="carries the coordinates of the damaged region">
This event is sent before the ready event. It may be generated multiple
times for each commit.

The arguments describe a box around an area that has changed since the
last ready event.
</description>
<arg name="x" type="uint" summary="damaged x coordinates"/>
<arg name="y" type="uint" summary="damaged y coordinates"/>
<arg name="width" type="uint" summary="current width"/>
<arg name="height" type="uint" summary="current height"/>
</event>

<event name="cursor_info">
<description summary="cursor specific information">
This event is only relevant when a cursor is being captured. It may be
generated at any time, but it should at least be generated once before
the first ready event of the surface.
</description>
<arg name="position_x" type="int" summary="position x coordinates"/>
<arg name="position_y" type="int" summary="position y coordinates"/>
<arg name="hotspot_x" type="int" summary="hotspot x coordinates"/>
<arg name="hotspot_y" type="int" summary="hotspot y coordinates"/>
</event>

<event name="failed">
<description summary="commit failed">
This event indicates that the attempted frame copy has failed.

After receiving this event, the client should destroy the object.
</description>
<arg name="reason" type="uint" enum="failure_reason"/>
</event>

<event name="presentation_time">
<description summary="indicates the presentation time of the frame">
This event indicates the presentation time of the frame when applicable.

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.
</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 name="ready">
<description summary="indicates frame is available for reading">
Called as soon as the frame is copied, indicating it is available
for reading.
</description>
</event>
</interface>
</protocol>
1 change: 1 addition & 0 deletions types/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ wlr_files += files(
'wlr_xdg_foreign_v2.c',
'wlr_xdg_foreign_registry.c',
'wlr_xdg_output_v1.c',
'wlr_zext_screencopy_v1.c',
)

if features.get('drm-backend')
Expand Down
Loading

0 comments on commit 84bbbef

Please sign in to comment.