Sunshine master
Self-hosted game stream host for Moonlight.
wayland.h
Go to the documentation of this file.
1
5#pragma once
6
7// standard includes
8#include <bitset>
9#include <cstdint>
10#include <map>
11#include <vector>
12
13#ifdef SUNSHINE_BUILD_WAYLAND
14 #include <linux-dmabuf-unstable-v1.h>
15 #include <wlr-screencopy-unstable-v1.h>
16 #include <xdg-output-unstable-v1.h>
17#endif
18
19// local includes
20#include "graphics.h"
21
26#ifdef SUNSHINE_BUILD_WAYLAND
27
28namespace wl {
33
37 class frame_t {
38 public:
39 frame_t();
43 void destroy();
44
46 std::optional<std::chrono::steady_clock::time_point> frame_timestamp;
47 };
48
52 class dmabuf_t {
53 public:
62
63 dmabuf_t();
64 ~dmabuf_t();
65
66 dmabuf_t(dmabuf_t &&) = delete;
67 dmabuf_t(const dmabuf_t &) = delete;
68 dmabuf_t &operator=(const dmabuf_t &) = delete;
69 dmabuf_t &operator=(dmabuf_t &&) = delete;
70
80 void listen(zwlr_screencopy_manager_v1 *screencopy_manager, zwp_linux_dmabuf_v1 *dmabuf_interface, const std::map<std::uint32_t, std::vector<std::uint64_t>> *supported_modifiers, wl_output *output, bool blend_cursor = false);
88 static void buffer_params_created(void *data, struct zwp_linux_buffer_params_v1 *params, struct wl_buffer *wl_buffer);
95 static void buffer_params_failed(void *data, struct zwp_linux_buffer_params_v1 *params);
105 void buffer(zwlr_screencopy_frame_v1 *frame, std::uint32_t format, std::uint32_t width, std::uint32_t height, std::uint32_t stride);
114 void linux_dmabuf(zwlr_screencopy_frame_v1 *frame, std::uint32_t format, std::uint32_t width, std::uint32_t height);
120 void buffer_done(zwlr_screencopy_frame_v1 *frame);
127 void flags(zwlr_screencopy_frame_v1 *frame, std::uint32_t flags);
137 void damage(zwlr_screencopy_frame_v1 *frame, std::uint32_t x, std::uint32_t y, std::uint32_t width, std::uint32_t height);
146 void ready(zwlr_screencopy_frame_v1 *frame, std::uint32_t tv_sec_hi, std::uint32_t tv_sec_lo, std::uint32_t tv_nsec);
152 void failed(zwlr_screencopy_frame_v1 *frame);
153
160 return current_frame == &frames[0] ? &frames[1] : &frames[0];
161 }
162
164 std::array<frame_t, 2> frames;
166 zwlr_screencopy_frame_v1_listener listener;
167
168 private:
169 bool init_gbm();
170 void cleanup_gbm();
171 void create_and_copy_dmabuf(zwlr_screencopy_frame_v1 *frame);
172
173 zwp_linux_dmabuf_v1 *dmabuf_interface {nullptr};
174 const std::map<std::uint32_t, std::vector<std::uint64_t>> *supported_modifiers {nullptr};
175
176 struct {
177 bool supported {false};
178 std::uint32_t format;
179 std::uint32_t width;
180 std::uint32_t height;
181 std::uint32_t stride;
182 } shm_info;
183
184 struct {
185 bool supported {false};
186 std::uint32_t format;
187 std::uint32_t width;
188 std::uint32_t height;
189 } dmabuf_info;
190
191 struct gbm_device *gbm_device {nullptr};
192 struct gbm_bo *current_bo {nullptr};
193 struct wl_buffer *current_wl_buffer {nullptr};
194 bool y_invert {false};
195 };
196
200 class monitor_t {
201 public:
207 explicit monitor_t(wl_output *output);
208
209 monitor_t(monitor_t &&) = delete;
210 monitor_t(const monitor_t &) = delete;
211 monitor_t &operator=(const monitor_t &) = delete;
212 monitor_t &operator=(monitor_t &&) = delete;
213
219 void listen(zxdg_output_manager_v1 *output_manager);
225 void xdg_name(zxdg_output_v1 *, const char *name);
231 void xdg_description(zxdg_output_v1 *, const char *description);
238 void xdg_position(zxdg_output_v1 *, std::int32_t x, std::int32_t y);
245 void xdg_size(zxdg_output_v1 *, std::int32_t width, std::int32_t height);
246
250 void xdg_done(zxdg_output_v1 *) {}
251
265 void wl_geometry(wl_output *wl_output, std::int32_t x, std::int32_t y, std::int32_t physical_width, std::int32_t physical_height, std::int32_t subpixel, const char *make, const char *model, std::int32_t transform) {}
266
276 void wl_mode(wl_output *wl_output, std::uint32_t flags, std::int32_t width, std::int32_t height, std::int32_t refresh);
277
283 void wl_done(wl_output *wl_output) {}
284
291 void wl_scale(wl_output *wl_output, std::int32_t factor) {}
292
293 wl_output *output;
294 std::string name;
295 std::string description;
297 wl_output_listener wl_listener;
298 zxdg_output_v1_listener xdg_listener;
299 };
300
305 struct bind_t {
306 std::uint32_t id;
307 std::uint32_t version;
308 };
309
310 public:
320
321 interface_t() noexcept;
322
323 interface_t(interface_t &&) = delete;
324 interface_t(const interface_t &) = delete;
325 interface_t &operator=(const interface_t &) = delete;
326 interface_t &operator=(interface_t &&) = delete;
327
333 void listen(wl_registry *registry);
334
341 bool operator[](interface_e bit) const {
342 return interface[bit];
343 }
344
351 void dmabuf_format(zwp_linux_dmabuf_v1 *zwp_linux_dmabuf, uint32_t format);
360 void dmabuf_modifier(zwp_linux_dmabuf_v1 *zwp_linux_dmabuf, uint32_t format, uint32_t modifier_hi, uint32_t modifier_lo);
361
362 std::vector<std::unique_ptr<monitor_t>> monitors;
363 std::map<std::uint32_t, std::vector<std::uint64_t>> supported_modifiers;
364 zwlr_screencopy_manager_v1 *screencopy_manager {nullptr};
365 zwp_linux_dmabuf_v1 *dmabuf_interface {nullptr};
366 zxdg_output_manager_v1 *output_manager {nullptr};
367
368 private:
369 void add_interface(wl_registry *registry, std::uint32_t id, const char *interface, std::uint32_t version);
370 void del_interface(wl_registry *registry, uint32_t id);
371
372 std::bitset<MAX_INTERFACES> interface;
373 wl_registry_listener listener;
374 zwp_linux_dmabuf_v1_listener dmabuf_listener;
375 };
376
380 class display_t {
381 public:
388 int init(const char *display_name = nullptr);
389
390 // Roundtrip with Wayland connection
394 void roundtrip();
395
396 // Wait up to the timeout to read and dispatch new events
397 bool dispatch(std::chrono::milliseconds timeout);
398
404 wl_registry *registry();
405
412 return display_internal.get();
413 }
414
415 private:
416 display_internal_t display_internal;
417 };
418
425 std::vector<std::unique_ptr<monitor_t>> monitors(const char *display_name = nullptr);
431 int init();
432} // namespace wl
433#else
434
435struct wl_output;
436struct zxdg_output_manager_v1;
437
438namespace wl {
439 class monitor_t {
440 public:
441 monitor_t(wl_output *output);
442
443 monitor_t(monitor_t &&) = delete;
444 monitor_t(const monitor_t &) = delete;
445 monitor_t &operator=(const monitor_t &) = delete;
446 monitor_t &operator=(monitor_t &&) = delete;
447
448 void listen(zxdg_output_manager_v1 *output_manager);
449
450 wl_output *output;
451 std::string name;
452 std::string description;
454 };
455
456 inline std::vector<std::unique_ptr<monitor_t>> monitors(const char *display_name = nullptr) {
457 return {};
458 }
459
460 inline int init() {
461 return -1;
462 }
463} // namespace wl
464#endif
Unique pointer wrapper with customizable pointer and deleter types.
Definition utility.h:820
element_type * pointer
Pointer type stored by the unique pointer wrapper.
Definition utility.h:829
pointer get()
Return the currently wrapped value or handle.
Definition utility.h:948
Wayland display connection used to dispatch capture events.
Definition wayland.h:380
wl_registry * registry()
Return the Wayland registry for global discovery.
Definition wayland.cpp:113
void roundtrip()
Flush pending Wayland requests and wait for replies.
Definition wayland.cpp:79
display_internal_t::pointer get()
Return the native Wayland display pointer.
Definition wayland.h:411
bool dispatch(std::chrono::milliseconds timeout)
Waits up to the specified timeout to dispatch new events on the wl_display.
Definition wayland.cpp:88
Listener state for Wayland screencopy frames backed by DMA-BUFs.
Definition wayland.h:52
void linux_dmabuf(zwlr_screencopy_frame_v1 *frame, std::uint32_t format, std::uint32_t width, std::uint32_t height)
Record Linux DMA-BUF parameters advertised for the frame.
Definition wayland.cpp:354
void ready(zwlr_screencopy_frame_v1 *frame, std::uint32_t tv_sec_hi, std::uint32_t tv_sec_lo, std::uint32_t tv_nsec)
Mark the current screencopy frame as ready and store its timestamp.
Definition wayland.cpp:491
status_e status
Current state of the active screencopy request.
Definition wayland.h:163
void buffer_done(zwlr_screencopy_frame_v1 *frame)
Allocate or import the buffer once the compositor finished describing it.
Definition wayland.cpp:433
void damage(zwlr_screencopy_frame_v1 *frame, std::uint32_t x, std::uint32_t y, std::uint32_t width, std::uint32_t height)
Record damaged frame bounds reported by the compositor.
Definition wayland.cpp:533
void flags(zwlr_screencopy_frame_v1 *frame, std::uint32_t flags)
Record frame flags reported by the compositor.
Definition wayland.cpp:367
static void buffer_params_failed(void *data, struct zwp_linux_buffer_params_v1 *params)
Mark DMA-BUF buffer creation as failed.
Definition wayland.cpp:475
frame_t * get_next_frame()
Select the inactive frame slot for the next screencopy request.
Definition wayland.h:159
static void buffer_params_created(void *data, struct zwp_linux_buffer_params_v1 *params, struct wl_buffer *wl_buffer)
Store the Wayland buffer created for a DMA-BUF parameter request.
Definition wayland.cpp:458
void listen(zwlr_screencopy_manager_v1 *screencopy_manager, zwp_linux_dmabuf_v1 *dmabuf_interface, const std::map< std::uint32_t, std::vector< std::uint64_t > > *supported_modifiers, wl_output *output, bool blend_cursor=false)
Start a screencopy request and attach the DMA-BUF listener callbacks.
Definition wayland.cpp:295
void failed(zwlr_screencopy_frame_v1 *frame)
Mark the frame capture as failed.
Definition wayland.cpp:520
frame_t * current_frame
Frame descriptor currently being filled by the compositor.
Definition wayland.h:165
status_e
Capture state for the active screencopy request.
Definition wayland.h:57
@ WAITING
Waiting for a frame.
Definition wayland.h:58
@ READY
Frame is ready.
Definition wayland.h:59
@ REINIT
Reinitialize the frame.
Definition wayland.h:60
void buffer(zwlr_screencopy_frame_v1 *frame, std::uint32_t format, std::uint32_t width, std::uint32_t height, std::uint32_t stride)
Record DMA-BUF buffer parameters from the compositor.
Definition wayland.cpp:339
std::array< frame_t, 2 > frames
Double-buffered frame descriptors.
Definition wayland.h:164
zwlr_screencopy_frame_v1_listener listener
Callback table registered on screencopy frames.
Definition wayland.h:166
Captured Wayland frame metadata and DMA-BUF surface state.
Definition wayland.h:37
egl::surface_descriptor_t sd
DMA-BUF surface descriptor received from the compositor.
Definition wayland.h:45
void destroy()
Release file descriptors and native buffers associated with this frame.
Definition wayland.cpp:541
std::optional< std::chrono::steady_clock::time_point > frame_timestamp
Capture timestamp associated with the frame.
Definition wayland.h:46
Wayland registry state for screencopy, DMA-BUF, and output globals.
Definition wayland.h:304
std::vector< std::unique_ptr< monitor_t > > monitors
Outputs discovered from the Wayland registry.
Definition wayland.h:362
void listen(wl_registry *registry)
Discover compositor globals from the Wayland registry.
Definition wayland.cpp:193
zwlr_screencopy_manager_v1 * screencopy_manager
WLR screencopy global used to request frames.
Definition wayland.h:364
interface_e
Wayland globals required by the WLR capture backend.
Definition wayland.h:314
@ WLR_EXPORT_DMABUF
screencopy manager
Definition wayland.h:316
@ LINUX_DMABUF
linux-dmabuf protocol
Definition wayland.h:317
@ MAX_INTERFACES
Maximum number of interfaces.
Definition wayland.h:318
@ XDG_OUTPUT
xdg-output
Definition wayland.h:315
zwp_linux_dmabuf_v1 * dmabuf_interface
Linux DMA-BUF global used to allocate frame buffers.
Definition wayland.h:365
void dmabuf_modifier(zwp_linux_dmabuf_v1 *zwp_linux_dmabuf, uint32_t format, uint32_t modifier_hi, uint32_t modifier_lo)
Record a DMA-BUF format modifier advertised by the compositor.
Definition wayland.cpp:200
std::map< std::uint32_t, std::vector< std::uint64_t > > supported_modifiers
DRM format modifiers grouped by format.
Definition wayland.h:363
void dmabuf_format(zwp_linux_dmabuf_v1 *zwp_linux_dmabuf, uint32_t format)
Record a DMA-BUF format advertised by the compositor.
Definition wayland.cpp:197
zxdg_output_manager_v1 * output_manager
xdg-output global used to query monitor names and sizes.
Definition wayland.h:366
Wayland output metadata used to match a configured display name.
Definition wayland.h:200
std::string name
xdg-output name used for display selection.
Definition wayland.h:294
void xdg_description(zxdg_output_v1 *, const char *description)
Store the xdg-output human-readable monitor description.
Definition wayland.cpp:140
void xdg_done(zxdg_output_v1 *)
Acknowledge completion of an xdg-output metadata update.
Definition wayland.h:250
wl_output * output
Wayland output associated with this monitor.
Definition wayland.h:293
void wl_done(wl_output *wl_output)
Acknowledge completion of a wl-output metadata update.
Definition wayland.h:283
zxdg_output_v1_listener xdg_listener
Callback table for xdg-output events.
Definition wayland.h:298
void wl_geometry(wl_output *wl_output, std::int32_t x, std::int32_t y, std::int32_t physical_width, std::int32_t physical_height, std::int32_t subpixel, const char *make, const char *model, std::int32_t transform)
Receive physical wl-output geometry metadata.
Definition wayland.h:265
wl_output_listener wl_listener
Callback table for wl-output events.
Definition wayland.h:297
void xdg_name(zxdg_output_v1 *, const char *name)
Store the xdg-output logical monitor name.
Definition wayland.cpp:134
std::string description
xdg-output description used for logs and UI.
Definition wayland.h:295
void listen(zxdg_output_manager_v1 *output_manager)
Attach xdg-output and wl-output listeners for this monitor.
Definition wayland.cpp:172
void xdg_size(zxdg_output_v1 *, std::int32_t width, std::int32_t height)
Store the logical monitor size reported by xdg-output.
Definition wayland.cpp:153
void wl_mode(wl_output *wl_output, std::uint32_t flags, std::int32_t width, std::int32_t height, std::int32_t refresh)
Store the active pixel mode reported by wl-output.
Definition wayland.cpp:159
monitor_t(wl_output *output)
Track a Wayland output and its advertised modes.
Definition wayland.cpp:117
void wl_scale(wl_output *wl_output, std::int32_t factor)
Receive the wl-output scale factor.
Definition wayland.h:291
platf::touch_port_t viewport
Logical monitor bounds used to scale absolute input.
Definition wayland.h:296
void xdg_position(zxdg_output_v1 *, std::int32_t x, std::int32_t y)
Store the logical monitor position reported by xdg-output.
Definition wayland.cpp:146
Declarations for graphics related functions.
Definition wayland.cpp:35
std::vector< std::unique_ptr< monitor_t > > monitors(const char *display_name)
Refresh the monitor list reported by the display server.
Definition wayland.cpp:559
int init()
Initialize Wayland registry interfaces required for capture.
Definition wayland.cpp:594
EGL surface descriptor used to import a captured DMA-BUF.
Definition graphics.h:496
Touchscreen coordinate bounds used to scale absolute input.
Definition common.h:361