diff options
Diffstat (limited to 'src/platformsupport')
-rw-r--r-- | src/platformsupport/kmsconvenience/qkmsdevice.cpp | 39 | ||||
-rw-r--r-- | src/platformsupport/kmsconvenience/qkmsdevice_p.h | 31 |
2 files changed, 53 insertions, 17 deletions
diff --git a/src/platformsupport/kmsconvenience/qkmsdevice.cpp b/src/platformsupport/kmsconvenience/qkmsdevice.cpp index 401a2aec81..753fdb07af 100644 --- a/src/platformsupport/kmsconvenience/qkmsdevice.cpp +++ b/src/platformsupport/kmsconvenience/qkmsdevice.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2017 The Qt Company Ltd. ** Copyright (C) 2016 Pelagicore AG ** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> ** Contact: https://www.qt.io/licensing/ @@ -179,7 +179,7 @@ QPlatformScreen *QKmsDevice::createScreenForConnector(drmModeResPtr resources, drmModeModeInfo configurationModeline; auto userConfig = m_screenConfig->outputSettings(); - auto userConnectorConfig = userConfig.value(QString::fromUtf8(connectorName)); + QVariantMap 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(); @@ -489,9 +489,22 @@ static bool orderedScreenLessThan(const OrderedScreen &a, const OrderedScreen &b void QKmsDevice::createScreens() { + // Headless mode using a render node: cannot do any output related DRM + // stuff. Skip it all and register a dummy screen. + if (m_screenConfig->headless()) { + QPlatformScreen *screen = createHeadlessScreen(); + if (screen) { + qCDebug(qLcKmsDebug, "Headless mode enabled"); + registerScreen(screen, true, QPoint(0, 0), QList<QPlatformScreen *>()); + return; + } else { + qWarning("QKmsDevice: Requested headless mode without support in the backend. Request is ignored."); + } + } + drmModeResPtr resources = drmModeGetResources(m_dri_fd); if (!resources) { - qWarning("drmModeGetResources failed"); + qErrnoWarning(errno, "drmModeGetResources failed"); return; } @@ -597,6 +610,12 @@ void QKmsDevice::createScreens() } } +QPlatformScreen *QKmsDevice::createHeadlessScreen() +{ + // headless mode not supported by default + return nullptr; +} + // not all subclasses support screen cloning void QKmsDevice::registerScreenCloning(QPlatformScreen *screen, QPlatformScreen *screenThisScreenClones, @@ -628,7 +647,8 @@ QKmsScreenConfig *QKmsDevice::screenConfig() const } QKmsScreenConfig::QKmsScreenConfig() - : m_hwCursor(true) + : m_headless(false) + , m_hwCursor(true) , m_separateScreens(false) , m_pbuffers(false) , m_virtualDesktopLayout(VirtualDesktopLayoutHorizontal) @@ -663,6 +683,16 @@ void QKmsScreenConfig::loadConfig() const QJsonObject object = doc.object(); + const QString headlessStr = object.value(QLatin1String("headless")).toString(); + const QByteArray headless = headlessStr.toUtf8(); + QSize headlessSize; + if (sscanf(headless.constData(), "%dx%d", &headlessSize.rwidth(), &headlessSize.rheight()) == 2) { + m_headless = true; + m_headlessSize = headlessSize; + } else { + m_headless = false; + } + 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(); @@ -694,6 +724,7 @@ void QKmsScreenConfig::loadConfig() } qCDebug(qLcKmsDebug) << "Requested configuration (some settings may be ignored):\n" + << "\theadless:" << m_headless << "\n" << "\thwcursor:" << m_hwCursor << "\n" << "\tpbuffers:" << m_pbuffers << "\n" << "\tseparateScreens:" << m_separateScreens << "\n" diff --git a/src/platformsupport/kmsconvenience/qkmsdevice_p.h b/src/platformsupport/kmsconvenience/qkmsdevice_p.h index 390cc52e4d..bbc03b8e2a 100644 --- a/src/platformsupport/kmsconvenience/qkmsdevice_p.h +++ b/src/platformsupport/kmsconvenience/qkmsdevice_p.h @@ -77,6 +77,8 @@ public: QString devicePath() const { return m_devicePath; } + bool headless() const { return m_headless; } + QSize headlessSize() const { return m_headlessSize; } bool hwCursor() const { return m_hwCursor; } bool separateScreens() const { return m_separateScreens; } bool supportsPBuffers() const { return m_pbuffers; } @@ -88,6 +90,8 @@ private: void loadConfig(); QString m_devicePath; + bool m_headless; + QSize m_headlessSize; bool m_hwCursor; bool m_separateScreens; bool m_pbuffers; @@ -98,21 +102,21 @@ private: struct QKmsOutput { QString name; - uint32_t connector_id; - uint32_t crtc_id; + uint32_t connector_id = 0; + uint32_t crtc_id = 0; QSizeF physical_size; - int preferred_mode; // index of preferred mode in list below - int mode; // index of selected mode in list below - bool mode_set; - drmModeCrtcPtr saved_crtc; + int preferred_mode = -1; // index of preferred mode in list below + int mode = -1; // index of selected mode in list below + bool mode_set = false; + drmModeCrtcPtr saved_crtc = nullptr; QList<drmModeModeInfo> modes; - int subpixel; - drmModePropertyPtr dpms_prop; - drmModePropertyBlobPtr edid_blob; - bool wants_plane; - uint32_t plane_id; - bool plane_set; - uint32_t drm_format; + int subpixel = DRM_MODE_SUBPIXEL_UNKNOWN; + drmModePropertyPtr dpms_prop = nullptr; + drmModePropertyBlobPtr edid_blob = nullptr; + bool wants_plane = false; + uint32_t plane_id = 0; + bool plane_set = false; + uint32_t drm_format = DRM_FORMAT_XRGB8888; QString clone_source; void restoreMode(QKmsDevice *device); @@ -147,6 +151,7 @@ public: protected: virtual QPlatformScreen *createScreen(const QKmsOutput &output) = 0; + virtual QPlatformScreen *createHeadlessScreen(); virtual void registerScreenCloning(QPlatformScreen *screen, QPlatformScreen *screenThisScreenClones, const QVector<QPlatformScreen *> &screensCloningThisScreen); |