wayland: port linux drm syncobj from RenderBackend to DrmDevice

This commit is contained in:
Xaver Hugl 2024-05-07 16:03:14 +02:00
parent 0f41239515
commit 2e9e6893bb
11 changed files with 22 additions and 60 deletions

View file

@ -181,21 +181,6 @@ DrmGpu *EglGbmBackend::gpu() const
return m_backend->primaryGpu();
}
bool EglGbmBackend::supportsTimelines() const
{
return m_backend->primaryGpu()->syncObjTimelinesSupported();
}
std::unique_ptr<SyncTimeline> EglGbmBackend::importTimeline(FileDescriptor &&syncObjFd)
{
uint32_t handle = 0;
if (drmSyncobjFDToHandle(m_backend->primaryGpu()->fd(), syncObjFd.get(), &handle) != 0) {
qCWarning(KWIN_DRM) << "importing syncobj timeline failed!" << strerror(errno);
return nullptr;
}
return std::make_unique<SyncTimeline>(m_backend->primaryGpu()->fd(), handle);
}
} // namespace KWin
#include "moc_drm_egl_backend.cpp"

View file

@ -61,9 +61,6 @@ public:
EglDisplay *displayForGpu(DrmGpu *gpu);
std::shared_ptr<EglContext> contextForGpu(DrmGpu *gpu);
bool supportsTimelines() const override;
std::unique_ptr<SyncTimeline> importTimeline(FileDescriptor &&syncObjFd) override;
private:
bool initializeEgl();
bool initRenderingContext();

View file

@ -75,9 +75,6 @@ DrmGpu::DrmGpu(DrmBackend *backend, int fd, std::unique_ptr<DrmDevice> &&device)
m_addFB2ModifiersSupported = drmGetCap(fd, DRM_CAP_ADDFB2_MODIFIERS, &capability) == 0 && capability == 1;
qCDebug(KWIN_DRM) << "drmModeAddFB2WithModifiers is" << (m_addFB2ModifiersSupported ? "supported" : "not supported") << "on GPU" << this;
m_supportsSyncTimelines = drmGetCap(fd, DRM_CAP_SYNCOBJ_TIMELINE, &capability) == 0 && capability == 1;
qCDebug(KWIN_DRM) << "sync obj timelines are" << (m_supportsSyncTimelines ? "supported" : "not supported") << "on GPU" << this;
// find out what driver this kms device is using
DrmUniquePtr<drmVersion> version(drmGetVersion(fd));
m_isI915 = strstr(version->name, "i915");
@ -678,11 +675,6 @@ bool DrmGpu::asyncPageflipSupported() const
return m_asyncPageflipSupported;
}
bool DrmGpu::syncObjTimelinesSupported() const
{
return m_supportsSyncTimelines;
}
bool DrmGpu::isI915() const
{
return m_isI915;

View file

@ -75,7 +75,6 @@ public:
bool atomicModeSetting() const;
bool addFB2ModifiersSupported() const;
bool asyncPageflipSupported() const;
bool syncObjTimelinesSupported() const;
bool isI915() const;
bool isNVidia() const;
bool isAmdgpu() const;
@ -145,7 +144,6 @@ private:
bool m_isRemoved = false;
bool m_isActive = true;
bool m_forceModeset = false;
bool m_supportsSyncTimelines = false;
clockid_t m_presentationClock;
std::unique_ptr<EglDisplay> m_eglDisplay;
DrmBackend *const m_platform;

View file

@ -25,6 +25,8 @@ DrmDevice::DrmDevice(const QString &path, dev_t id, FileDescriptor &&fd, gbm_dev
, m_gbmDevice(gbmDevice)
, m_allocator(std::make_unique<GbmGraphicsBufferAllocator>(gbmDevice))
{
uint64_t value = 0;
m_supportsSyncObjTimelines = drmGetCap(m_fd.get(), DRM_CAP_SYNCOBJ_TIMELINE, &value) == 0 && value != 0;
}
DrmDevice::~DrmDevice()
@ -57,6 +59,11 @@ int DrmDevice::fileDescriptor() const
return m_fd.get();
}
bool DrmDevice::supportsSyncObjTimelines() const
{
return m_supportsSyncObjTimelines;
}
std::unique_ptr<DrmDevice> DrmDevice::open(const QString &path)
{
return openWithAuthentication(path, -1);

View file

@ -30,6 +30,7 @@ public:
gbm_device *gbmDevice() const;
GraphicsBufferAllocator *allocator() const;
int fileDescriptor() const;
bool supportsSyncObjTimelines() const;
static std::unique_ptr<DrmDevice> open(const QString &path);
static std::unique_ptr<DrmDevice> openWithAuthentication(const QString &path, int authenticatedFd);
@ -42,6 +43,7 @@ private:
const FileDescriptor m_fd;
gbm_device *const m_gbmDevice;
const std::unique_ptr<GraphicsBufferAllocator> m_allocator;
bool m_supportsSyncObjTimelines;
};
}

View file

@ -168,16 +168,6 @@ std::unique_ptr<SurfaceTexture> RenderBackend::createSurfaceTextureWayland(Surfa
return nullptr;
}
bool RenderBackend::supportsTimelines() const
{
return false;
}
std::unique_ptr<SyncTimeline> RenderBackend::importTimeline(FileDescriptor &&syncObjFd)
{
return nullptr;
}
} // namespace KWin
#include "moc_renderbackend.cpp"

View file

