mirror of
https://github.com/LizardByte/Sunshine.git
synced 2026-08-07 18:36:34 +00:00
fix(wayland): support DMA-BUF modifiers for wlroots capture (#5132)
This commit is contained in:
@@ -176,6 +176,10 @@ 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)
|
||||
} {
|
||||
}
|
||||
|
||||
@@ -183,6 +187,14 @@ namespace wl {
|
||||
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,
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
|
||||
// standard includes
|
||||
#include <bitset>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#ifdef SUNSHINE_BUILD_WAYLAND
|
||||
#include <linux-dmabuf-unstable-v1.h>
|
||||
@@ -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);
|
||||
@@ -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};
|
||||
@@ -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};
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
Reference in New Issue
Block a user