wayland: port linux drm syncobj from RenderBackend to DrmDevice
This commit is contained in:
parent
0f41239515
commit
2e9e6893bb
11 changed files with 22 additions and 60 deletions
|
@ -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"
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue