screencasting: implement intefraces to create dmabuf textures
This commit is contained in:
parent
38eb72efe3
commit
42e543c5b2
8 changed files with 173 additions and 3 deletions
|
@ -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()
|
||||
|
|
|
@ -34,6 +34,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#if HAVE_GBM
|
||||
#include "egl_gbm_backend.h"
|
||||
#include <gbm.h>
|
||||
#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
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
81
plugins/platforms/drm/gbm_dmabuf.cpp
Normal file
81
plugins/platforms/drm/gbm_dmabuf.cpp
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright © 2020 Aleix Pol Gonzalez <aleixpol@kde.org>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors:
|
||||
* Aleix Pol Gonzalez <aleixpol@kde.org>
|
||||
*/
|
||||
|
||||
#include "gbm_dmabuf.h"
|
||||
#include "kwineglimagetexture.h"
|
||||
#include "platformsupport/scenes/opengl/drm_fourcc.h"
|
||||
#include "main.h"
|
||||
#include "platform.h"
|
||||
#include <unistd.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
52
plugins/platforms/drm/gbm_dmabuf.h
Normal file
52
plugins/platforms/drm/gbm_dmabuf.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright © 2020 Aleix Pol Gonzalez <aleixpol@kde.org>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors:
|
||||
* Aleix Pol Gonzalez <aleixpol@kde.org>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "dmabuftexture.h"
|
||||
#include <gbm.h>
|
||||
#include <QSize>
|
||||
#include <epoxy/egl.h>
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
|
@ -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(
|
||||
|
|
|
@ -35,6 +35,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "pointer_input.h"
|
||||
#include "screens.h"
|
||||
#include "wayland_server.h"
|
||||
#include "../drm/gbm_dmabuf.h"
|
||||
|
||||
#include <config-kwin.h>
|
||||
|
||||
|
@ -64,6 +65,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
#include <linux/input.h>
|
||||
#include <wayland-cursor.h>
|
||||
#include <unistd.h>
|
||||
#include <gbm.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue