From 2e70a86900962b1f5f6ad79ca3245bc99873d889 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 4 Oct 2016 11:29:26 +0200 Subject: Move DRM/KMS code from eglfs into kmsconvenience The generic DRM code, not involving any GBM or EGLDevice stuff, can now be reused in components outside eglfs, for example linuxfb in order to get support for DRM dumb buffers. Task-number: QTBUG-56306 Change-Id: If7dffdb2415489dbc6470782fa76efcaeccf01c7 Reviewed-by: Oswald Buddenhagen Reviewed-by: Andy Nichols --- .../deviceintegration/eglfs_kms/eglfs_kms.pro | 2 +- .../eglfs_kms/qeglfskmsgbmdevice.cpp | 36 +- .../eglfs_kms/qeglfskmsgbmdevice.h | 11 +- .../eglfs_kms/qeglfskmsgbmintegration.cpp | 24 +- .../eglfs_kms/qeglfskmsgbmintegration.h | 2 +- .../eglfs_kms/qeglfskmsgbmscreen.cpp | 15 +- .../eglfs_kms/qeglfskmsgbmscreen.h | 4 +- .../eglfs_kms_egldevice/eglfs_kms_egldevice.pro | 2 +- .../eglfs_kms_egldevice/qeglfskmsegldevice.cpp | 23 +- .../eglfs_kms_egldevice/qeglfskmsegldevice.h | 14 +- .../qeglfskmsegldeviceintegration.cpp | 21 +- .../qeglfskmsegldeviceintegration.h | 7 +- .../qeglfskmsegldevicescreen.cpp | 14 +- .../eglfs_kms_egldevice/qeglfskmsegldevicescreen.h | 4 +- .../eglfs_kms_support/eglfs_kms_support.pro | 6 +- .../eglfs_kms_support/qeglfskmsdevice.cpp | 429 +-------------------- .../eglfs_kms_support/qeglfskmsdevice.h | 60 +-- .../eglfs_kms_support/qeglfskmsintegration.cpp | 121 +----- .../eglfs_kms_support/qeglfskmsintegration.h | 30 +- .../eglfs_kms_support/qeglfskmsscreen.cpp | 52 +-- .../eglfs_kms_support/qeglfskmsscreen.h | 33 +- 21 files changed, 155 insertions(+), 755 deletions(-) (limited to 'src/plugins/platforms/eglfs/deviceintegration') diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro index 255db824b7..e522c0ee1b 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro @@ -4,7 +4,7 @@ PLUGIN_TYPE = egldeviceintegrations PLUGIN_CLASS_NAME = QEglFSKmsGbmIntegrationPlugin load(qt_plugin) -QT += core-private gui-private eglfsdeviceintegration-private eglfs_kms_support-private +QT += core-private gui-private eglfsdeviceintegration-private eglfs_kms_support-private kms_support-private INCLUDEPATH += $$PWD/../../api $$PWD/../eglfs_kms_support diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp index 3a220ec942..2040d6bc0e 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp @@ -46,7 +46,6 @@ #include #include -#include #define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0]) @@ -65,8 +64,8 @@ void QEglFSKmsGbmDevice::pageFlipHandler(int fd, unsigned int sequence, unsigned screen->flipFinished(); } -QEglFSKmsGbmDevice::QEglFSKmsGbmDevice(QEglFSKmsIntegration *integration, const QString &path) - : QEglFSKmsDevice(integration, path) +QEglFSKmsGbmDevice::QEglFSKmsGbmDevice(QKmsScreenConfig *screenConfig, const QString &path) + : QEglFSKmsDevice(screenConfig, path) , m_gbm_device(Q_NULLPTR) , m_globalCursor(Q_NULLPTR) { @@ -77,7 +76,6 @@ bool QEglFSKmsGbmDevice::open() Q_ASSERT(fd() == -1); Q_ASSERT(m_gbm_device == Q_NULLPTR); - qCDebug(qLcEglfsKmsDebug) << "Opening device" << devicePath(); int fd = qt_safe_open(devicePath().toLocal8Bit().constData(), O_RDWR | O_CLOEXEC); if (fd == -1) { qErrnoWarning("Could not open DRM device %s", qPrintable(devicePath())); @@ -101,6 +99,8 @@ bool QEglFSKmsGbmDevice::open() void QEglFSKmsGbmDevice::close() { + // Note: screens are gone at this stage. + if (m_gbm_device) { gbm_device_destroy(m_gbm_device); m_gbm_device = Q_NULLPTR; @@ -110,15 +110,11 @@ void QEglFSKmsGbmDevice::close() qt_safe_close(fd()); setFd(-1); } - - if (m_globalCursor) - m_globalCursor->deleteLater(); - m_globalCursor = Q_NULLPTR; } -EGLNativeDisplayType QEglFSKmsGbmDevice::nativeDisplay() const +void *QEglFSKmsGbmDevice::nativeDisplay() const { - return reinterpret_cast(m_gbm_device); + return m_gbm_device; } gbm_device * QEglFSKmsGbmDevice::gbmDevice() const @@ -131,6 +127,17 @@ QPlatformCursor *QEglFSKmsGbmDevice::globalCursor() const return m_globalCursor; } +// Cannot do this from close(), it may be too late. +// Call this from the last screen dtor instead. +void QEglFSKmsGbmDevice::destroyGlobalCursor() +{ + if (m_globalCursor) { + qCDebug(qLcEglfsKmsDebug, "Destroying global GBM mouse cursor"); + delete m_globalCursor; + m_globalCursor = Q_NULLPTR; + } +} + void QEglFSKmsGbmDevice::handleDrmEvent() { drmEventContext drmEvent = { @@ -142,14 +149,13 @@ void QEglFSKmsGbmDevice::handleDrmEvent() drmHandleEvent(fd(), &drmEvent); } -QEglFSKmsScreen *QEglFSKmsGbmDevice::createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output) +QPlatformScreen *QEglFSKmsGbmDevice::createScreen(const QKmsOutput &output) { - static bool firstScreen = true; - QEglFSKmsGbmScreen *screen = new QEglFSKmsGbmScreen(integration, device, output); + QEglFSKmsGbmScreen *screen = new QEglFSKmsGbmScreen(this, output); - if (firstScreen && integration->hwCursor()) { + if (!m_globalCursor && screenConfig()->hwCursor()) { + qCDebug(qLcEglfsKmsDebug, "Creating new global GBM mouse cursor"); m_globalCursor = new QEglFSKmsGbmCursor(screen); - firstScreen = false; } return screen; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h index 7c0af84422..25284c6468 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h @@ -43,7 +43,7 @@ #define QEGLFSKMSGBMDEVICE_H #include "qeglfskmsgbmcursor.h" -#include "qeglfskmsdevice.h" +#include #include @@ -54,21 +54,20 @@ class QEglFSKmsScreen; class QEglFSKmsGbmDevice: public QEglFSKmsDevice { public: - QEglFSKmsGbmDevice(QEglFSKmsIntegration *integration, const QString &path); + QEglFSKmsGbmDevice(QKmsScreenConfig *screenConfig, const QString &path); bool open() Q_DECL_OVERRIDE; void close() Q_DECL_OVERRIDE; - EGLNativeDisplayType nativeDisplay() const Q_DECL_OVERRIDE; + void *nativeDisplay() const Q_DECL_OVERRIDE; gbm_device *gbmDevice() const; QPlatformCursor *globalCursor() const; + void destroyGlobalCursor(); void handleDrmEvent(); - virtual QEglFSKmsScreen *createScreen(QEglFSKmsIntegration *integration, - QEglFSKmsDevice *device, - QEglFSKmsOutput output) Q_DECL_OVERRIDE; + QPlatformScreen *createScreen(const QKmsOutput &output) Q_DECL_OVERRIDE; private: Q_DISABLE_COPY(QEglFSKmsGbmDevice) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp index 38419a55c8..16767114ab 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp @@ -63,8 +63,9 @@ QT_BEGIN_NAMESPACE QMutex QEglFSKmsGbmScreen::m_waitForFlipMutex; QEglFSKmsGbmIntegration::QEglFSKmsGbmIntegration() - : QEglFSKmsIntegration() -{} +{ + qCDebug(qLcEglfsKmsDebug, "New DRM/KMS via GBM integration created"); +} EGLNativeWindowType QEglFSKmsGbmIntegration::createNativeWindow(QPlatformWindow *platformWindow, const QSize &size, @@ -104,10 +105,12 @@ void QEglFSKmsGbmIntegration::destroyNativeWindow(EGLNativeWindowType window) QPlatformCursor *QEglFSKmsGbmIntegration::createCursor(QPlatformScreen *screen) const { - if (hwCursor()) - return Q_NULLPTR; - else + if (screenConfig()->hwCursor()) { + return nullptr; + } else { + qCDebug(qLcEglfsKmsDebug, "Using plain OpenGL mouse cursor"); return new QEglFSCursor(screen); + } } void QEglFSKmsGbmIntegration::presentBuffer(QPlatformSurface *surface) @@ -118,13 +121,12 @@ void QEglFSKmsGbmIntegration::presentBuffer(QPlatformSurface *surface) screen->flip(); } -QEglFSKmsDevice *QEglFSKmsGbmIntegration::createDevice(const QString &devicePath) +QKmsDevice *QEglFSKmsGbmIntegration::createDevice() { - QString path = devicePath; - if (!devicePath.isEmpty()) { - qCDebug(qLcEglfsKmsDebug) << "Using DRM device" << path << "specified in config file"; + QString path = screenConfig()->devicePath(); + if (!path.isEmpty()) { + qCDebug(qLcEglfsKmsDebug) << "GBM: Using DRM device" << path << "specified in config file"; } else { - QDeviceDiscovery *d = QDeviceDiscovery::create(QDeviceDiscovery::Device_VideoMask); const QStringList devices = d->scanConnectedDevices(); qCDebug(qLcEglfsKmsDebug) << "Found the following video devices:" << devices; @@ -137,7 +139,7 @@ QEglFSKmsDevice *QEglFSKmsGbmIntegration::createDevice(const QString &devicePath qCDebug(qLcEglfsKmsDebug) << "Using" << path; } - return new QEglFSKmsGbmDevice(this, path); + return new QEglFSKmsGbmDevice(screenConfig(), path); } QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.h index 727571d3e3..fa2e494a89 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.h @@ -65,7 +65,7 @@ public: void presentBuffer(QPlatformSurface *surface) Q_DECL_OVERRIDE; protected: - QEglFSKmsDevice *createDevice(const QString &devicePath) Q_DECL_OVERRIDE; + QKmsDevice *createDevice() Q_DECL_OVERRIDE; private: }; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp index bed775ff81..ebce0a4776 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp @@ -92,10 +92,8 @@ QEglFSKmsGbmScreen::FrameBuffer *QEglFSKmsGbmScreen::framebufferForBufferObject( return fb.take(); } -QEglFSKmsGbmScreen::QEglFSKmsGbmScreen(QEglFSKmsIntegration *integration, - QEglFSKmsDevice *device, - QEglFSKmsOutput output) - : QEglFSKmsScreen(integration, device, output) +QEglFSKmsGbmScreen::QEglFSKmsGbmScreen(QKmsDevice *device, const QKmsOutput &output) + : QEglFSKmsScreen(device, output) , m_gbm_surface(Q_NULLPTR) , m_gbm_bo_current(Q_NULLPTR) , m_gbm_bo_next(Q_NULLPTR) @@ -105,12 +103,17 @@ QEglFSKmsGbmScreen::QEglFSKmsGbmScreen(QEglFSKmsIntegration *integration, QEglFSKmsGbmScreen::~QEglFSKmsGbmScreen() { + const int remainingScreenCount = qGuiApp->screens().count(); + qCDebug(qLcEglfsKmsDebug, "Screen dtor. Remaining screens: %d", remainingScreenCount); + if (!remainingScreenCount && !device()->screenConfig()->separateScreens()) + static_cast(device())->destroyGlobalCursor(); } QPlatformCursor *QEglFSKmsGbmScreen::cursor() const { - if (integration()->hwCursor()) { - if (!integration()->separateScreens()) + QKmsScreenConfig *config = device()->screenConfig(); + if (config->hwCursor()) { + if (!config->separateScreens()) return static_cast(device())->globalCursor(); if (m_cursor.isNull()) { diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h index d7ad348291..ffc96955d4 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h @@ -54,9 +54,7 @@ class QEglFSKmsGbmCursor; class QEglFSKmsGbmScreen : public QEglFSKmsScreen { public: - QEglFSKmsGbmScreen(QEglFSKmsIntegration *integration, - QEglFSKmsDevice *device, - QEglFSKmsOutput output); + QEglFSKmsGbmScreen(QKmsDevice *device, const QKmsOutput &output); ~QEglFSKmsGbmScreen(); QPlatformCursor *cursor() const Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro index a625021aba..a2dc9c4a50 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro @@ -1,6 +1,6 @@ TARGET = qeglfs-kms-egldevice-integration -QT += core-private gui-private eglfsdeviceintegration-private eglfs_kms_support-private +QT += core-private gui-private eglfsdeviceintegration-private eglfs_kms_support-private kms_support-private INCLUDEPATH += $$PWD/../../api $$PWD/../eglfs_kms_support diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp index 60989e2bd0..f0bf59466e 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp @@ -40,14 +40,16 @@ #include "qeglfskmsegldevice.h" #include "qeglfskmsegldevicescreen.h" #include "qeglfskmsegldeviceintegration.h" +#include "private/qeglfsintegration_p.h" #include "private/qeglfscursor_p.h" #include QT_BEGIN_NAMESPACE -QEglFSKmsEglDevice::QEglFSKmsEglDevice(QEglFSKmsIntegration *integration, const QString &path) - : QEglFSKmsDevice(integration, path), +QEglFSKmsEglDevice::QEglFSKmsEglDevice(QEglFSKmsEglDeviceIntegration *devInt, QKmsScreenConfig *screenConfig, const QString &path) + : QEglFSKmsDevice(screenConfig, path), + m_devInt(devInt), m_globalCursor(nullptr) { } @@ -56,11 +58,9 @@ bool QEglFSKmsEglDevice::open() { Q_ASSERT(fd() == -1); - qCDebug(qLcEglfsKmsDebug, "Opening DRM device %s", qPrintable(devicePath())); - int fd = drmOpen(devicePath().toLocal8Bit().constData(), Q_NULLPTR); if (Q_UNLIKELY(fd < 0)) - qFatal("Could not open DRM device"); + qFatal("Could not open DRM (NV) device"); setFd(fd); @@ -69,25 +69,24 @@ bool QEglFSKmsEglDevice::open() void QEglFSKmsEglDevice::close() { - qCDebug(qLcEglfsKmsDebug, "Closing DRM device"); + // Note: screens are gone at this stage. if (qt_safe_close(fd()) == -1) - qErrnoWarning("Could not close DRM device"); + qErrnoWarning("Could not close DRM (NV) device"); setFd(-1); } EGLNativeDisplayType QEglFSKmsEglDevice::nativeDisplay() const { - return reinterpret_cast(static_cast(m_integration)->eglDevice()); + return reinterpret_cast(m_devInt->eglDevice()); } -QEglFSKmsScreen *QEglFSKmsEglDevice::createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, - QEglFSKmsOutput output) +QPlatformScreen *QEglFSKmsEglDevice::createScreen(const QKmsOutput &output) { - QEglFSKmsScreen *screen = new QEglFSKmsEglDeviceScreen(integration, device, output); + QEglFSKmsScreen *screen = new QEglFSKmsEglDeviceScreen(this, output); - if (!m_globalCursor && !integration->separateScreens()) { + if (!m_globalCursor && !screenConfig()->separateScreens()) { qCDebug(qLcEglfsKmsDebug, "Creating new global mouse cursor"); m_globalCursor = new QEglFSCursor(screen); } diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h index 8c8f79f70c..b9304b8502 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h @@ -45,25 +45,25 @@ QT_BEGIN_NAMESPACE class QPlatformCursor; +class QEglFSKmsEglDeviceIntegration; class QEglFSKmsEglDevice: public QEglFSKmsDevice { public: - QEglFSKmsEglDevice(QEglFSKmsIntegration *integration, const QString &path); + QEglFSKmsEglDevice(QEglFSKmsEglDeviceIntegration *devInt, QKmsScreenConfig *screenConfig, const QString &path); - virtual bool open() Q_DECL_OVERRIDE; - virtual void close() Q_DECL_OVERRIDE; + bool open() Q_DECL_OVERRIDE; + void close() Q_DECL_OVERRIDE; - virtual EGLNativeDisplayType nativeDisplay() const Q_DECL_OVERRIDE; + void *nativeDisplay() const Q_DECL_OVERRIDE; - virtual QEglFSKmsScreen *createScreen(QEglFSKmsIntegration *integration, - QEglFSKmsDevice *device, - QEglFSKmsOutput output) Q_DECL_OVERRIDE; + QPlatformScreen *createScreen(const QKmsOutput &output) Q_DECL_OVERRIDE; QPlatformCursor *globalCursor() { return m_globalCursor; } void destroyGlobalCursor(); private: + QEglFSKmsEglDeviceIntegration *m_devInt; QPlatformCursor *m_globalCursor; }; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp index d0c9c9565e..36fbfbd05c 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp @@ -50,8 +50,7 @@ QT_BEGIN_NAMESPACE QEglFSKmsEglDeviceIntegration::QEglFSKmsEglDeviceIntegration() - : QEglFSKmsIntegration() - , m_egl_device(EGL_NO_DEVICE_EXT) + : m_egl_device(EGL_NO_DEVICE_EXT) , m_funcs(Q_NULLPTR) { qCDebug(qLcEglfsKmsDebug, "New DRM/KMS on EGLDevice integration created"); @@ -101,10 +100,10 @@ bool QEglFSKmsEglDeviceIntegration::supportsPBuffers() const return true; } -class QEglJetsonTK1Window : public QEglFSWindow +class QEglFSKmsEglDeviceWindow : public QEglFSWindow { public: - QEglJetsonTK1Window(QWindow *w, const QEglFSKmsEglDeviceIntegration *integration) + QEglFSKmsEglDeviceWindow(QWindow *w, const QEglFSKmsEglDeviceIntegration *integration) : QEglFSWindow(w) , m_integration(integration) , m_egl_stream(EGL_NO_STREAM_KHR) @@ -118,13 +117,13 @@ public: EGLint m_latency; }; -void QEglJetsonTK1Window::invalidateSurface() +void QEglFSKmsEglDeviceWindow::invalidateSurface() { QEglFSWindow::invalidateSurface(); m_integration->m_funcs->destroy_stream(screen()->display(), m_egl_stream); } -void QEglJetsonTK1Window::resetSurface() +void QEglFSKmsEglDeviceWindow::resetSurface() { qCDebug(qLcEglfsKmsDebug, "Creating stream"); @@ -213,7 +212,7 @@ void QEglJetsonTK1Window::resetSurface() QEglFSWindow *QEglFSKmsEglDeviceIntegration::createWindow(QWindow *window) const { - QEglJetsonTK1Window *eglWindow = new QEglJetsonTK1Window(window, this); + QEglFSKmsEglDeviceWindow *eglWindow = new QEglFSKmsEglDeviceWindow(window, this); m_funcs->initialize(eglWindow->screen()->display()); if (Q_UNLIKELY(!(m_funcs->has_egl_output_base && m_funcs->has_egl_output_drm && m_funcs->has_egl_stream && @@ -223,10 +222,8 @@ QEglFSWindow *QEglFSKmsEglDeviceIntegration::createWindow(QWindow *window) const return eglWindow; } -QEglFSKmsDevice *QEglFSKmsEglDeviceIntegration::createDevice(const QString &devicePath) +QKmsDevice *QEglFSKmsEglDeviceIntegration::createDevice() { - Q_UNUSED(devicePath) - if (Q_UNLIKELY(!query_egl_device())) qFatal("Could not set up EGL device!"); @@ -234,7 +231,7 @@ QEglFSKmsDevice *QEglFSKmsEglDeviceIntegration::createDevice(const QString &devi if (Q_UNLIKELY(!deviceName)) qFatal("Failed to query device name from EGLDevice"); - return new QEglFSKmsEglDevice(this, deviceName); + return new QEglFSKmsEglDevice(this, screenConfig(), deviceName); } bool QEglFSKmsEglDeviceIntegration::query_egl_device() @@ -261,7 +258,7 @@ bool QEglFSKmsEglDeviceIntegration::query_egl_device() QPlatformCursor *QEglFSKmsEglDeviceIntegration::createCursor(QPlatformScreen *screen) const { - return separateScreens() ? new QEglFSCursor(screen) : nullptr; + return screenConfig()->separateScreens() ? new QEglFSCursor(screen) : nullptr; } QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h index cddfdbd5c6..a274474433 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h @@ -64,7 +64,7 @@ public: EGLDeviceEXT eglDevice() const { return m_egl_device; } protected: - QEglFSKmsDevice *createDevice(const QString &devicePath) Q_DECL_OVERRIDE; + QKmsDevice *createDevice() Q_DECL_OVERRIDE; QPlatformCursor *createCursor(QPlatformScreen *screen) const Q_DECL_OVERRIDE; private: @@ -72,10 +72,9 @@ private: bool query_egl_device(); EGLDeviceEXT m_egl_device; - - friend class QEglJetsonTK1Window; - // EGLStream infrastructure QEGLStreamConvenience *m_funcs; + + friend class QEglFSKmsEglDeviceWindow; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp index 1f672afeb4..532ec0b440 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp @@ -40,11 +40,14 @@ #include "qeglfskmsegldevicescreen.h" #include "qeglfskmsegldevice.h" #include +#include QT_BEGIN_NAMESPACE -QEglFSKmsEglDeviceScreen::QEglFSKmsEglDeviceScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output) - : QEglFSKmsScreen(integration, device, output) +Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug) + +QEglFSKmsEglDeviceScreen::QEglFSKmsEglDeviceScreen(QKmsDevice *device, const QKmsOutput &output) + : QEglFSKmsScreen(device, output) { } @@ -52,7 +55,7 @@ QEglFSKmsEglDeviceScreen::~QEglFSKmsEglDeviceScreen() { const int remainingScreenCount = qGuiApp->screens().count(); qCDebug(qLcEglfsKmsDebug, "Screen dtor. Remaining screens: %d", remainingScreenCount); - if (!remainingScreenCount && !m_integration->separateScreens()) + if (!remainingScreenCount && !device()->screenConfig()->separateScreens()) static_cast(device())->destroyGlobalCursor(); } @@ -62,7 +65,10 @@ QPlatformCursor *QEglFSKmsEglDeviceScreen::cursor() const // in its ctor. With separateScreens just use that. Otherwise // there's a virtual desktop and the device has a global cursor // and the base class has no dedicated cursor at all. - return m_integration->separateScreens() ? QEglFSScreen::cursor() : static_cast(device())->globalCursor(); + // config->hwCursor() is ignored for now, just use the standard OpenGL cursor. + return device()->screenConfig()->separateScreens() + ? QEglFSScreen::cursor() + : static_cast(device())->globalCursor(); } void QEglFSKmsEglDeviceScreen::waitForFlip() diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h index c57f52c6b7..1655a3f038 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h @@ -47,9 +47,7 @@ QT_BEGIN_NAMESPACE class QEglFSKmsEglDeviceScreen : public QEglFSKmsScreen { public: - QEglFSKmsEglDeviceScreen(QEglFSKmsIntegration *integration, - QEglFSKmsDevice *device, - QEglFSKmsOutput output); + QEglFSKmsEglDeviceScreen(QKmsDevice *device, const QKmsOutput &output); ~QEglFSKmsEglDeviceScreen(); QPlatformCursor *cursor() const Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro index 487edb569e..3c0a0ce30f 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro @@ -2,7 +2,7 @@ TARGET = QtEglFsKmsSupport CONFIG += no_module_headers internal_module load(qt_module) -QT += core-private gui-private eglfsdeviceintegration-private +QT += core-private gui-private eglfsdeviceintegration-private kms_support-private INCLUDEPATH += $$PWD/../../api @@ -15,8 +15,8 @@ QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF SOURCES += $$PWD/qeglfskmsintegration.cpp \ $$PWD/qeglfskmsdevice.cpp \ - $$PWD/qeglfskmsscreen.cpp \ + $$PWD/qeglfskmsscreen.cpp HEADERS += $$PWD/qeglfskmsintegration.h \ $$PWD/qeglfskmsdevice.h \ - $$PWD/qeglfskmsscreen.h \ + $$PWD/qeglfskmsscreen.h diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp index f6b58d1ba6..e99a6957a8 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp @@ -1,6 +1,5 @@ /**************************************************************************** ** -** Copyright (C) 2015 Pier Luigi Fiorini ** Copyright (C) 2016 The Qt Company Ltd. ** Copyright (C) 2016 Pelagicore AG ** Contact: https://www.qt.io/licensing/ @@ -41,432 +40,24 @@ #include "qeglfskmsdevice.h" #include "qeglfskmsscreen.h" - -#include "qeglfsintegration_p.h" - -#include -#include +#include "private/qeglfsintegration_p.h" #include -#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0]) - QT_BEGIN_NAMESPACE -Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug) - -enum OutputConfiguration { - OutputConfigOff, - OutputConfigPreferred, - OutputConfigCurrent, - OutputConfigMode, - OutputConfigModeline -}; - -int QEglFSKmsDevice::crtcForConnector(drmModeResPtr resources, drmModeConnectorPtr connector) -{ - for (int i = 0; i < connector->count_encoders; i++) { - drmModeEncoderPtr encoder = drmModeGetEncoder(m_dri_fd, connector->encoders[i]); - if (!encoder) { - qWarning("Failed to get encoder"); - continue; - } - - quint32 possibleCrtcs = encoder->possible_crtcs; - drmModeFreeEncoder(encoder); - - for (int j = 0; j < resources->count_crtcs; j++) { - bool isPossible = possibleCrtcs & (1 << j); - bool isAvailable = !(m_crtc_allocator & 1 << resources->crtcs[j]); - - if (isPossible && isAvailable) - return j; - } - } - - return -1; -} - -static const char * const connector_type_names[] = { // must match DRM_MODE_CONNECTOR_* - "None", - "VGA", - "DVI", - "DVI", - "DVI", - "Composite", - "TV", - "LVDS", - "CTV", - "DIN", - "DP", - "HDMI", - "HDMI", - "TV", - "eDP", - "Virtual", - "DSI" -}; - -static QByteArray nameForConnector(const drmModeConnectorPtr connector) -{ - QByteArray connectorName("UNKNOWN"); - - if (connector->connector_type < ARRAY_LENGTH(connector_type_names)) - connectorName = connector_type_names[connector->connector_type]; - - connectorName += QByteArray::number(connector->connector_type_id); - - return connectorName; -} - -static bool parseModeline(const QByteArray &text, drmModeModeInfoPtr mode) -{ - char hsync[16]; - char vsync[16]; - float fclock; - - mode->type = DRM_MODE_TYPE_USERDEF; - mode->hskew = 0; - mode->vscan = 0; - mode->vrefresh = 0; - mode->flags = 0; - - if (sscanf(text.constData(), "%f %hd %hd %hd %hd %hd %hd %hd %hd %15s %15s", - &fclock, - &mode->hdisplay, - &mode->hsync_start, - &mode->hsync_end, - &mode->htotal, - &mode->vdisplay, - &mode->vsync_start, - &mode->vsync_end, - &mode->vtotal, hsync, vsync) != 11) - return false; - - mode->clock = fclock * 1000; - - if (strcmp(hsync, "+hsync") == 0) - mode->flags |= DRM_MODE_FLAG_PHSYNC; - else if (strcmp(hsync, "-hsync") == 0) - mode->flags |= DRM_MODE_FLAG_NHSYNC; - else - return false; - - if (strcmp(vsync, "+vsync") == 0) - mode->flags |= DRM_MODE_FLAG_PVSYNC; - else if (strcmp(vsync, "-vsync") == 0) - mode->flags |= DRM_MODE_FLAG_NVSYNC; - else - return false; - - return true; -} - -QEglFSKmsScreen *QEglFSKmsDevice::createScreenForConnector(drmModeResPtr resources, - drmModeConnectorPtr connector, - VirtualDesktopInfo *vinfo) -{ - const QByteArray connectorName = nameForConnector(connector); - - const int crtc = crtcForConnector(resources, connector); - if (crtc < 0) { - qWarning() << "No usable crtc/encoder pair for connector" << connectorName; - return Q_NULLPTR; - } - - OutputConfiguration configuration; - QSize configurationSize; - drmModeModeInfo configurationModeline; - - auto userConfig = m_integration->outputSettings(); - auto userConnectorConfig = userConfig.value(QString::fromUtf8(connectorName)); - // default to the preferred mode unless overridden in the config - const QByteArray mode = userConnectorConfig.value(QStringLiteral("mode"), QStringLiteral("preferred")) - .toByteArray().toLower(); - if (mode == "off") { - configuration = OutputConfigOff; - } else if (mode == "preferred") { - configuration = OutputConfigPreferred; - } else if (mode == "current") { - configuration = OutputConfigCurrent; - } else if (sscanf(mode.constData(), "%dx%d", &configurationSize.rwidth(), &configurationSize.rheight()) == 2) { - configuration = OutputConfigMode; - } else if (parseModeline(mode, &configurationModeline)) { - configuration = OutputConfigModeline; - } else { - qWarning("Invalid mode \"%s\" for output %s", mode.constData(), connectorName.constData()); - configuration = OutputConfigPreferred; - } - if (vinfo) { - *vinfo = VirtualDesktopInfo(); - vinfo->virtualIndex = userConnectorConfig.value(QStringLiteral("virtualIndex"), INT_MAX).toInt(); - if (userConnectorConfig.contains(QStringLiteral("virtualPos"))) { - const QByteArray vpos = userConnectorConfig.value(QStringLiteral("virtualPos")).toByteArray(); - const QByteArrayList vposComp = vpos.split(','); - if (vposComp.count() == 2) - vinfo->virtualPos = QPoint(vposComp[0].trimmed().toInt(), vposComp[1].trimmed().toInt()); - } - } - - const uint32_t crtc_id = resources->crtcs[crtc]; - - if (configuration == OutputConfigOff) { - qCDebug(qLcEglfsKmsDebug) << "Turning off output" << connectorName; - drmModeSetCrtc(m_dri_fd, crtc_id, 0, 0, 0, 0, 0, Q_NULLPTR); - return Q_NULLPTR; - } - - // Skip disconnected output - if (configuration == OutputConfigPreferred && connector->connection == DRM_MODE_DISCONNECTED) { - qCDebug(qLcEglfsKmsDebug) << "Skipping disconnected output" << connectorName; - return Q_NULLPTR; - } - - // Get the current mode on the current crtc - drmModeModeInfo crtc_mode; - memset(&crtc_mode, 0, sizeof crtc_mode); - if (drmModeEncoderPtr encoder = drmModeGetEncoder(m_dri_fd, connector->connector_id)) { - drmModeCrtcPtr crtc = drmModeGetCrtc(m_dri_fd, encoder->crtc_id); - drmModeFreeEncoder(encoder); - - if (!crtc) - return Q_NULLPTR; - - if (crtc->mode_valid) - crtc_mode = crtc->mode; - - drmModeFreeCrtc(crtc); - } - - QList modes; - modes.reserve(connector->count_modes); - qCDebug(qLcEglfsKmsDebug) << connectorName << "mode count:" << connector->count_modes; - for (int i = 0; i < connector->count_modes; i++) { - const drmModeModeInfo &mode = connector->modes[i]; - qCDebug(qLcEglfsKmsDebug) << "mode" << i << mode.hdisplay << "x" << mode.vdisplay - << '@' << mode.vrefresh << "hz"; - modes << connector->modes[i]; - } - - int preferred = -1; - int current = -1; - int configured = -1; - int best = -1; - - for (int i = modes.size() - 1; i >= 0; i--) { - const drmModeModeInfo &m = modes.at(i); - - if (configuration == OutputConfigMode && - m.hdisplay == configurationSize.width() && - m.vdisplay == configurationSize.height()) { - configured = i; - } - - if (!memcmp(&crtc_mode, &m, sizeof m)) - current = i; - - if (m.type & DRM_MODE_TYPE_PREFERRED) - preferred = i; - - best = i; - } - - if (configuration == OutputConfigModeline) { - modes << configurationModeline; - configured = modes.size() - 1; - } - - if (current < 0 && crtc_mode.clock != 0) { - modes << crtc_mode; - current = mode.size() - 1; - } - - if (configuration == OutputConfigCurrent) - configured = current; - - int selected_mode = -1; - - if (configured >= 0) - selected_mode = configured; - else if (preferred >= 0) - selected_mode = preferred; - else if (current >= 0) - selected_mode = current; - else if (best >= 0) - selected_mode = best; - - if (selected_mode < 0) { - qWarning() << "No modes available for output" << connectorName; - return Q_NULLPTR; - } else { - int width = modes[selected_mode].hdisplay; - int height = modes[selected_mode].vdisplay; - int refresh = modes[selected_mode].vrefresh; - qCDebug(qLcEglfsKmsDebug) << "Selected mode" << selected_mode << ":" << width << "x" << height - << '@' << refresh << "hz for output" << connectorName; - } - - // physical size from connector < config values < env vars - static const int width = qEnvironmentVariableIntValue("QT_QPA_EGLFS_PHYSICAL_WIDTH"); - static const int height = qEnvironmentVariableIntValue("QT_QPA_EGLFS_PHYSICAL_HEIGHT"); - QSizeF physSize(width, height); - if (physSize.isEmpty()) { - physSize = QSize(userConnectorConfig.value(QStringLiteral("physicalWidth")).toInt(), - userConnectorConfig.value(QStringLiteral("physicalHeight")).toInt()); - if (physSize.isEmpty()) { - physSize.setWidth(connector->mmWidth); - physSize.setHeight(connector->mmHeight); - } - } - qCDebug(qLcEglfsKmsDebug) << "Physical size is" << physSize << "mm" << "for output" << connectorName; - - QEglFSKmsOutput output = { - QString::fromUtf8(connectorName), - connector->connector_id, - crtc_id, - physSize, - selected_mode, - false, - drmModeGetCrtc(m_dri_fd, crtc_id), - modes, - connector->subpixel, - connectorProperty(connector, QByteArrayLiteral("DPMS")) - }; - - m_crtc_allocator |= (1 << output.crtc_id); - m_connector_allocator |= (1 << output.connector_id); - - return createScreen(m_integration, this, output); -} - -drmModePropertyPtr QEglFSKmsDevice::connectorProperty(drmModeConnectorPtr connector, const QByteArray &name) -{ - drmModePropertyPtr prop; - - for (int i = 0; i < connector->count_props; i++) { - prop = drmModeGetProperty(m_dri_fd, connector->props[i]); - if (!prop) - continue; - if (strcmp(prop->name, name.constData()) == 0) - return prop; - drmModeFreeProperty(prop); - } - - return Q_NULLPTR; -} - -QEglFSKmsDevice::QEglFSKmsDevice(QEglFSKmsIntegration *integration, const QString &path) - : m_integration(integration) - , m_path(path) - , m_dri_fd(-1) - , m_crtc_allocator(0) - , m_connector_allocator(0) -{ -} - -QEglFSKmsDevice::~QEglFSKmsDevice() -{ -} - -struct OrderedScreen -{ - OrderedScreen() : screen(nullptr) { } - OrderedScreen(QEglFSKmsScreen *screen, const QEglFSKmsDevice::VirtualDesktopInfo &vinfo) - : screen(screen), vinfo(vinfo) { } - QEglFSKmsScreen *screen; - QEglFSKmsDevice::VirtualDesktopInfo vinfo; -}; - -QDebug operator<<(QDebug dbg, const OrderedScreen &s) -{ - QDebugStateSaver saver(dbg); - dbg.nospace() << "OrderedScreen(" << s.screen << " : " << s.vinfo.virtualIndex - << " / " << s.vinfo.virtualPos << ")"; - return dbg; -} - -static bool orderedScreenLessThan(const OrderedScreen &a, const OrderedScreen &b) -{ - return a.vinfo.virtualIndex < b.vinfo.virtualIndex; -} - -void QEglFSKmsDevice::createScreens() -{ - drmModeResPtr resources = drmModeGetResources(m_dri_fd); - if (!resources) { - qWarning("drmModeGetResources failed"); - return; - } - - QVector screens; - - for (int i = 0; i < resources->count_connectors; i++) { - drmModeConnectorPtr connector = drmModeGetConnector(m_dri_fd, resources->connectors[i]); - if (!connector) - continue; - - VirtualDesktopInfo vinfo; - QEglFSKmsScreen *screen = createScreenForConnector(resources, connector, &vinfo); - if (screen) - screens.append(OrderedScreen(screen, vinfo)); - - drmModeFreeConnector(connector); - } - - drmModeFreeResources(resources); - - // Use stable sort to preserve the original order for outputs with unspecified indices. - std::stable_sort(screens.begin(), screens.end(), orderedScreenLessThan); - qCDebug(qLcEglfsKmsDebug) << "Sorted screen list:" << screens; - - QPoint pos(0, 0); - QList siblings; - QEglFSIntegration *qpaIntegration = static_cast(QGuiApplicationPrivate::platformIntegration()); - - for (const OrderedScreen &orderedScreen : screens) { - QEglFSKmsScreen *s = orderedScreen.screen; - // set up a horizontal or vertical virtual desktop - if (orderedScreen.vinfo.virtualPos.isNull()) { - s->setVirtualPosition(pos); - if (m_integration->virtualDesktopLayout() == QEglFSKmsIntegration::VirtualDesktopLayoutVertical) - pos.ry() += s->geometry().height(); - else - pos.rx() += s->geometry().width(); - } else { - s->setVirtualPosition(orderedScreen.vinfo.virtualPos); - } - qCDebug(qLcEglfsKmsDebug) << "Adding screen" << s << "to QPA with geometry" << s->geometry(); - // The order in qguiapp's screens list will match the order set by - // virtualIndex. This is not only handy but also required since for instance - // evdevtouch relies on it when performing touch device - screen mapping. - qpaIntegration->addScreen(s); - siblings << s; - } - - if (!m_integration->separateScreens()) { - // enable the virtual desktop - Q_FOREACH (QPlatformScreen *screen, siblings) - static_cast(screen)->setVirtualSiblings(siblings); - } -} - -int QEglFSKmsDevice::fd() const -{ - return m_dri_fd; -} - -QString QEglFSKmsDevice::devicePath() const -{ - return m_path; -} - -QEglFSKmsScreen *QEglFSKmsDevice::createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output) +QEglFSKmsDevice::QEglFSKmsDevice(QKmsScreenConfig *screenConfig, const QString &path) + : QKmsDevice(screenConfig, path) { - return new QEglFSKmsScreen(integration, device, output); } -void QEglFSKmsDevice::setFd(int fd) +void QEglFSKmsDevice::registerScreen(QPlatformScreen *screen, + const QPoint &virtualPos, + const QList &virtualSiblings) { - m_dri_fd = fd; + QEglFSKmsScreen *s = static_cast(screen); + s->setVirtualPosition(virtualPos); + s->setVirtualSiblings(virtualSiblings); + static_cast(QGuiApplicationPrivate::platformIntegration())->addScreen(s); } QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h index 3e7ac7e3f0..1bbea250bb 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h @@ -1,6 +1,5 @@ /**************************************************************************** ** -** Copyright (C) 2015 Pier Luigi Fiorini ** Copyright (C) 2016 The Qt Company Ltd. ** Copyright (C) 2016 Pelagicore AG ** Contact: https://www.qt.io/licensing/ @@ -42,64 +41,21 @@ #ifndef QEGLFSKMSDEVICE_H #define QEGLFSKMSDEVICE_H -#include "qeglfskmsintegration.h" -#include "qeglfskmsscreen.h" - -#include -#include +#include "private/qeglfsglobal_p.h" +#include QT_BEGIN_NAMESPACE -class Q_EGLFS_EXPORT QEglFSKmsDevice +class Q_EGLFS_EXPORT QEglFSKmsDevice : public QKmsDevice { public: - struct VirtualDesktopInfo { - VirtualDesktopInfo() : virtualIndex(0) { } - int virtualIndex; - QPoint virtualPos; - }; - - QEglFSKmsDevice(QEglFSKmsIntegration *integration, const QString &path); - virtual ~QEglFSKmsDevice(); - - virtual bool open() = 0; - virtual void close() = 0; - - virtual void createScreens(); - - virtual EGLNativeDisplayType nativeDisplay() const = 0; - int fd() const; - QString devicePath() const; - -protected: - virtual QEglFSKmsScreen *createScreen(QEglFSKmsIntegration *integration, - QEglFSKmsDevice *device, - QEglFSKmsOutput output); - void setFd(int fd); - - QEglFSKmsIntegration *m_integration; - QString m_path; - int m_dri_fd; - - quint32 m_crtc_allocator; - quint32 m_connector_allocator; - - int crtcForConnector(drmModeResPtr resources, drmModeConnectorPtr connector); - QEglFSKmsScreen *createScreenForConnector(drmModeResPtr resources, - drmModeConnectorPtr connector, - VirtualDesktopInfo *vinfo); - drmModePropertyPtr connectorProperty(drmModeConnectorPtr connector, const QByteArray &name); - - static void pageFlipHandler(int fd, - unsigned int sequence, - unsigned int tv_sec, - unsigned int tv_usec, - void *user_data); + QEglFSKmsDevice(QKmsScreenConfig *screenConfig, const QString &path); -private: - Q_DISABLE_COPY(QEglFSKmsDevice) + void registerScreen(QPlatformScreen *screen, + const QPoint &virtualPos, + const QList &virtualSiblings) override; }; QT_END_NAMESPACE -#endif +#endif // QEGLFSKMSDEVICE_H diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp index 5368a6d031..c77151181e 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp @@ -40,13 +40,10 @@ ****************************************************************************/ #include "qeglfskmsintegration.h" -#include "qeglfskmsdevice.h" #include "qeglfskmsscreen.h" -#include -#include -#include -#include +#include + #include #include @@ -58,28 +55,27 @@ QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(qLcEglfsKmsDebug, "qt.qpa.eglfs.kms") QEglFSKmsIntegration::QEglFSKmsIntegration() - : m_device(Q_NULLPTR) - , m_hwCursor(false) - , m_pbuffers(false) - , m_separateScreens(false) - , m_virtualDesktopLayout(VirtualDesktopLayoutHorizontal) -{} - -void QEglFSKmsIntegration::platformInit() + : m_device(Q_NULLPTR), + m_screenConfig(new QKmsScreenConfig) { - loadConfig(); +} - if (!m_devicePath.isEmpty()) { - qCDebug(qLcEglfsKmsDebug) << "Using DRM device" << m_devicePath << "specified in config file"; - } +QEglFSKmsIntegration::~QEglFSKmsIntegration() +{ + delete m_screenConfig; +} - m_device = createDevice(m_devicePath); +void QEglFSKmsIntegration::platformInit() +{ + qCDebug(qLcEglfsKmsDebug, "platformInit: Opening DRM device"); + m_device = createDevice(); if (Q_UNLIKELY(!m_device->open())) - qFatal("Could not open device %s - aborting!", qPrintable(m_devicePath)); + qFatal("Could not open DRM device"); } void QEglFSKmsIntegration::platformDestroy() { + qCDebug(qLcEglfsKmsDebug, "platformDestroy: Closing DRM device"); m_device->close(); delete m_device; m_device = Q_NULLPTR; @@ -88,7 +84,7 @@ void QEglFSKmsIntegration::platformDestroy() EGLNativeDisplayType QEglFSKmsIntegration::platformDisplay() const { Q_ASSERT(m_device); - return m_device->nativeDisplay(); + return (EGLNativeDisplayType) m_device->nativeDisplay(); } bool QEglFSKmsIntegration::usesDefaultScreen() @@ -134,94 +130,17 @@ void QEglFSKmsIntegration::waitForVSync(QPlatformSurface *surface) const bool QEglFSKmsIntegration::supportsPBuffers() const { - return m_pbuffers; -} - -bool QEglFSKmsIntegration::hwCursor() const -{ - return m_hwCursor; -} - -bool QEglFSKmsIntegration::separateScreens() const -{ - return m_separateScreens; -} - -QEglFSKmsIntegration::VirtualDesktopLayout QEglFSKmsIntegration::virtualDesktopLayout() const -{ - return m_virtualDesktopLayout; + return m_screenConfig->supportsPBuffers(); } -QMap QEglFSKmsIntegration::outputSettings() const -{ - return m_outputSettings; -} - -QEglFSKmsDevice *QEglFSKmsIntegration::device() const +QKmsDevice *QEglFSKmsIntegration::device() const { return m_device; } -void QEglFSKmsIntegration::loadConfig() +QKmsScreenConfig *QEglFSKmsIntegration::screenConfig() const { - static QByteArray json = qgetenv("QT_QPA_EGLFS_KMS_CONFIG"); - if (json.isEmpty()) - return; - - qCDebug(qLcEglfsKmsDebug) << "Loading KMS setup from" << json; - - QFile file(QString::fromUtf8(json)); - if (!file.open(QFile::ReadOnly)) { - qCWarning(qLcEglfsKmsDebug) << "Could not open config file" - << json << "for reading"; - return; - } - - const QJsonDocument doc = QJsonDocument::fromJson(file.readAll()); - if (!doc.isObject()) { - qCWarning(qLcEglfsKmsDebug) << "Invalid config file" << json - << "- no top-level JSON object"; - return; - } - - const QJsonObject object = doc.object(); - - m_hwCursor = object.value(QLatin1String("hwcursor")).toBool(m_hwCursor); - m_pbuffers = object.value(QLatin1String("pbuffers")).toBool(m_pbuffers); - m_devicePath = object.value(QLatin1String("device")).toString(); - m_separateScreens = object.value(QLatin1String("separateScreens")).toBool(m_separateScreens); - - const QString vdOriString = object.value(QLatin1String("virtualDesktopLayout")).toString(); - if (!vdOriString.isEmpty()) { - if (vdOriString == QLatin1String("horizontal")) - m_virtualDesktopLayout = VirtualDesktopLayoutHorizontal; - else if (vdOriString == QLatin1String("vertical")) - m_virtualDesktopLayout = VirtualDesktopLayoutVertical; - else - qCWarning(qLcEglfsKmsDebug) << "Unknown virtualDesktopOrientation value" << vdOriString; - } - - const QJsonArray outputs = object.value(QLatin1String("outputs")).toArray(); - for (int i = 0; i < outputs.size(); i++) { - const QVariantMap outputSettings = outputs.at(i).toObject().toVariantMap(); - - if (outputSettings.contains(QStringLiteral("name"))) { - const QString name = outputSettings.value(QStringLiteral("name")).toString(); - - if (m_outputSettings.contains(name)) { - qCDebug(qLcEglfsKmsDebug) << "Output" << name << "configured multiple times!"; - } - - m_outputSettings.insert(name, outputSettings); - } - } - - qCDebug(qLcEglfsKmsDebug) << "Configuration:\n" - << "\thwcursor:" << m_hwCursor << "\n" - << "\tpbuffers:" << m_pbuffers << "\n" - << "\tseparateScreens:" << m_separateScreens << "\n" - << "\tvirtualDesktopLayout:" << m_virtualDesktopLayout << "\n" - << "\toutputs:" << m_outputSettings; + return m_screenConfig; } QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h index ba49945715..21347d9131 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h @@ -49,19 +49,16 @@ QT_BEGIN_NAMESPACE -class QEglFSKmsDevice; +class QKmsDevice; +class QKmsScreenConfig; Q_EGLFS_EXPORT Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug) class Q_EGLFS_EXPORT QEglFSKmsIntegration : public QEglFSDeviceIntegration { public: - enum VirtualDesktopLayout { - VirtualDesktopLayoutHorizontal, - VirtualDesktopLayoutVertical - }; - QEglFSKmsIntegration(); + ~QEglFSKmsIntegration(); void platformInit() Q_DECL_OVERRIDE; void platformDestroy() Q_DECL_OVERRIDE; @@ -73,25 +70,14 @@ public: void waitForVSync(QPlatformSurface *surface) const Q_DECL_OVERRIDE; bool supportsPBuffers() const Q_DECL_OVERRIDE; - virtual bool hwCursor() const; - virtual bool separateScreens() const; - virtual VirtualDesktopLayout virtualDesktopLayout() const; - QMap outputSettings() const; - - QEglFSKmsDevice *device() const; + QKmsDevice *device() const; + QKmsScreenConfig *screenConfig() const; protected: - virtual QEglFSKmsDevice *createDevice(const QString &devicePath) = 0; - - void loadConfig(); + virtual QKmsDevice *createDevice() = 0; - QEglFSKmsDevice *m_device; - bool m_hwCursor; - bool m_pbuffers; - bool m_separateScreens; - VirtualDesktopLayout m_virtualDesktopLayout; - QString m_devicePath; - QMap m_outputSettings; + QKmsDevice *m_device; + QKmsScreenConfig *m_screenConfig; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp index 4021609407..a2af586947 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp @@ -40,7 +40,6 @@ ****************************************************************************/ #include "qeglfskmsscreen.h" -#include "qeglfskmsdevice.h" #include "qeglfsintegration_p.h" #include @@ -69,30 +68,19 @@ private: QEglFSKmsScreen *m_screen; }; -QEglFSKmsScreen::QEglFSKmsScreen(QEglFSKmsIntegration *integration, - QEglFSKmsDevice *device, - QEglFSKmsOutput output) - : QEglFSScreen(eglGetDisplay(device->nativeDisplay())) - , m_integration(integration) +QEglFSKmsScreen::QEglFSKmsScreen(QKmsDevice *device, const QKmsOutput &output) + : QEglFSScreen(eglGetDisplay((EGLNativeDisplayType) device->nativeDisplay())) , m_device(device) , m_output(output) , m_powerState(PowerStateOn) , m_interruptHandler(new QEglFSKmsInterruptHandler(this)) { - m_siblings << this; // gets overridden by QEglFSKmsDevice later if !separateScreens + m_siblings << this; // gets overridden later } QEglFSKmsScreen::~QEglFSKmsScreen() { - if (m_output.dpms_prop) { - drmModeFreeProperty(m_output.dpms_prop); - m_output.dpms_prop = Q_NULLPTR; - } - restoreMode(); - if (m_output.saved_crtc) { - drmModeFreeCrtc(m_output.saved_crtc); - m_output.saved_crtc = Q_NULLPTR; - } + m_output.cleanup(m_device); delete m_interruptHandler; } @@ -171,16 +159,7 @@ void QEglFSKmsScreen::flipFinished() void QEglFSKmsScreen::restoreMode() { - if (m_output.mode_set && m_output.saved_crtc) { - drmModeSetCrtc(m_device->fd(), - m_output.saved_crtc->crtc_id, - m_output.saved_crtc->buffer_id, - 0, 0, - &m_output.connector_id, 1, - &m_output.saved_crtc->mode); - - m_output.mode_set = false; - } + m_output.restoreMode(m_device); } qreal QEglFSKmsScreen::refreshRate() const @@ -191,20 +170,7 @@ qreal QEglFSKmsScreen::refreshRate() const QPlatformScreen::SubpixelAntialiasingType QEglFSKmsScreen::subpixelAntialiasingTypeHint() const { - switch (m_output.subpixel) { - default: - case DRM_MODE_SUBPIXEL_UNKNOWN: - case DRM_MODE_SUBPIXEL_NONE: - return Subpixel_None; - case DRM_MODE_SUBPIXEL_HORIZONTAL_RGB: - return Subpixel_RGB; - case DRM_MODE_SUBPIXEL_HORIZONTAL_BGR: - return Subpixel_BGR; - case DRM_MODE_SUBPIXEL_VERTICAL_RGB: - return Subpixel_VRGB; - case DRM_MODE_SUBPIXEL_VERTICAL_BGR: - return Subpixel_VBGR; - } + return m_output.subpixelAntialiasingTypeHint(); } QPlatformScreen::PowerState QEglFSKmsScreen::powerState() const @@ -214,11 +180,7 @@ QPlatformScreen::PowerState QEglFSKmsScreen::powerState() const void QEglFSKmsScreen::setPowerState(QPlatformScreen::PowerState state) { - if (!m_output.dpms_prop) - return; - - drmModeConnectorSetProperty(m_device->fd(), m_output.connector_id, - m_output.dpms_prop->prop_id, (int)state); + m_output.setPowerState(m_device, state); m_powerState = state; } diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h index 2b6a0ffe6c..25740697d7 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h @@ -42,39 +42,20 @@ #ifndef QEGLFSKMSSCREEN_H #define QEGLFSKMSSCREEN_H -#include "qeglfskmsintegration.h" #include "private/qeglfsscreen_p.h" #include #include -#include -#include +#include QT_BEGIN_NAMESPACE -class QEglFSKmsDevice; class QEglFSKmsInterruptHandler; -struct QEglFSKmsOutput -{ - QString name; - uint32_t connector_id; - uint32_t crtc_id; - QSizeF physical_size; - int mode; // index of selected mode in list below - bool mode_set; - drmModeCrtcPtr saved_crtc; - QList modes; - int subpixel; - drmModePropertyPtr dpms_prop; -}; - class Q_EGLFS_EXPORT QEglFSKmsScreen : public QEglFSScreen { public: - QEglFSKmsScreen(QEglFSKmsIntegration *integration, - QEglFSKmsDevice *device, - QEglFSKmsOutput output); + QEglFSKmsScreen(QKmsDevice *device, const QKmsOutput &output); ~QEglFSKmsScreen(); void setVirtualPosition(const QPoint &pos); @@ -96,8 +77,7 @@ public: QList virtualSiblings() const Q_DECL_OVERRIDE { return m_siblings; } void setVirtualSiblings(QList sl) { m_siblings = sl; } - QEglFSKmsIntegration *integration() const { return m_integration; } - QEglFSKmsDevice *device() const { return m_device; } + QKmsDevice *device() const { return m_device; } void destroySurface(); @@ -105,7 +85,7 @@ public: virtual void flip(); virtual void flipFinished(); - QEglFSKmsOutput &output() { return m_output; } + QKmsOutput &output() { return m_output; } void restoreMode(); SubpixelAntialiasingType subpixelAntialiasingTypeHint() const Q_DECL_OVERRIDE; @@ -114,10 +94,9 @@ public: void setPowerState(QPlatformScreen::PowerState state) Q_DECL_OVERRIDE; protected: - QEglFSKmsIntegration *m_integration; - QEglFSKmsDevice *m_device; + QKmsDevice *m_device; - QEglFSKmsOutput m_output; + QKmsOutput m_output; QPoint m_pos; QList m_siblings; -- cgit v1.2.3