@ -130,9 +130,6 @@ public:
virtual std::unique_ptr<SurfaceTexture> createSurfaceTextureX11(SurfacePixmapX11 *pixmap);
virtual std::unique_ptr<SurfaceTexture> createSurfaceTextureWayland(SurfacePixmap *pixmap);
virtual bool supportsTimelines() const;
virtual std::unique_ptr<SyncTimeline> importTimeline(FileDescriptor &&syncObjFd);
};
} // namespace KWin

View file

@ -7,6 +7,7 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "linux_drm_syncobj_v1.h"
#include "core/drmdevice.h"
#include "core/syncobjtimeline.h"
#include "display.h"
#include "linux_drm_syncobj_v1_p.h"
@ -22,9 +23,10 @@ namespace KWin
static constexpr uint32_t s_version = 1;
LinuxDrmSyncObjV1Interface::LinuxDrmSyncObjV1Interface(Display *display, QObject *parent)
LinuxDrmSyncObjV1Interface::LinuxDrmSyncObjV1Interface(Display *display, QObject *parent, DrmDevice *drmDevice)
: QObject(parent)
, QtWaylandServer::wp_linux_drm_syncobj_manager_v1(*display, s_version)
, m_drmDevice(drmDevice)
{
}
@ -42,23 +44,17 @@ void LinuxDrmSyncObjV1Interface::wp_linux_drm_syncobj_manager_v1_get_surface(Res
void LinuxDrmSyncObjV1Interface::wp_linux_drm_syncobj_manager_v1_import_timeline(Resource *resource, uint32_t id, int32_t rawFd)
{
FileDescriptor fd(rawFd);
// TODO add a GPU abstraction, instead of using the render backend
if (!m_renderBackend || isGlobalRemoved()) {
if (isGlobalRemoved()) {
// to not crash the client, create an inert timeline
new LinuxDrmSyncObjTimelineV1(resource->client(), id, nullptr);
return;
}
auto timeline = m_renderBackend->importTimeline(std::move(fd));
if (!timeline) {
uint32_t handle = 0;
if (drmSyncobjFDToHandle(m_drmDevice->fileDescriptor(), fd.get(), &handle) != 0) {
wl_resource_post_error(resource->handle, WP_LINUX_DRM_SYNCOBJ_MANAGER_V1_ERROR_INVALID_TIMELINE, "Importing timeline failed");
return;
}
new LinuxDrmSyncObjTimelineV1(resource->client(), id, std::move(timeline));
}
void LinuxDrmSyncObjV1Interface::setRenderBackend(RenderBackend *backend)
{
m_renderBackend = backend;
new LinuxDrmSyncObjTimelineV1(resource->client(), id, std::make_unique<SyncTimeline>(m_drmDevice->fileDescriptor(), handle));
}
void LinuxDrmSyncObjV1Interface::wp_linux_drm_syncobj_manager_v1_destroy(Resource *resource)

View file

@ -21,14 +21,14 @@ class Display;
class SurfaceInterface;
class RenderBackend;
class SyncTimeline;
class DrmDevice;
class KWIN_EXPORT LinuxDrmSyncObjV1Interface : public QObject, private QtWaylandServer::wp_linux_drm_syncobj_manager_v1
{
Q_OBJECT
public:
explicit LinuxDrmSyncObjV1Interface(Display *display, QObject *parent = nullptr);
explicit LinuxDrmSyncObjV1Interface(Display *display, QObject *parent, DrmDevice *drmDevice);
void setRenderBackend(RenderBackend *backend);
void remove();
private:
@ -37,7 +37,7 @@ private:
void wp_linux_drm_syncobj_manager_v1_destroy(Resource *resource) override;
void wp_linux_drm_syncobj_manager_v1_destroy_global() override;
QPointer<RenderBackend> m_renderBackend;
DrmDevice *const m_drmDevice;
};
class LinuxDrmSyncObjSurfaceV1 : private QtWaylandServer::wp_linux_drm_syncobj_surface_v1

View file

@ -11,6 +11,7 @@
#include "config-kwin.h"
#include "backends/drm/drm_backend.h"
#include "core/drmdevice.h"
#include "core/output.h"
#include "core/outputbackend.h"
#include "idle_inhibition.h"
@ -840,7 +841,7 @@ LinuxDrmSyncObjV1Interface *WaylandServer::linuxSyncObj() const
void WaylandServer::setRenderBackend(RenderBackend *backend)
{
if (backend->supportsTimelines()) {
if (backend->drmDevice()->supportsSyncObjTimelines()) {
// ensure the DRM_IOCTL_SYNCOBJ_EVENTFD ioctl is supported
const auto linuxVersion = linuxKernelVersion();
if (linuxVersion.majorVersion() < 6 && linuxVersion.minorVersion() < 6) {
@ -851,15 +852,12 @@ void WaylandServer::setRenderBackend(RenderBackend *backend)
return;
}
if (!m_linuxDrmSyncObj) {
m_linuxDrmSyncObj = new LinuxDrmSyncObjV1Interface(m_display, m_display);
m_linuxDrmSyncObj = new LinuxDrmSyncObjV1Interface(m_display, m_display, backend->drmDevice());
}
} else if (m_linuxDrmSyncObj) {
m_linuxDrmSyncObj->remove();
m_linuxDrmSyncObj = nullptr;
}
if (m_linuxDrmSyncObj) {
m_linuxDrmSyncObj->setRenderBackend(backend);
}
}
#if KWIN_BUILD_SCREENLOCKER