Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions src/platform/linux/wayland.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,13 +176,25 @@ namespace wl {
listener {
&CLASS_CALL(interface_t, add_interface),
&CLASS_CALL(interface_t, del_interface)
},
dmabuf_listener {
&CLASS_CALL(interface_t, dmabuf_format),
&CLASS_CALL(interface_t, dmabuf_modifier)
} {
}

void interface_t::listen(wl_registry *registry) {
wl_registry_add_listener(registry, &listener, this);
}

void interface_t::dmabuf_format(zwp_linux_dmabuf_v1 *zwp_linux_dmabuf, uint32_t format) {
}

void interface_t::dmabuf_modifier(zwp_linux_dmabuf_v1 *zwp_linux_dmabuf, uint32_t format, uint32_t modifier_hi, uint32_t modifier_lo) {
uint64_t modifier = ((uint64_t)modifier_hi << 32) | modifier_lo;
supported_modifiers[format].push_back(modifier);
}

void interface_t::add_interface(
wl_registry *registry,
std::uint32_t id,
Expand Down Expand Up @@ -210,7 +222,8 @@ namespace wl {
this->interface[WLR_EXPORT_DMABUF] = true;
} else if (!std::strcmp(interface, zwp_linux_dmabuf_v1_interface.name)) {
BOOST_LOG(info) << "[wayland] Found interface: "sv << interface << '(' << id << ") version "sv << version;
dmabuf_interface = (zwp_linux_dmabuf_v1 *) wl_registry_bind(registry, id, &zwp_linux_dmabuf_v1_interface, version);
dmabuf_interface = (zwp_linux_dmabuf_v1 *) wl_registry_bind(registry, id, &zwp_linux_dmabuf_v1_interface, std::min(version, 3u));
zwp_linux_dmabuf_v1_add_listener(dmabuf_interface, &dmabuf_listener, this);

this->interface[LINUX_DMABUF] = true;
}
Expand Down Expand Up @@ -275,10 +288,12 @@ namespace wl {
void dmabuf_t::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
) {
this->dmabuf_interface = dmabuf_interface;
this->supported_modifiers = supported_modifiers;
// Reset state
shm_info.supported = false;
dmabuf_info.supported = false;
Expand Down Expand Up @@ -357,7 +372,17 @@ namespace wl {
}

// Create GBM buffer
current_bo = gbm_bo_create(gbm_device, dmabuf_info.width, dmabuf_info.height, dmabuf_info.format, GBM_BO_USE_RENDERING);
if (supported_modifiers) {
auto it = supported_modifiers->find(dmabuf_info.format);
if (it != supported_modifiers->end() && !it->second.empty()) {
current_bo = gbm_bo_create_with_modifiers(gbm_device, dmabuf_info.width, dmabuf_info.height, dmabuf_info.format, it->second.data(), it->second.size());
}
}

if (!current_bo) {
current_bo = gbm_bo_create(gbm_device, dmabuf_info.width, dmabuf_info.height, dmabuf_info.format, GBM_BO_USE_RENDERING);
}

if (!current_bo) {
BOOST_LOG(error) << "Failed to create GBM buffer"sv;
zwlr_screencopy_frame_v1_destroy(frame);
Expand Down
11 changes: 10 additions & 1 deletion src/platform/linux/wayland.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

// standard includes
#include <bitset>
#include <cstdint>
#include <map>
#include <vector>

#ifdef SUNSHINE_BUILD_WAYLAND
#include <linux-dmabuf-unstable-v1.h>
Expand Down Expand Up @@ -50,7 +53,7 @@ namespace wl {
dmabuf_t &operator=(const dmabuf_t &) = delete;
dmabuf_t &operator=(dmabuf_t &&) = delete;

void listen(zwlr_screencopy_manager_v1 *screencopy_manager, zwp_linux_dmabuf_v1 *dmabuf_interface, wl_output *output, bool blend_cursor = false);
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);
static void buffer_params_created(void *data, struct zwp_linux_buffer_params_v1 *params, struct wl_buffer *wl_buffer);
static void buffer_params_failed(void *data, struct zwp_linux_buffer_params_v1 *params);
void buffer(zwlr_screencopy_frame_v1 *frame, std::uint32_t format, std::uint32_t width, std::uint32_t height, std::uint32_t stride);
Expand All @@ -76,6 +79,7 @@ namespace wl {
void create_and_copy_dmabuf(zwlr_screencopy_frame_v1 *frame);

zwp_linux_dmabuf_v1 *dmabuf_interface {nullptr};
const std::map<std::uint32_t, std::vector<std::uint64_t>> *supported_modifiers {nullptr};

struct {
bool supported {false};
Expand Down Expand Up @@ -158,7 +162,11 @@ namespace wl {
return interface[bit];
}

void dmabuf_format(zwp_linux_dmabuf_v1 *zwp_linux_dmabuf, uint32_t format);
void dmabuf_modifier(zwp_linux_dmabuf_v1 *zwp_linux_dmabuf, uint32_t format, uint32_t modifier_hi, uint32_t modifier_lo);

std::vector<std::unique_ptr<monitor_t>> monitors;
std::map<std::uint32_t, std::vector<std::uint64_t>> supported_modifiers;
zwlr_screencopy_manager_v1 *screencopy_manager {nullptr};
zwp_linux_dmabuf_v1 *dmabuf_interface {nullptr};
zxdg_output_manager_v1 *output_manager {nullptr};
Expand All @@ -169,6 +177,7 @@ namespace wl {

std::bitset<MAX_INTERFACES> interface;
wl_registry_listener listener;
zwp_linux_dmabuf_v1_listener dmabuf_listener;
};

class display_t {
Expand Down
2 changes: 1 addition & 1 deletion src/platform/linux/wlgrab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ namespace wl {
auto to = std::chrono::steady_clock::now() + timeout;

// Dispatch events until we get a new frame or the timeout expires
dmabuf.listen(interface.screencopy_manager, interface.dmabuf_interface, output, cursor);
dmabuf.listen(interface.screencopy_manager, interface.dmabuf_interface, &interface.supported_modifiers, output, cursor);
do {
auto remaining_time_ms = std::chrono::duration_cast<std::chrono::milliseconds>(to - std::chrono::steady_clock::now());
if (remaining_time_ms.count() < 0 || !display.dispatch(remaining_time_ms)) {
Expand Down