[plasma/kwin] /: wayland: implement linux dmabuf version 6
Xaver Hugl <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit e0cce2fd1f62f6a01e714f4212ce03fee2b2a8f0 by Xaver Hugl.
Committed on 28/07/2026 at 10:59.
Pushed by zamundaaa into branch 'master'.
wayland: implement linux dmabuf version 6
This ports the protocol to version 6, but there are no functional changes yet.
M +1 -1 CMakeLists.txt
M +1 -1 src/wayland-client/linuxdmabuf.cpp
M +33 -20 src/wayland/linuxdmabufv1clientbuffer.cpp
M +2 -0 src/wayland/linuxdmabufv1clientbuffer_p.h
https://invent.kde.org/plasma/kwin/-/commit/e0cce2fd1f62f6a01e714f4212ce03fee2b2a8f0
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8788c3f14e4..6d77a57976e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -211,7 +211,7 @@ if (Wayland_VERSION VERSION_GREATER_EQUAL "1.25.91")
add_compile_definitions(HAVE_ACK_GLOBAL_REMOVE=1)
endif()
-find_package(WaylandProtocols 1.48)
+find_package(WaylandProtocols 1.49)
set_package_properties(WaylandProtocols PROPERTIES
TYPE REQUIRED
PURPOSE "Collection of Wayland protocols that add functionality not available in the Wayland core protocol"
diff --git a/src/wayland-client/linuxdmabuf.cpp b/src/wayland-client/linuxdmabuf.cpp
index 17d3d4e4b68..5b323f68be0 100644
--- a/src/wayland-client/linuxdmabuf.cpp
+++ b/src/wayland-client/linuxdmabuf.cpp
@@ -135,7 +135,7 @@ void LinuxDmabufFeedbackV1::tranche_flags(void *data, zwp_linux_dmabuf_feedback_
LinuxDmabufV1::LinuxDmabufV1(wl_registry *registry, uint32_t name, uint32_t version)
{
- m_dmabuf = static_cast<zwp_linux_dmabuf_v1 *>(wl_registry_bind(registry, name, &zwp_linux_dmabuf_v1_interface, version));
+ m_dmabuf = static_cast<zwp_linux_dmabuf_v1 *>(wl_registry_bind(registry, name, &zwp_linux_dmabuf_v1_interface, std::min(4u, version)));
static const struct zwp_linux_dmabuf_v1_listener dmabufListener = {
.format = format,
diff --git a/src/wayland/linuxdmabufv1clientbuffer.cpp b/src/wayland/linuxdmabufv1clientbuffer.cpp
index 8e5bab213f1..ae4935e8106 100644
--- a/src/wayland/linuxdmabufv1clientbuffer.cpp
+++ b/src/wayland/linuxdmabufv1clientbuffer.cpp
@@ -28,7 +28,7 @@
namespace KWin
{
-static const int s_version = 5;
+static const int s_version = 6;
LinuxDmaBufV1ClientBufferIntegrationPrivate::LinuxDmaBufV1ClientBufferIntegrationPrivate(LinuxDmaBufV1ClientBufferIntegration *q, Display *display)
: QtWaylandServer::zwp_linux_dmabuf_v1(*display, s_version)
@@ -103,7 +103,9 @@ LinuxDmaBufParamsV1::LinuxDmaBufParamsV1(LinuxDmaBufV1ClientBufferIntegration *i
: QtWaylandServer::zwp_linux_buffer_params_v1(resource)
, m_integration(integration)
{
- m_attrs.device = integration->mainDevice(wl_resource_get_client(resource));
+ if (wl_resource_get_version(resource) < ZWP_LINUX_BUFFER_PARAMS_V1_SET_SAMPLING_DEVICE_SINCE_VERSION) {
+ m_targetDevice = integration->mainDevice(wl_resource_get_client(resource));
+ }
}
void LinuxDmaBufParamsV1::zwp_linux_buffer_params_v1_destroy_resource(Resource *resource)
@@ -174,6 +176,7 @@ void LinuxDmaBufParamsV1::zwp_linux_buffer_params_v1_create(Resource *resource,
m_attrs.width = width;
m_attrs.height = height;
m_attrs.format = format;
+ m_attrs.device = m_targetDevice.value_or(m_integration->mainDevice(resource->client()));
auto clientBuffer = new LinuxDmaBufV1ClientBuffer(std::move(m_attrs));
if (!renderBackend->testImportBuffer(clientBuffer)) {
@@ -225,6 +228,7 @@ void LinuxDmaBufParamsV1::zwp_linux_buffer_params_v1_create_immed(Resource *reso
m_attrs.width = width;
m_attrs.height = height;
m_attrs.format = format;
+ m_attrs.device = m_targetDevice.value_or(m_integration->mainDevice(resource->client()));
auto clientBuffer = new LinuxDmaBufV1ClientBuffer(std::move(m_attrs));
if (!renderBackend->testImportBuffer(clientBuffer)) {
@@ -243,6 +247,15 @@ void LinuxDmaBufParamsV1::zwp_linux_buffer_params_v1_create_immed(Resource *reso
clientBuffer->initialize(bufferResource);
}
+void LinuxDmaBufParamsV1::zwp_linux_buffer_params_v1_set_sampling_device(Resource *resource, wl_array *device)
+{
+ if (device->size < sizeof(dev_t)) {
+ wl_resource_post_error(resource->handle, error_invalid_dev_t_size, "Incomplete dev_t sent!");
+ return;
+ }
+ m_targetDevice = *reinterpret_cast<dev_t *>(device->data);
+}
+
bool LinuxDmaBufParamsV1::test(Resource *resource, uint32_t width, uint32_t height)
{
if (Q_UNLIKELY(!m_attrs.planeCount)) {
@@ -461,17 +474,7 @@ QList<LinuxDmaBufV1Feedback::Tranche> LinuxDmaBufV1Feedback::createScanoutTranch
if (!scanoutDevice) {
return ret;
}
- RenderDevice *compatibleWithScanout = GpuManager::self()->compatibleRenderDevice(scanoutDevice);
for (const auto &tranche : tranches) {
- // for now, limit scanout tranches to the main device
- // TODO relax this with dmabuf v6
- if (tranche.device != mainDevice) {
- continue;
- }
- if (compatibleWithScanout && tranche.device != compatibleWithScanout->deviceId()) {
- // limit scanout tranches to devices we can also sample from
- continue;
- }
LinuxDmaBufV1Feedback::Tranche scanoutTranche;
for (auto it = tranche.formatTable.constBegin(); it != tranche.formatTable.constEnd(); it++) {
const uint32_t format = it.key();
@@ -485,7 +488,7 @@ QList<LinuxDmaBufV1Feedback::Tranche> LinuxDmaBufV1Feedback::createScanoutTranch
}
if (!scanoutTranche.formatTable.isEmpty()) {
scanoutTranche.device = scanoutDevice->deviceId();
- scanoutTranche.flags = tranche.flags | LinuxDmaBufV1Feedback::TrancheFlag::Scanout;
+ scanoutTranche.flags = LinuxDmaBufV1Feedback::TrancheFlag::Scanout;
ret.push_back(scanoutTranche);
}
}
@@ -507,10 +510,19 @@ void LinuxDmaBufV1FeedbackPrivate::send(Resource *resource)
{
const dev_t mainDevice = m_bufferintegration->q->mainDevice(resource->client());
send_format_table(resource->handle, m_bufferintegration->table->file.fd(), m_bufferintegration->table->file.size());
- QByteArray bytes;
- bytes.append(reinterpret_cast<const char *>(&mainDevice), sizeof(dev_t));
- send_main_device(resource->handle, bytes);
- const auto sendTranche = [this, resource](const LinuxDmaBufV1Feedback::Tranche &tranche) {
+ if (resource->version() < ZWP_LINUX_BUFFER_PARAMS_V1_SET_SAMPLING_DEVICE_SINCE_VERSION) {
+ QByteArray bytes;
+ bytes.append(reinterpret_cast<const char *>(&mainDevice), sizeof(dev_t));
+ send_main_device(resource->handle, bytes);
+ }
+ const auto sendTranche = [this, resource, mainDevice](const LinuxDmaBufV1Feedback::Tranche &tranche) {
+ const bool supportsSamplingFlag = resource->version() >= ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SAMPLING_SINCE_VERSION;
+ if (!supportsSamplingFlag
+ && tranche.flags == LinuxDmaBufV1Feedback::TrancheFlag::Sampling
+ && tranche.device != mainDevice) {
+ // dmabuf v5 only supports the main device for sampling
+ return;
+ }
QByteArray targetDevice;
targetDevice.append(reinterpret_cast<const char *>(&tranche.device), sizeof(dev_t));
QByteArray indices;
@@ -527,6 +539,10 @@ void LinuxDmaBufV1FeedbackPrivate::send(Resource *resource)
if (tranche.flags & LinuxDmaBufV1Feedback::TrancheFlag::Scanout) {
flags |= tranche_flags_scanout;
}
+ if (resource->version() >= ZWP_LINUX_BUFFER_PARAMS_V1_SET_SAMPLING_DEVICE_SINCE_VERSION
+ && (tranche.flags & LinuxDmaBufV1Feedback::TrancheFlag::Sampling)) {
+ flags |= tranche_flags_sampling;
+ }
send_tranche_flags(resource->handle, flags);
send_tranche_done(resource->handle);
};
@@ -534,9 +550,6 @@ void LinuxDmaBufV1FeedbackPrivate::send(Resource *resource)
sendTranche(tranche);
}
for (const auto &tranche : std::as_const(m_bufferintegration->defaultTranches)) {
- if (tranche.device != mainDevice) {
- continue;
- }
sendTranche(tranche);
}
send_done(resource->handle);
diff --git a/src/wayland/linuxdmabufv1clientbuffer_p.h b/src/wayland/linuxdmabufv1clientbuffer_p.h
index 7fc4fcae955..c3efedfa2e2 100644
--- a/src/wayland/linuxdmabufv1clientbuffer_p.h
+++ b/src/wayland/linuxdmabufv1clientbuffer_p.h
@@ -70,6 +70,7 @@ protected:
void zwp_linux_buffer_params_v1_create(Resource *resource, int32_t width, int32_t height, uint32_t format, uint32_t flags) override;
void
zwp_linux_buffer_params_v1_create_immed(Resource *resource, uint32_t buffer_id, int32_t width, int32_t height, uint32_t format, uint32_t flags) override;
+ void zwp_linux_buffer_params_v1_set_sampling_device(Resource *resource, wl_array *device) override;
private:
bool test(Resource *resource, uint32_t width, uint32_t height);
@@ -77,6 +78,7 @@ private:
LinuxDmaBufV1ClientBufferIntegration *m_integration;
DmaBufAttributes m_attrs;
std::array<uint64_t, 4> m_modifiers;
+ std::optional<dev_t> m_targetDevice;
bool m_isUsed = false;
};