diff --git a/plugins/platforms/drm/CMakeLists.txt b/plugins/platforms/drm/CMakeLists.txt
index eff0f8e938..9a4fd4d2dc 100644
--- a/plugins/platforms/drm/CMakeLists.txt
+++ b/plugins/platforms/drm/CMakeLists.txt
@@ -18,6 +18,7 @@ if (HAVE_GBM)
egl_gbm_backend.cpp
drm_buffer_gbm.cpp
gbm_surface.cpp
+ gbm_dmabuf.cpp
remoteaccess_manager.cpp
)
endif()
diff --git a/plugins/platforms/drm/drm_backend.cpp b/plugins/platforms/drm/drm_backend.cpp
index 97f1b3f653..3e444ed36d 100644
--- a/plugins/platforms/drm/drm_backend.cpp
+++ b/plugins/platforms/drm/drm_backend.cpp
@@ -34,6 +34,7 @@ along with this program. If not, see .
#if HAVE_GBM
#include "egl_gbm_backend.h"
#include
+#include "gbm_dmabuf.h"
#endif
#if HAVE_EGL_STREAMS
#include "egl_stream_backend.h"
@@ -818,4 +819,13 @@ QString DrmBackend::supportInformation() const
return supportInfo;
}
+DmaBufTexture *DrmBackend::createDmaBufTexture(const QSize &size)
+{
+#if HAVE_GBM
+ return GbmDmaBuf::createBuffer(size, m_gbmDevice);
+#else
+ return nullptr;
+#endif
+}
+
}
diff --git a/plugins/platforms/drm/drm_backend.h b/plugins/platforms/drm/drm_backend.h
index 93333279a6..63ddecdf72 100644
--- a/plugins/platforms/drm/drm_backend.h
+++ b/plugins/platforms/drm/drm_backend.h
@@ -55,7 +55,6 @@ class DrmConnector;
class GbmSurface;
class Cursor;
-
class KWIN_EXPORT DrmBackend : public Platform
{
Q_OBJECT
@@ -68,6 +67,7 @@ public:
Screens *createScreens(QObject *parent = nullptr) override;
QPainterBackend *createQPainterBackend() override;
OpenGLBackend* createOpenGLBackend() override;
+ DmaBufTexture *createDmaBufTexture(const QSize &size) override;
void init() override;
void prepareShutdown() override;
diff --git a/plugins/platforms/drm/gbm_dmabuf.cpp b/plugins/platforms/drm/gbm_dmabuf.cpp
new file mode 100644
index 0000000000..535eb21845
--- /dev/null
+++ b/plugins/platforms/drm/gbm_dmabuf.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright © 2020 Aleix Pol Gonzalez
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see .
+ *
+ * Authors:
+ * Aleix Pol Gonzalez
+ */
+
+#include "gbm_dmabuf.h"
+#include "kwineglimagetexture.h"
+#include "platformsupport/scenes/opengl/drm_fourcc.h"
+#include "main.h"
+#include "platform.h"
+#include
+
+namespace KWin
+{
+
+GbmDmaBuf::GbmDmaBuf(GLTexture *texture, gbm_bo *bo, int fd)
+ : DmaBufTexture(texture)
+ , m_bo(bo)
+ , m_fd(fd)
+{}
+
+GbmDmaBuf::~GbmDmaBuf()
+{
+ m_texture.reset(nullptr);
+
+ close(m_fd);
+ gbm_bo_destroy(m_bo);
+}
+
+
+KWin::GbmDmaBuf *GbmDmaBuf::createBuffer(const QSize &size, gbm_device *device)
+{
+ auto bo = gbm_bo_create(device, size.width(), size.height(), GBM_BO_FORMAT_ARGB8888, GBM_BO_USE_RENDERING | GBM_BO_USE_LINEAR);
+
+ if (!bo) {
+ gbm_bo_destroy(bo);
+ return nullptr;
+ }
+
+ const int fd = gbm_bo_get_fd(bo);
+ if (fd < 0) {
+ gbm_bo_destroy(bo);
+ return nullptr;
+ }
+
+ EGLint importAttributes[] = {
+ EGL_WIDTH, EGLint(gbm_bo_get_width(bo)),
+ EGL_HEIGHT, EGLint(gbm_bo_get_height(bo)),
+ EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,
+ EGL_DMA_BUF_PLANE0_FD_EXT, fd,
+ EGL_DMA_BUF_PLANE0_OFFSET_EXT, EGLint(gbm_bo_get_offset(bo, 0)),
+ EGL_DMA_BUF_PLANE0_PITCH_EXT, EGLint(gbm_bo_get_stride(bo)),
+ EGL_NONE
+ };
+
+ EGLDisplay display = kwinApp()->platform()->sceneEglDisplay();
+ EGLImageKHR destinationImage = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, nullptr, importAttributes);
+ if (destinationImage == EGL_NO_IMAGE_KHR) {
+ return nullptr;
+ }
+
+ return new GbmDmaBuf(new KWin::EGLImageTexture(display, destinationImage, GL_RGBA8, size), bo, fd);
+}
+
+}
+
diff --git a/plugins/platforms/drm/gbm_dmabuf.h b/plugins/platforms/drm/gbm_dmabuf.h
new file mode 100644
index 0000000000..a22f2aeeeb
--- /dev/null
+++ b/plugins/platforms/drm/gbm_dmabuf.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright © 2020 Aleix Pol Gonzalez
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see .
+ *
+ * Authors:
+ * Aleix Pol Gonzalez
+ */
+
+#pragma once
+
+#include "dmabuftexture.h"
+#include
+#include
+#include
+
+namespace KWin
+{
+
+class GbmDmaBuf : public DmaBufTexture
+{
+public:
+ ~GbmDmaBuf();
+
+ int fd() const override
+ {
+ return m_fd;
+ }
+ quint32 stride() const override {
+ return gbm_bo_get_stride(m_bo);
+ }
+
+ static GbmDmaBuf *createBuffer(const QSize &size, gbm_device *device);
+
+private:
+ GbmDmaBuf(GLTexture *texture, gbm_bo *bo, int fd);
+ struct gbm_bo *const m_bo;
+ const int m_fd;
+};
+
+}
diff --git a/plugins/platforms/wayland/CMakeLists.txt b/plugins/platforms/wayland/CMakeLists.txt
index 13320b4dc4..700b5514c2 100644
--- a/plugins/platforms/wayland/CMakeLists.txt
+++ b/plugins/platforms/wayland/CMakeLists.txt
@@ -3,6 +3,7 @@ set(WAYLAND_BACKEND_SOURCES
scene_qpainter_wayland_backend.cpp
wayland_backend.cpp
wayland_output.cpp
+ ../drm/gbm_dmabuf.cpp
)
if (HAVE_WAYLAND_EGL)
@@ -15,7 +16,7 @@ set_target_properties(KWinWaylandWaylandBackend PROPERTIES LIBRARY_OUTPUT_DIRECT
target_link_libraries(KWinWaylandWaylandBackend kwin KF5::WaylandClient SceneQPainterBackend)
if (HAVE_WAYLAND_EGL)
- target_link_libraries(KWinWaylandWaylandBackend SceneOpenGLBackend Wayland::Egl)
+ target_link_libraries(KWinWaylandWaylandBackend SceneOpenGLBackend Wayland::Egl gbm::gbm)
endif()
install(
diff --git a/plugins/platforms/wayland/wayland_backend.cpp b/plugins/platforms/wayland/wayland_backend.cpp
index 804dc8c9d4..bd8bffd7fd 100644
--- a/plugins/platforms/wayland/wayland_backend.cpp
+++ b/plugins/platforms/wayland/wayland_backend.cpp
@@ -35,6 +35,7 @@ along with this program. If not, see .
#include "pointer_input.h"
#include "screens.h"
#include "wayland_server.h"
+#include "../drm/gbm_dmabuf.h"
#include
@@ -64,6 +65,9 @@ along with this program. If not, see .
#include
#include
+#include
+#include
+#include
namespace KWin
{
@@ -451,8 +455,18 @@ WaylandBackend::WaylandBackend(QObject *parent)
, m_connectionThreadObject(new ConnectionThread(nullptr))
, m_connectionThread(nullptr)
{
- connect(this, &WaylandBackend::connectionFailed, this, &WaylandBackend::initFailed);
supportsOutputChanges();
+ connect(this, &WaylandBackend::connectionFailed, this, &WaylandBackend::initFailed);
+
+
+ char const *drm_render_node = "/dev/dri/renderD128";
+ m_drm_fd = open(drm_render_node, O_RDWR);
+ if (m_drm_fd < 0) {
+ qCWarning(KWIN_WAYLAND_BACKEND) << "Failed to open drm render node" << drm_render_node;
+ m_gbmDevice = nullptr;
+ return;
+ }
+ m_gbmDevice = gbm_create_device(m_drm_fd);
}
WaylandBackend::~WaylandBackend()
@@ -477,6 +491,8 @@ WaylandBackend::~WaylandBackend()
m_connectionThread->quit();
m_connectionThread->wait();
m_connectionThreadObject->deleteLater();
+ gbm_device_destroy(m_gbmDevice);
+ close(m_drm_fd);
qCDebug(KWIN_WAYLAND_BACKEND) << "Destroyed Wayland display";
}
@@ -835,6 +851,11 @@ Outputs WaylandBackend::enabledOutputs() const
return m_outputs;
}
+DmaBufTexture *WaylandBackend::createDmaBufTexture(const QSize& size)
+{
+ return GbmDmaBuf::createBuffer(size, m_gbmDevice);
+}
+
}
} // KWin
diff --git a/plugins/platforms/wayland/wayland_backend.h b/plugins/platforms/wayland/wayland_backend.h
index e9cda4b139..dfdec642d0 100644
--- a/plugins/platforms/wayland/wayland_backend.h
+++ b/plugins/platforms/wayland/wayland_backend.h
@@ -36,6 +36,7 @@ struct wl_buffer;
struct wl_display;
struct wl_event_queue;
struct wl_seat;
+struct gbm_device;
namespace KWayland
{
@@ -184,6 +185,7 @@ public:
Screens *createScreens(QObject *parent = nullptr) override;
OpenGLBackend *createOpenGLBackend() override;
QPainterBackend *createQPainterBackend() override;
+ DmaBufTexture *createDmaBufTexture(const QSize &size) override;
void flush();
@@ -248,6 +250,8 @@ private:
WaylandCursor *m_waylandCursor = nullptr;
bool m_pointerLockRequested = false;
+ int m_drmFileDescriptor = 0;
+ gbm_device *m_gbmDevice;
};
inline