diff --git a/src/backends/drm/drm_egl_backend.cpp b/src/backends/drm/drm_egl_backend.cpp index d8d55923b1..369009f8b6 100644 --- a/src/backends/drm/drm_egl_backend.cpp +++ b/src/backends/drm/drm_egl_backend.cpp @@ -181,21 +181,6 @@ DrmGpu *EglGbmBackend::gpu() const return m_backend->primaryGpu(); } -bool EglGbmBackend::supportsTimelines() const -{ - return m_backend->primaryGpu()->syncObjTimelinesSupported(); -} - -std::unique_ptr 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(m_backend->primaryGpu()->fd(), handle); -} - } // namespace KWin #include "moc_drm_egl_backend.cpp" diff --git a/src/backends/drm/drm_egl_backend.h b/src/backends/drm/drm_egl_backend.h index 69afe521bb..dab2ccb921 100644 --- a/src/backends/drm/drm_egl_backend.h +++ b/src/backends/drm/drm_egl_backend.h @@ -61,9 +61,6 @@ public: EglDisplay *displayForGpu(DrmGpu *gpu); std::shared_ptr contextForGpu(DrmGpu *gpu); - bool supportsTimelines() const override; - std::unique_ptr importTimeline(FileDescriptor &&syncObjFd) override; - private: bool initializeEgl(); bool initRenderingContext(); diff --git a/src/backends/drm/drm_gpu.cpp b/src/backends/drm/drm_gpu.cpp index a5f4fb0ced..2bd7251acb 100644 --- a/src/backends/drm/drm_gpu.cpp +++ b/src/backends/drm/drm_gpu.cpp @@ -75,9 +75,6 @@ DrmGpu::DrmGpu(DrmBackend *backend, int fd, std::unique_ptr &&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 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; diff --git a/src/backends/drm/drm_gpu.h b/src/backends/drm/drm_gpu.h index fd2d1c67fa..323ac6bac8 100644 --- a/src/backends/drm/drm_gpu.h +++ b/src/backends/drm/drm_gpu.h @@ -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 m_eglDisplay; DrmBackend *const m_platform; diff --git a/src/core/drmdevice.cpp b/src/core/drmdevice.cpp index 6bc48d8e08..81dce17174 100644 --- a/src/core/drmdevice.cpp +++ b/src/core/drmdevice.cpp @@ -25,6 +25,8 @@ DrmDevice::DrmDevice(const QString &path, dev_t id, FileDescriptor &&fd, gbm_dev , m_gbmDevice(gbmDevice) , m_allocator(std::make_unique(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::open(const QString &path) { return openWithAuthentication(path, -1); diff --git a/src/core/drmdevice.h b/src/core/drmdevice.h index f56bbe4a01..252796449e 100644 --- a/src/core/drmdevice.h +++ b/src/core/drmdevice.h @@ -30,6 +30,7 @@ public: gbm_device *gbmDevice() const; GraphicsBufferAllocator *allocator() const; int fileDescriptor() const; + bool supportsSyncObjTimelines() const; static std::unique_ptr open(const QString &path); static std::unique_ptr openWithAuthentication(const QString &path, int authenticatedFd); @@ -42,6 +43,7 @@ private: const FileDescriptor m_fd; gbm_device *const m_gbmDevice; const std::unique_ptr m_allocator; + bool m_supportsSyncObjTimelines; }; } diff --git a/src/core/renderbackend.cpp b/src/core/renderbackend.cpp index f4c53ce391..c8c8dac755 100644 --- a/src/core/renderbackend.cpp +++ b/src/core/renderbackend.cpp @@ -168,16 +168,6 @@ std::unique_ptr RenderBackend::createSurfaceTextureWayland(Surfa return nullptr; } -bool RenderBackend::supportsTimelines() const -{ - return false; -} - -std::unique_ptr RenderBackend::importTimeline(FileDescriptor &&syncObjFd) -{ - return nullptr; -} - } // namespace KWin #include "moc_renderbackend.cpp" diff --git a/src/core/renderbackend.h b/src/core/renderbackend.h index 4bd17d5cc2..313c0b668c 100644 --- a/src/core/renderbackend.h +++ b/src/core/renderbackend.h @@ -130,9 +130,6 @@ public: virtual std::unique_ptr createSurfaceTextureX11(SurfacePixmapX11 *pixmap); virtual std::unique_ptr createSurfaceTextureWayland(SurfacePixmap *pixmap); - - virtual bool supportsTimelines() const; - virtual std::unique_ptr importTimeline(FileDescriptor &&syncObjFd); }; } // namespace KWin diff --git a/src/wayland/linux_drm_syncobj_v1.cpp b/src/wayland/linux_drm_syncobj_v1.cpp index 589ccd78c3..b77b0b84d6 100644 --- a/src/wayland/linux_drm_syncobj_v1.cpp +++ b/src/wayland/linux_drm_syncobj_v1.cpp @@ -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(m_drmDevice->fileDescriptor(), handle)); } void LinuxDrmSyncObjV1Interface::wp_linux_drm_syncobj_manager_v1_destroy(Resource *resource) diff --git a/src/wayland/linux_drm_syncobj_v1.h b/src/wayland/linux_drm_syncobj_v1.h index ff6ddbe034..2a81eb05f1 100644 --- a/src/wayland/linux_drm_syncobj_v1.h +++ b/src/wayland/linux_drm_syncobj_v1.h @@ -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 m_renderBackend; + DrmDevice *const m_drmDevice; }; class LinuxDrmSyncObjSurfaceV1 : private QtWaylandServer::wp_linux_drm_syncobj_surface_v1 diff --git a/src/wayland_server.cpp b/src/wayland_server.cpp index eefdde86ff..e8c1c29c9a 100644 --- a/src/wayland_server.cpp +++ b/src/wayland_server.cpp @@ -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