screencasting: implement intefraces to create dmabuf textures

icc-effect-master
Aleix Pol 2020-07-22 19:31:23 +02:00
parent 38eb72efe3
commit 42e543c5b2
8 changed files with 173 additions and 3 deletions

View File

@ -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()

View File

@ -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
}
}

View File

@ -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;

View 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);
}
}

View 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;
};
}

View File

@ -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(

View File

@ -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

View File

@ -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