diff options
Diffstat (limited to 'src/plugins/platforms/eglfs/deviceintegration/eglfs_kms')
17 files changed, 931 insertions, 1518 deletions
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 12ae0a13b1..b1791240ab 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro @@ -1,31 +1,35 @@ TARGET = qeglfs-kms-integration -QT += core-private gui-private platformsupport-private eglfs_device_lib-private +PLUGIN_TYPE = egldeviceintegrations +PLUGIN_CLASS_NAME = QEglFSKmsGbmIntegrationPlugin +load(qt_plugin) + +QT += core-private gui-private platformsupport-private eglfs_device_lib-private eglfs_kms_support-private -INCLUDEPATH += $$PWD/../.. +INCLUDEPATH += $$PWD/../.. $$PWD/../eglfs_kms_support -# Avoid X11 header collision -DEFINES += MESA_EGL_NO_X11_HEADERS +# Avoid X11 header collision, use generic EGL native types +DEFINES += QT_EGL_NO_X11 CONFIG += link_pkgconfig -PKGCONFIG += libdrm gbm +!contains(QT_CONFIG, no-pkg-config) { + PKGCONFIG += libdrm gbm +} else { + LIBS += -ldrm -lgbm +} CONFIG += egl QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF -SOURCES += $$PWD/qeglfskmsmain.cpp \ - $$PWD/qeglfskmsintegration.cpp \ - $$PWD/qeglfskmsdevice.cpp \ - $$PWD/qeglfskmsscreen.cpp \ - $$PWD/qeglfskmscursor.cpp +SOURCES += $$PWD/qeglfskmsgbmmain.cpp \ + $$PWD/qeglfskmsgbmintegration.cpp \ + $$PWD/qeglfskmsgbmdevice.cpp \ + $$PWD/qeglfskmsgbmscreen.cpp \ + $$PWD/qeglfskmsgbmcursor.cpp -HEADERS += $$PWD/qeglfskmsintegration.h \ - $$PWD/qeglfskmsdevice.h \ - $$PWD/qeglfskmsscreen.h \ - $$PWD/qeglfskmscursor.h +HEADERS += $$PWD/qeglfskmsgbmintegration.h \ + $$PWD/qeglfskmsgbmdevice.h \ + $$PWD/qeglfskmsgbmscreen.h \ + $$PWD/qeglfskmsgbmcursor.h OTHER_FILES += $$PWD/eglfs_kms.json - -PLUGIN_TYPE = egldeviceintegrations -PLUGIN_CLASS_NAME = QEglFSKmsIntegrationPlugin -load(qt_plugin) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp deleted file mode 100644 index 8ba0a5cdd0..0000000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp +++ /dev/null @@ -1,451 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeglfskmsdevice.h" -#include "qeglfskmsscreen.h" - -#include "qeglfsintegration.h" - -#include <QtCore/QLoggingCategory> -#include <QtCore/private/qcore_unix_p.h> -#include <QtGui/private/qguiapplication_p.h> - -#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[] = { - "None", - "VGA", - "DVI", - "DVI", - "DVI", - "Composite", - "TV", - "LVDS", - "CTV", - "DIN", - "DP", - "HDMI", - "HDMI", - "TV", - "eDP", -}; - -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::screenForConnector(drmModeResPtr resources, drmModeConnectorPtr connector, QPoint pos) -{ - 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; - - const QByteArray mode = m_integration->outputSettings().value(QString::fromUtf8(connectorName)) - .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; - } - - 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<drmModeModeInfo> 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; - } - - QEglFSKmsOutput output = { - QString::fromUtf8(connectorName), - connector->connector_id, - crtc_id, - QSizeF(connector->mmWidth, connector->mmHeight), - 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 new QEglFSKmsScreen(m_integration, this, output, pos); -} - -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; -} - -void QEglFSKmsDevice::pageFlipHandler(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data) -{ - Q_UNUSED(fd); - Q_UNUSED(sequence); - Q_UNUSED(tv_sec); - Q_UNUSED(tv_usec); - - QEglFSKmsScreen *screen = static_cast<QEglFSKmsScreen *>(user_data); - screen->flipFinished(); -} - -QEglFSKmsDevice::QEglFSKmsDevice(QEglFSKmsIntegration *integration, const QString &path) - : m_integration(integration) - , m_path(path) - , m_dri_fd(-1) - , m_gbm_device(Q_NULLPTR) - , m_crtc_allocator(0) - , m_connector_allocator(0) - , m_globalCursor(Q_NULLPTR) -{ -} - -bool QEglFSKmsDevice::open() -{ - Q_ASSERT(m_dri_fd == -1); - Q_ASSERT(m_gbm_device == Q_NULLPTR); - - qCDebug(qLcEglfsKmsDebug) << "Opening device" << m_path; - m_dri_fd = qt_safe_open(m_path.toLocal8Bit().constData(), O_RDWR | O_CLOEXEC); - if (m_dri_fd == -1) { - qErrnoWarning("Could not open DRM device %s", qPrintable(m_path)); - return false; - } - - qCDebug(qLcEglfsKmsDebug) << "Creating GBM device for file descriptor" << m_dri_fd - << "obtained from" << m_path; - m_gbm_device = gbm_create_device(m_dri_fd); - if (!m_gbm_device) { - qErrnoWarning("Could not create GBM device"); - qt_safe_close(m_dri_fd); - m_dri_fd = -1; - return false; - } - - return true; -} - -void QEglFSKmsDevice::close() -{ - if (m_gbm_device) { - gbm_device_destroy(m_gbm_device); - m_gbm_device = Q_NULLPTR; - } - - if (m_dri_fd != -1) { - qt_safe_close(m_dri_fd); - m_dri_fd = -1; - } - - if (m_globalCursor) - m_globalCursor->deleteLater(); - m_globalCursor = Q_NULLPTR; -} - -void QEglFSKmsDevice::createScreens() -{ - drmModeResPtr resources = drmModeGetResources(m_dri_fd); - if (!resources) { - qWarning("drmModeGetResources failed"); - return; - } - - QEglFSKmsScreen *primaryScreen = Q_NULLPTR; - QList<QPlatformScreen *> siblings; - QPoint pos(0, 0); - QEglFSIntegration *integration = static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration()); - - for (int i = 0; i < resources->count_connectors; i++) { - drmModeConnectorPtr connector = drmModeGetConnector(m_dri_fd, resources->connectors[i]); - if (!connector) - continue; - - QEglFSKmsScreen *screen = screenForConnector(resources, connector, pos); - if (screen) { - integration->addScreen(screen); - pos.rx() += screen->geometry().width(); - siblings << screen; - - if (!primaryScreen) - primaryScreen = screen; - } - - drmModeFreeConnector(connector); - } - - drmModeFreeResources(resources); - - if (!m_integration->separateScreens()) { - Q_FOREACH (QPlatformScreen *screen, siblings) - static_cast<QEglFSKmsScreen *>(screen)->setVirtualSiblings(siblings); - - if (primaryScreen && m_integration->hwCursor()) - m_globalCursor = new QEglFSKmsCursor(primaryScreen); - } -} - -gbm_device *QEglFSKmsDevice::device() const -{ - return m_gbm_device; -} - -int QEglFSKmsDevice::fd() const -{ - return m_dri_fd; -} - -QPlatformCursor *QEglFSKmsDevice::globalCursor() const -{ - return m_globalCursor; -} - -void QEglFSKmsDevice::handleDrmEvent() -{ - drmEventContext drmEvent = { - DRM_EVENT_CONTEXT_VERSION, - Q_NULLPTR, // vblank handler - pageFlipHandler // page flip handler - }; - - drmHandleEvent(m_dri_fd, &drmEvent); -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.h deleted file mode 100644 index 411f9a7200..0000000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QEGLFSKMSDEVICE_H -#define QEGLFSKMSDEVICE_H - -#include "qeglfskmscursor.h" -#include "qeglfskmsintegration.h" - -#include <xf86drm.h> -#include <xf86drmMode.h> -#include <gbm.h> - -QT_BEGIN_NAMESPACE - -class QEglFSKmsScreen; - -class QEglFSKmsDevice -{ -public: - QEglFSKmsDevice(QEglFSKmsIntegration *integration, const QString &path); - - bool open(); - void close(); - - void createScreens(); - - gbm_device *device() const; - int fd() const; - - QPlatformCursor *globalCursor() const; - - void handleDrmEvent(); - -private: - Q_DISABLE_COPY(QEglFSKmsDevice) - - QEglFSKmsIntegration *m_integration; - QString m_path; - int m_dri_fd; - gbm_device *m_gbm_device; - - quint32 m_crtc_allocator; - quint32 m_connector_allocator; - - QEglFSKmsCursor *m_globalCursor; - - int crtcForConnector(drmModeResPtr resources, drmModeConnectorPtr connector); - QEglFSKmsScreen *screenForConnector(drmModeResPtr resources, drmModeConnectorPtr connector, QPoint pos); - 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); -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp index bcc908905c..5b779d6732 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp @@ -2,39 +2,46 @@ ** ** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> ** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2016 Pelagicore AG +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "qeglfskmscursor.h" -#include "qeglfskmsscreen.h" -#include "qeglfskmsdevice.h" +#include "qeglfskmsgbmcursor.h" +#include "qeglfskmsgbmscreen.h" +#include "qeglfskmsgbmdevice.h" #include <QtCore/QJsonDocument> #include <QtCore/QJsonObject> @@ -58,7 +65,7 @@ QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug) -QEglFSKmsCursor::QEglFSKmsCursor(QEglFSKmsScreen *screen) +QEglFSKmsGbmCursor::QEglFSKmsGbmCursor(QEglFSKmsGbmScreen *screen) : m_screen(screen) , m_cursorSize(64, 64) // 64x64 is the old standard size, we now try to query the real size below , m_bo(Q_NULLPTR) @@ -78,7 +85,7 @@ QEglFSKmsCursor::QEglFSKmsCursor(QEglFSKmsScreen *screen) m_cursorSize.setHeight(height); } - m_bo = gbm_bo_create(m_screen->device()->device(), m_cursorSize.width(), m_cursorSize.height(), + m_bo = gbm_bo_create(static_cast<QEglFSKmsGbmDevice *>(m_screen->device())->gbmDevice(), m_cursorSize.width(), m_cursorSize.height(), GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE); if (!m_bo) { qWarning("Could not create buffer for cursor!"); @@ -86,9 +93,9 @@ QEglFSKmsCursor::QEglFSKmsCursor(QEglFSKmsScreen *screen) initCursorAtlas(); } - m_deviceListener = new QEglFSKmsCursorDeviceListener(this); + m_deviceListener = new QEglFSKmsGbmCursorDeviceListener(this); connect(QGuiApplicationPrivate::inputDeviceManager(), &QInputDeviceManager::deviceListChanged, - m_deviceListener, &QEglFSKmsCursorDeviceListener::onDeviceListChanged); + m_deviceListener, &QEglFSKmsGbmCursorDeviceListener::onDeviceListChanged); if (!m_deviceListener->hasMouse()) m_state = CursorPendingHidden; @@ -99,7 +106,7 @@ QEglFSKmsCursor::QEglFSKmsCursor(QEglFSKmsScreen *screen) setPos(QPoint(0, 0)); } -QEglFSKmsCursor::~QEglFSKmsCursor() +QEglFSKmsGbmCursor::~QEglFSKmsGbmCursor() { delete m_deviceListener; @@ -115,7 +122,7 @@ QEglFSKmsCursor::~QEglFSKmsCursor() } } -void QEglFSKmsCursor::updateMouseStatus() +void QEglFSKmsGbmCursor::updateMouseStatus() { const bool wasVisible = m_state == CursorVisible; const bool visible = m_deviceListener->hasMouse(); @@ -129,24 +136,24 @@ void QEglFSKmsCursor::updateMouseStatus() #endif } -bool QEglFSKmsCursorDeviceListener::hasMouse() const +bool QEglFSKmsGbmCursorDeviceListener::hasMouse() const { return QGuiApplicationPrivate::inputDeviceManager()->deviceCount(QInputDeviceManager::DeviceTypePointer) > 0; } -void QEglFSKmsCursorDeviceListener::onDeviceListChanged(QInputDeviceManager::DeviceType type) +void QEglFSKmsGbmCursorDeviceListener::onDeviceListChanged(QInputDeviceManager::DeviceType type) { - if (type == QInputDeviceManager::DeviceTypePointer) + if (type == QInputDeviceManager::DeviceTypePointer) m_cursor->updateMouseStatus(); } -void QEglFSKmsCursor::pointerEvent(const QMouseEvent &event) +void QEglFSKmsGbmCursor::pointerEvent(const QMouseEvent &event) { setPos(event.screenPos().toPoint()); } #ifndef QT_NO_CURSOR -void QEglFSKmsCursor::changeCursor(QCursor *windowCursor, QWindow *window) +void QEglFSKmsGbmCursor::changeCursor(QCursor *windowCursor, QWindow *window) { Q_UNUSED(window); @@ -215,12 +222,12 @@ void QEglFSKmsCursor::changeCursor(QCursor *windowCursor, QWindow *window) } #endif // QT_NO_CURSOR -QPoint QEglFSKmsCursor::pos() const +QPoint QEglFSKmsGbmCursor::pos() const { return m_pos; } -void QEglFSKmsCursor::setPos(const QPoint &pos) +void QEglFSKmsGbmCursor::setPos(const QPoint &pos) { Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { QEglFSKmsScreen *kmsScreen = static_cast<QEglFSKmsScreen *>(screen); @@ -236,7 +243,7 @@ void QEglFSKmsCursor::setPos(const QPoint &pos) } } -void QEglFSKmsCursor::initCursorAtlas() +void QEglFSKmsGbmCursor::initCursorAtlas() { static QByteArray json = qgetenv("QT_QPA_EGLFS_CURSOR"); if (json.isEmpty()) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h index f26df91be5..de13a058cf 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h @@ -1,38 +1,44 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ -#ifndef QEGLFSKMSCURSOR_H -#define QEGLFSKMSCURSOR_H +#ifndef QEGLFSKMSGBMCURSOR_H +#define QEGLFSKMSGBMCURSOR_H #include <qpa/qplatformcursor.h> #include <QtCore/QList> @@ -43,31 +49,31 @@ QT_BEGIN_NAMESPACE -class QEglFSKmsScreen; -class QEglFSKmsCursor; +class QEglFSKmsGbmScreen; +class QEglFSKmsGbmCursor; -class QEglFSKmsCursorDeviceListener : public QObject +class QEglFSKmsGbmCursorDeviceListener : public QObject { Q_OBJECT public: - QEglFSKmsCursorDeviceListener(QEglFSKmsCursor *cursor) : m_cursor(cursor) { } + QEglFSKmsGbmCursorDeviceListener(QEglFSKmsGbmCursor *cursor) : m_cursor(cursor) { } bool hasMouse() const; public slots: void onDeviceListChanged(QInputDeviceManager::DeviceType type); private: - QEglFSKmsCursor *m_cursor; + QEglFSKmsGbmCursor *m_cursor; }; -class QEglFSKmsCursor : public QPlatformCursor +class QEglFSKmsGbmCursor : public QPlatformCursor { Q_OBJECT public: - QEglFSKmsCursor(QEglFSKmsScreen *screen); - ~QEglFSKmsCursor(); + QEglFSKmsGbmCursor(QEglFSKmsGbmScreen *screen); + ~QEglFSKmsGbmCursor(); // input methods void pointerEvent(const QMouseEvent & event) Q_DECL_OVERRIDE; @@ -90,13 +96,13 @@ private: CursorVisible }; - QEglFSKmsScreen *m_screen; + QEglFSKmsGbmScreen *m_screen; QSize m_cursorSize; gbm_bo *m_bo; QPoint m_pos; QPlatformCursorImage m_cursorImage; CursorState m_state; - QEglFSKmsCursorDeviceListener *m_deviceListener; + QEglFSKmsGbmCursorDeviceListener *m_deviceListener; // cursor atlas information struct CursorAtlas { @@ -111,4 +117,4 @@ private: QT_END_NAMESPACE -#endif +#endif // QEGLFSKMSGBMCURSOR_H diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp new file mode 100644 index 0000000000..278752bddf --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> +** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2016 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qeglfskmsgbmdevice.h" +#include "qeglfskmsgbmscreen.h" + +#include "qeglfsintegration.h" + +#include <QtCore/QLoggingCategory> +#include <QtCore/private/qcore_unix_p.h> +#include <QtGui/private/qguiapplication_p.h> + +#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0]) + +QT_BEGIN_NAMESPACE + +Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug) + +void QEglFSKmsGbmDevice::pageFlipHandler(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data) +{ + Q_UNUSED(fd); + Q_UNUSED(sequence); + Q_UNUSED(tv_sec); + Q_UNUSED(tv_usec); + + QEglFSKmsScreen *screen = static_cast<QEglFSKmsScreen *>(user_data); + screen->flipFinished(); +} + +QEglFSKmsGbmDevice::QEglFSKmsGbmDevice(QEglFSKmsIntegration *integration, const QString &path) + : QEglFSKmsDevice(integration, path) + , m_gbm_device(Q_NULLPTR) + , m_globalCursor(Q_NULLPTR) +{ +} + +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())); + return false; + } + + qCDebug(qLcEglfsKmsDebug) << "Creating GBM device for file descriptor" << fd + << "obtained from" << devicePath(); + m_gbm_device = gbm_create_device(fd); + if (!m_gbm_device) { + qErrnoWarning("Could not create GBM device"); + qt_safe_close(fd); + fd = -1; + return false; + } + + setFd(fd); + + return true; +} + +void QEglFSKmsGbmDevice::close() +{ + if (m_gbm_device) { + gbm_device_destroy(m_gbm_device); + m_gbm_device = Q_NULLPTR; + } + + if (fd() != -1) { + qt_safe_close(fd()); + setFd(-1); + } + + if (m_globalCursor) + m_globalCursor->deleteLater(); + m_globalCursor = Q_NULLPTR; +} + +EGLNativeDisplayType QEglFSKmsGbmDevice::nativeDisplay() const +{ + return reinterpret_cast<EGLNativeDisplayType>(m_gbm_device); +} + +gbm_device * QEglFSKmsGbmDevice::gbmDevice() const +{ + return m_gbm_device; +} + +QPlatformCursor *QEglFSKmsGbmDevice::globalCursor() const +{ + return m_globalCursor; +} + +void QEglFSKmsGbmDevice::handleDrmEvent() +{ + drmEventContext drmEvent = { + DRM_EVENT_CONTEXT_VERSION, + Q_NULLPTR, // vblank handler + pageFlipHandler // page flip handler + }; + + drmHandleEvent(fd(), &drmEvent); +} + +QEglFSKmsScreen *QEglFSKmsGbmDevice::createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output, QPoint position) +{ + static bool firstScreen = true; + QEglFSKmsGbmScreen *screen = new QEglFSKmsGbmScreen(integration, device, output, position); + + if (firstScreen && integration->hwCursor()) { + m_globalCursor = new QEglFSKmsGbmCursor(screen); + firstScreen = false; + } + + return screen; +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h new file mode 100644 index 0000000000..6a45f9ffa0 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> +** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2016 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEGLFSKMSGBMDEVICE_H +#define QEGLFSKMSGBMDEVICE_H + +#include "qeglfskmsgbmcursor.h" +#include "qeglfskmsdevice.h" + +#include <gbm.h> + +QT_BEGIN_NAMESPACE + +class QEglFSKmsScreen; + +class QEglFSKmsGbmDevice: public QEglFSKmsDevice +{ +public: + QEglFSKmsGbmDevice(QEglFSKmsIntegration *integration, const QString &path); + + bool open() Q_DECL_OVERRIDE; + void close() Q_DECL_OVERRIDE; + + EGLNativeDisplayType nativeDisplay() const Q_DECL_OVERRIDE; + gbm_device *gbmDevice() const; + + QPlatformCursor *globalCursor() const; + + void handleDrmEvent(); + + virtual QEglFSKmsScreen *createScreen(QEglFSKmsIntegration *integration, + QEglFSKmsDevice *device, + QEglFSKmsOutput output, + QPoint position) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QEglFSKmsGbmDevice) + + gbm_device *m_gbm_device; + + QEglFSKmsGbmCursor *m_globalCursor; + + static void pageFlipHandler(int fd, + unsigned int sequence, + unsigned int tv_sec, + unsigned int tv_usec, + void *user_data); +}; + +QT_END_NAMESPACE + +#endif // QEGLFSKMSGBMDEVICE_H diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp new file mode 100644 index 0000000000..1c0a8e1b5f --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> +** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2016 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qeglfskmsgbmintegration.h" +#include "qeglfskmsgbmdevice.h" +#include "qeglfskmsgbmscreen.h" +#include "qeglfskmsgbmcursor.h" +#include "qeglfscursor.h" + +#include <QtPlatformSupport/private/qdevicediscovery_p.h> +#include <QtCore/QLoggingCategory> +#include <QtCore/QJsonDocument> +#include <QtCore/QJsonObject> +#include <QtCore/QJsonArray> +#include <QtGui/qpa/qplatformwindow.h> +#include <QtGui/qpa/qplatformcursor.h> +#include <QtGui/QScreen> + +#include <xf86drm.h> +#include <xf86drmMode.h> +#include <gbm.h> + +QT_BEGIN_NAMESPACE + +QMutex QEglFSKmsGbmScreen::m_waitForFlipMutex; + +QEglFSKmsGbmIntegration::QEglFSKmsGbmIntegration() + : QEglFSKmsIntegration() +{} + +EGLNativeWindowType QEglFSKmsGbmIntegration::createNativeWindow(QPlatformWindow *platformWindow, + const QSize &size, + const QSurfaceFormat &format) +{ + Q_UNUSED(size); + Q_UNUSED(format); + + QEglFSKmsGbmScreen *screen = static_cast<QEglFSKmsGbmScreen *>(platformWindow->screen()); + if (screen->surface()) { + qWarning("Only single window per screen supported!"); + return 0; + } + + return reinterpret_cast<EGLNativeWindowType>(screen->createSurface()); +} + +EGLNativeWindowType QEglFSKmsGbmIntegration::createNativeOffscreenWindow(const QSurfaceFormat &format) +{ + Q_UNUSED(format); + Q_ASSERT(device()); + + qCDebug(qLcEglfsKmsDebug) << "Creating native off screen window"; + gbm_surface *surface = gbm_surface_create(static_cast<QEglFSKmsGbmDevice *>(device())->gbmDevice(), + 1, 1, + GBM_FORMAT_XRGB8888, + GBM_BO_USE_RENDERING); + + return reinterpret_cast<EGLNativeWindowType>(surface); +} + +void QEglFSKmsGbmIntegration::destroyNativeWindow(EGLNativeWindowType window) +{ + gbm_surface *surface = reinterpret_cast<gbm_surface *>(window); + gbm_surface_destroy(surface); +} + +QPlatformCursor *QEglFSKmsGbmIntegration::createCursor(QPlatformScreen *screen) const +{ + if (hwCursor()) + return Q_NULLPTR; + else + return new QEglFSCursor(screen); +} + +void QEglFSKmsGbmIntegration::presentBuffer(QPlatformSurface *surface) +{ + QWindow *window = static_cast<QWindow *>(surface->surface()); + QEglFSKmsScreen *screen = static_cast<QEglFSKmsScreen *>(window->screen()->handle()); + + screen->flip(); +} + +QEglFSKmsDevice *QEglFSKmsGbmIntegration::createDevice(const QString &devicePath) +{ + QString path = devicePath; + if (!devicePath.isEmpty()) { + qCDebug(qLcEglfsKmsDebug) << "Using DRM device" << path << "specified in config file"; + } else { + + QDeviceDiscovery *d = QDeviceDiscovery::create(QDeviceDiscovery::Device_VideoMask); + QStringList devices = d->scanConnectedDevices(); + qCDebug(qLcEglfsKmsDebug) << "Found the following video devices:" << devices; + d->deleteLater(); + + if (Q_UNLIKELY(devices.isEmpty())) + qFatal("Could not find DRM device!"); + + path = devices.first(); + qCDebug(qLcEglfsKmsDebug) << "Using" << path; + } + + return new QEglFSKmsGbmDevice(this, 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 new file mode 100644 index 0000000000..727571d3e3 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> +** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2016 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEGLFSKMSGBMINTEGRATION_H +#define QEGLFSKMSGBMINTEGRATION_H + +#include "qeglfskmsintegration.h" +#include <QtCore/QMap> +#include <QtCore/QVariant> + +QT_BEGIN_NAMESPACE + +class QEglFSKmsDevice; + +class QEglFSKmsGbmIntegration : public QEglFSKmsIntegration +{ +public: + QEglFSKmsGbmIntegration(); + + EGLNativeWindowType createNativeWindow(QPlatformWindow *platformWindow, + const QSize &size, + const QSurfaceFormat &format) Q_DECL_OVERRIDE; + EGLNativeWindowType createNativeOffscreenWindow(const QSurfaceFormat &format) Q_DECL_OVERRIDE; + void destroyNativeWindow(EGLNativeWindowType window) Q_DECL_OVERRIDE; + + QPlatformCursor *createCursor(QPlatformScreen *screen) const Q_DECL_OVERRIDE; + void presentBuffer(QPlatformSurface *surface) Q_DECL_OVERRIDE; + +protected: + QEglFSKmsDevice *createDevice(const QString &devicePath) Q_DECL_OVERRIDE; + +private: +}; + +QT_END_NAMESPACE + +#endif // QEGLFSKMSGBMINTEGRATION_H diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmmain.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmmain.cpp new file mode 100644 index 0000000000..8e8779ca10 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmmain.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2016 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qeglfsdeviceintegration.h" +#include "qeglfskmsgbmintegration.h" + +QT_BEGIN_NAMESPACE + +class QEglFSKmsGbmIntegrationPlugin : public QEGLDeviceIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QEGLDeviceIntegrationFactoryInterface_iid FILE "eglfs_kms.json") + +public: + QEGLDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSKmsGbmIntegration; } +}; + +QT_END_NAMESPACE + +#include "qeglfskmsgbmmain.moc" diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp new file mode 100644 index 0000000000..7a17b60a5e --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp @@ -0,0 +1,223 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> +** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2016 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qeglfskmsgbmscreen.h" +#include "qeglfskmsgbmdevice.h" +#include "qeglfskmsgbmcursor.h" +#include "qeglfsintegration.h" + +#include <QtCore/QLoggingCategory> + +#include <QtGui/private/qguiapplication_p.h> +#include <QtPlatformSupport/private/qfbvthandler_p.h> + +QT_BEGIN_NAMESPACE + +Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug) + +void QEglFSKmsGbmScreen::bufferDestroyedHandler(gbm_bo *bo, void *data) +{ + FrameBuffer *fb = static_cast<FrameBuffer *>(data); + + if (fb->fb) { + gbm_device *device = gbm_bo_get_device(bo); + drmModeRmFB(gbm_device_get_fd(device), fb->fb); + } + + delete fb; +} + +QEglFSKmsGbmScreen::FrameBuffer *QEglFSKmsGbmScreen::framebufferForBufferObject(gbm_bo *bo) +{ + { + FrameBuffer *fb = static_cast<FrameBuffer *>(gbm_bo_get_user_data(bo)); + if (fb) + return fb; + } + + uint32_t width = gbm_bo_get_width(bo); + uint32_t height = gbm_bo_get_height(bo); + uint32_t stride = gbm_bo_get_stride(bo); + uint32_t handle = gbm_bo_get_handle(bo).u32; + + QScopedPointer<FrameBuffer> fb(new FrameBuffer); + + int ret = drmModeAddFB(device()->fd(), width, height, 24, 32, + stride, handle, &fb->fb); + + if (ret) { + qWarning("Failed to create KMS FB!"); + return Q_NULLPTR; + } + + gbm_bo_set_user_data(bo, fb.data(), bufferDestroyedHandler); + return fb.take(); +} + +QEglFSKmsGbmScreen::QEglFSKmsGbmScreen(QEglFSKmsIntegration *integration, + QEglFSKmsDevice *device, + QEglFSKmsOutput output, + QPoint position) + : QEglFSKmsScreen(integration, device, output, position) + , m_gbm_surface(Q_NULLPTR) + , m_gbm_bo_current(Q_NULLPTR) + , m_gbm_bo_next(Q_NULLPTR) + , m_cursor(Q_NULLPTR) +{ +} + +QEglFSKmsGbmScreen::~QEglFSKmsGbmScreen() +{ +} + +QPlatformCursor *QEglFSKmsGbmScreen::cursor() const +{ + if (integration()->hwCursor()) { + if (!integration()->separateScreens()) + return static_cast<QEglFSKmsGbmDevice *>(device())->globalCursor(); + + if (m_cursor.isNull()) { + QEglFSKmsGbmScreen *that = const_cast<QEglFSKmsGbmScreen *>(this); + that->m_cursor.reset(new QEglFSKmsGbmCursor(that)); + } + + return m_cursor.data(); + } else { + return QEglFSScreen::cursor(); + } +} + +gbm_surface *QEglFSKmsGbmScreen::createSurface() +{ + if (!m_gbm_surface) { + qCDebug(qLcEglfsKmsDebug) << "Creating window for screen" << name(); + m_gbm_surface = gbm_surface_create(static_cast<QEglFSKmsGbmDevice *>(device())->gbmDevice(), + geometry().width(), + geometry().height(), + GBM_FORMAT_XRGB8888, + GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); + } + return m_gbm_surface; +} + +void QEglFSKmsGbmScreen::destroySurface() +{ + if (m_gbm_bo_current) { + gbm_bo_destroy(m_gbm_bo_current); + m_gbm_bo_current = Q_NULLPTR; + } + + if (m_gbm_bo_next) { + gbm_bo_destroy(m_gbm_bo_next); + m_gbm_bo_next = Q_NULLPTR; + } + + if (m_gbm_surface) { + gbm_surface_destroy(m_gbm_surface); + m_gbm_surface = Q_NULLPTR; + } +} + +void QEglFSKmsGbmScreen::waitForFlip() +{ + // Don't lock the mutex unless we actually need to + if (!m_gbm_bo_next) + return; + + QMutexLocker lock(&m_waitForFlipMutex); + while (m_gbm_bo_next) + static_cast<QEglFSKmsGbmDevice *>(device())->handleDrmEvent(); +} + +void QEglFSKmsGbmScreen::flip() +{ + if (!m_gbm_surface) { + qWarning("Cannot sync before platform init!"); + return; + } + + m_gbm_bo_next = gbm_surface_lock_front_buffer(m_gbm_surface); + if (!m_gbm_bo_next) { + qWarning("Could not lock GBM surface front buffer!"); + return; + } + + FrameBuffer *fb = framebufferForBufferObject(m_gbm_bo_next); + + if (!output().mode_set) { + int ret = drmModeSetCrtc(device()->fd(), + output().crtc_id, + fb->fb, + 0, 0, + &output().connector_id, 1, + &output().modes[output().mode]); + + if (ret) { + qErrnoWarning("Could not set DRM mode!"); + } else { + output().mode_set = true; + setPowerState(PowerStateOn); + } + } + + int ret = drmModePageFlip(device()->fd(), + output().crtc_id, + fb->fb, + DRM_MODE_PAGE_FLIP_EVENT, + this); + if (ret) { + qErrnoWarning("Could not queue DRM page flip!"); + gbm_surface_release_buffer(m_gbm_surface, m_gbm_bo_next); + m_gbm_bo_next = Q_NULLPTR; + } +} + +void QEglFSKmsGbmScreen::flipFinished() +{ + if (m_gbm_bo_current) + gbm_surface_release_buffer(m_gbm_surface, + m_gbm_bo_current); + + m_gbm_bo_current = m_gbm_bo_next; + m_gbm_bo_next = Q_NULLPTR; +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h new file mode 100644 index 0000000000..3381bbfdbb --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> +** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2016 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEGLFSKMSGBMSCREEN_H +#define QEGLFSKMSGBMSCREEN_H + +#include "qeglfskmsscreen.h" +#include <QtCore/QMutex> + +#include <gbm.h> + +QT_BEGIN_NAMESPACE + +class QEglFSKmsGbmCursor; + +class QEglFSKmsGbmScreen : public QEglFSKmsScreen +{ +public: + QEglFSKmsGbmScreen(QEglFSKmsIntegration *integration, + QEglFSKmsDevice *device, + QEglFSKmsOutput output, + QPoint position); + ~QEglFSKmsGbmScreen(); + + QPlatformCursor *cursor() const Q_DECL_OVERRIDE; + + gbm_surface *surface() const { return m_gbm_surface; } + gbm_surface *createSurface(); + void destroySurface(); + + void waitForFlip() Q_DECL_OVERRIDE; + void flip() Q_DECL_OVERRIDE; + void flipFinished() Q_DECL_OVERRIDE; + +private: + gbm_surface *m_gbm_surface; + + gbm_bo *m_gbm_bo_current; + gbm_bo *m_gbm_bo_next; + + QScopedPointer<QEglFSKmsGbmCursor> m_cursor; + + struct FrameBuffer { + FrameBuffer() : fb(0) {} + uint32_t fb; + }; + static void bufferDestroyedHandler(gbm_bo *bo, void *data); + FrameBuffer *framebufferForBufferObject(gbm_bo *bo); + + static QMutex m_waitForFlipMutex; +}; + +QT_END_NAMESPACE + +#endif // QEGLFSKMSGBMSCREEN_H diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp deleted file mode 100644 index d1814fb85d..0000000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp +++ /dev/null @@ -1,269 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeglfskmsintegration.h" -#include "qeglfskmsdevice.h" -#include "qeglfskmsscreen.h" -#include "qeglfskmscursor.h" -#include "qeglfscursor.h" - -#include <QtPlatformSupport/private/qdevicediscovery_p.h> -#include <QtCore/QLoggingCategory> -#include <QtCore/QJsonDocument> -#include <QtCore/QJsonObject> -#include <QtCore/QJsonArray> -#include <QtGui/qpa/qplatformwindow.h> -#include <QtGui/qpa/qplatformcursor.h> -#include <QtGui/QScreen> - -#include <xf86drm.h> -#include <xf86drmMode.h> -#include <gbm.h> - -QT_BEGIN_NAMESPACE - -Q_LOGGING_CATEGORY(qLcEglfsKmsDebug, "qt.qpa.eglfs.kms") - -QMutex QEglFSKmsScreen::m_waitForFlipMutex; - -QEglFSKmsIntegration::QEglFSKmsIntegration() - : m_device(Q_NULLPTR) - , m_hwCursor(true) - , m_pbuffers(false) - , m_separateScreens(false) -{} - -void QEglFSKmsIntegration::platformInit() -{ - loadConfig(); - - if (!m_devicePath.isEmpty()) { - qCDebug(qLcEglfsKmsDebug) << "Using DRM device" << m_devicePath << "specified in config file"; - } else { - - QDeviceDiscovery *d = QDeviceDiscovery::create(QDeviceDiscovery::Device_VideoMask); - QStringList devices = d->scanConnectedDevices(); - qCDebug(qLcEglfsKmsDebug) << "Found the following video devices:" << devices; - d->deleteLater(); - - if (devices.isEmpty()) - qFatal("Could not find DRM device!"); - - m_devicePath = devices.first(); - qCDebug(qLcEglfsKmsDebug) << "Using" << m_devicePath; - } - - m_device = new QEglFSKmsDevice(this, m_devicePath); - if (!m_device->open()) - qFatal("Could not open device %s - aborting!", qPrintable(m_devicePath)); -} - -void QEglFSKmsIntegration::platformDestroy() -{ - m_device->close(); - delete m_device; - m_device = Q_NULLPTR; -} - -EGLNativeDisplayType QEglFSKmsIntegration::platformDisplay() const -{ - Q_ASSERT(m_device); - return reinterpret_cast<EGLNativeDisplayType>(m_device->device()); -} - -bool QEglFSKmsIntegration::usesDefaultScreen() -{ - return false; -} - -void QEglFSKmsIntegration::screenInit() -{ - m_device->createScreens(); -} - -QSurfaceFormat QEglFSKmsIntegration::surfaceFormatFor(const QSurfaceFormat &inputFormat) const -{ - QSurfaceFormat format(inputFormat); - format.setRenderableType(QSurfaceFormat::OpenGLES); - format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); - format.setRedBufferSize(8); - format.setGreenBufferSize(8); - format.setBlueBufferSize(8); - return format; -} - -EGLNativeWindowType QEglFSKmsIntegration::createNativeWindow(QPlatformWindow *platformWindow, - const QSize &size, - const QSurfaceFormat &format) -{ - Q_UNUSED(size); - Q_UNUSED(format); - - QEglFSKmsScreen *screen = static_cast<QEglFSKmsScreen *>(platformWindow->screen()); - if (screen->surface()) { - qWarning("Only single window per screen supported!"); - return 0; - } - - return reinterpret_cast<EGLNativeWindowType>(screen->createSurface()); -} - -EGLNativeWindowType QEglFSKmsIntegration::createNativeOffscreenWindow(const QSurfaceFormat &format) -{ - Q_UNUSED(format); - Q_ASSERT(m_device); - - qCDebug(qLcEglfsKmsDebug) << "Creating native off screen window"; - gbm_surface *surface = gbm_surface_create(m_device->device(), - 1, 1, - GBM_FORMAT_XRGB8888, - GBM_BO_USE_RENDERING); - - return reinterpret_cast<EGLNativeWindowType>(surface); -} - -void QEglFSKmsIntegration::destroyNativeWindow(EGLNativeWindowType window) -{ - gbm_surface *surface = reinterpret_cast<gbm_surface *>(window); - gbm_surface_destroy(surface); -} - -bool QEglFSKmsIntegration::hasCapability(QPlatformIntegration::Capability cap) const -{ - switch (cap) { - case QPlatformIntegration::ThreadedPixmaps: - case QPlatformIntegration::OpenGL: - case QPlatformIntegration::ThreadedOpenGL: - return true; - default: - return false; - } -} - -QPlatformCursor *QEglFSKmsIntegration::createCursor(QPlatformScreen *screen) const -{ - if (m_hwCursor) - return Q_NULLPTR; - else - return new QEglFSCursor(screen); -} - -void QEglFSKmsIntegration::waitForVSync(QPlatformSurface *surface) const -{ - QWindow *window = static_cast<QWindow *>(surface->surface()); - QEglFSKmsScreen *screen = static_cast<QEglFSKmsScreen *>(window->screen()->handle()); - - screen->waitForFlip(); -} - -void QEglFSKmsIntegration::presentBuffer(QPlatformSurface *surface) -{ - QWindow *window = static_cast<QWindow *>(surface->surface()); - QEglFSKmsScreen *screen = static_cast<QEglFSKmsScreen *>(window->screen()->handle()); - - screen->flip(); -} - -bool QEglFSKmsIntegration::supportsPBuffers() const -{ - return m_pbuffers; -} - -bool QEglFSKmsIntegration::hwCursor() const -{ - return m_hwCursor; -} - -bool QEglFSKmsIntegration::separateScreens() const -{ - return m_separateScreens; -} - -QMap<QString, QVariantMap> QEglFSKmsIntegration::outputSettings() const -{ - return m_outputSettings; -} - -void QEglFSKmsIntegration::loadConfig() -{ - 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)) { - qCDebug(qLcEglfsKmsDebug) << "Could not open config file" - << json << "for reading"; - return; - } - - const QJsonDocument doc = QJsonDocument::fromJson(file.readAll()); - if (!doc.isObject()) { - qCDebug(qLcEglfsKmsDebug) << "Invalid config file" << json - << "- no top-level JSON object"; - return; - } - - const QJsonObject object = doc.object(); - - m_hwCursor = object.value(QStringLiteral("hwcursor")).toBool(m_hwCursor); - m_pbuffers = object.value(QStringLiteral("pbuffers")).toBool(m_pbuffers); - m_devicePath = object.value(QStringLiteral("device")).toString(); - m_separateScreens = object.value(QStringLiteral("separateScreens")).toBool(m_separateScreens); - - const QJsonArray outputs = object.value(QStringLiteral("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" - << "\toutputs:" << m_outputSettings; -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.h deleted file mode 100644 index edb6906a4b..0000000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.h +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QEGLFSKMSINTEGRATION_H -#define QEGLFSKMSINTEGRATION_H - -#include "qeglfsdeviceintegration.h" -#include <QtCore/QMap> -#include <QtCore/QVariant> - -QT_BEGIN_NAMESPACE - -class QEglFSKmsDevice; - -class QEglFSKmsIntegration : public QEGLDeviceIntegration -{ -public: - QEglFSKmsIntegration(); - - void platformInit() Q_DECL_OVERRIDE; - void platformDestroy() Q_DECL_OVERRIDE; - EGLNativeDisplayType platformDisplay() const Q_DECL_OVERRIDE; - bool usesDefaultScreen() Q_DECL_OVERRIDE; - void screenInit() Q_DECL_OVERRIDE; - QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const Q_DECL_OVERRIDE; - EGLNativeWindowType createNativeWindow(QPlatformWindow *platformWindow, - const QSize &size, - const QSurfaceFormat &format) Q_DECL_OVERRIDE; - EGLNativeWindowType createNativeOffscreenWindow(const QSurfaceFormat &format) Q_DECL_OVERRIDE; - void destroyNativeWindow(EGLNativeWindowType window) Q_DECL_OVERRIDE; - bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE; - QPlatformCursor *createCursor(QPlatformScreen *screen) const Q_DECL_OVERRIDE; - void waitForVSync(QPlatformSurface *surface) const Q_DECL_OVERRIDE; - void presentBuffer(QPlatformSurface *surface) Q_DECL_OVERRIDE; - bool supportsPBuffers() const Q_DECL_OVERRIDE; - - bool hwCursor() const; - bool separateScreens() const; - QMap<QString, QVariantMap> outputSettings() const; - -private: - void loadConfig(); - - QEglFSKmsDevice *m_device; - bool m_hwCursor; - bool m_pbuffers; - bool m_separateScreens; - QString m_devicePath; - QMap<QString, QVariantMap> m_outputSettings; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsmain.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsmain.cpp deleted file mode 100644 index 64a0bedb2c..0000000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsmain.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the qmake spec of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeglfsdeviceintegration.h" -#include "qeglfskmsintegration.h" - -QT_BEGIN_NAMESPACE - -class QEglFSKmsIntegrationPlugin : public QEGLDeviceIntegrationPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID QEGLDeviceIntegrationFactoryInterface_iid FILE "eglfs_kms.json") - -public: - QEGLDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSKmsIntegration; } -}; - -QT_END_NAMESPACE - -#include "qeglfskmsmain.moc" diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp deleted file mode 100644 index 048f5433dc..0000000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp +++ /dev/null @@ -1,353 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeglfskmsscreen.h" -#include "qeglfskmsdevice.h" -#include "qeglfskmscursor.h" -#include "qeglfsintegration.h" - -#include <QtCore/QLoggingCategory> - -#include <QtGui/private/qguiapplication_p.h> -#include <QtPlatformSupport/private/qfbvthandler_p.h> - -QT_BEGIN_NAMESPACE - -Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug) - -class QEglFSKmsInterruptHandler : public QObject -{ -public: - QEglFSKmsInterruptHandler(QEglFSKmsScreen *screen) : m_screen(screen) { - m_vtHandler = static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration())->vtHandler(); - connect(m_vtHandler, &QFbVtHandler::interrupted, this, &QEglFSKmsInterruptHandler::restoreVideoMode); - connect(m_vtHandler, &QFbVtHandler::aboutToSuspend, this, &QEglFSKmsInterruptHandler::restoreVideoMode); - } - -public slots: - void restoreVideoMode() { m_screen->restoreMode(); } - -private: - QFbVtHandler *m_vtHandler; - QEglFSKmsScreen *m_screen; -}; - -void QEglFSKmsScreen::bufferDestroyedHandler(gbm_bo *bo, void *data) -{ - FrameBuffer *fb = static_cast<FrameBuffer *>(data); - - if (fb->fb) { - gbm_device *device = gbm_bo_get_device(bo); - drmModeRmFB(gbm_device_get_fd(device), fb->fb); - } - - delete fb; -} - -QEglFSKmsScreen::FrameBuffer *QEglFSKmsScreen::framebufferForBufferObject(gbm_bo *bo) -{ - { - FrameBuffer *fb = static_cast<FrameBuffer *>(gbm_bo_get_user_data(bo)); - if (fb) - return fb; - } - - uint32_t width = gbm_bo_get_width(bo); - uint32_t height = gbm_bo_get_height(bo); - uint32_t stride = gbm_bo_get_stride(bo); - uint32_t handle = gbm_bo_get_handle(bo).u32; - - QScopedPointer<FrameBuffer> fb(new FrameBuffer); - - int ret = drmModeAddFB(m_device->fd(), width, height, 24, 32, - stride, handle, &fb->fb); - - if (ret) { - qWarning("Failed to create KMS FB!"); - return Q_NULLPTR; - } - - gbm_bo_set_user_data(bo, fb.data(), bufferDestroyedHandler); - return fb.take(); -} - -QEglFSKmsScreen::QEglFSKmsScreen(QEglFSKmsIntegration *integration, - QEglFSKmsDevice *device, - QEglFSKmsOutput output, - QPoint position) - : QEglFSScreen(eglGetDisplay(reinterpret_cast<EGLNativeDisplayType>(device->device()))) - , m_integration(integration) - , m_device(device) - , m_gbm_surface(Q_NULLPTR) - , m_gbm_bo_current(Q_NULLPTR) - , m_gbm_bo_next(Q_NULLPTR) - , m_output(output) - , m_pos(position) - , m_cursor(Q_NULLPTR) - , m_powerState(PowerStateOn) - , m_interruptHandler(new QEglFSKmsInterruptHandler(this)) -{ - m_siblings << this; -} - -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; - } - delete m_interruptHandler; -} - -QRect QEglFSKmsScreen::geometry() const -{ - const int mode = m_output.mode; - return QRect(m_pos.x(), m_pos.y(), - m_output.modes[mode].hdisplay, - m_output.modes[mode].vdisplay); -} - -int QEglFSKmsScreen::depth() const -{ - return 32; -} - -QImage::Format QEglFSKmsScreen::format() const -{ - return QImage::Format_RGB32; -} - -QSizeF QEglFSKmsScreen::physicalSize() const -{ - return m_output.physical_size; -} - -QDpi QEglFSKmsScreen::logicalDpi() const -{ - const QSizeF ps = physicalSize(); - const QSize s = geometry().size(); - - if (!ps.isEmpty() && !s.isEmpty()) - return QDpi(25.4 * s.width() / ps.width(), - 25.4 * s.height() / ps.height()); - else - return QDpi(100, 100); -} - -Qt::ScreenOrientation QEglFSKmsScreen::nativeOrientation() const -{ - return Qt::PrimaryOrientation; -} - -Qt::ScreenOrientation QEglFSKmsScreen::orientation() const -{ - return Qt::PrimaryOrientation; -} - -QString QEglFSKmsScreen::name() const -{ - return m_output.name; -} - -QPlatformCursor *QEglFSKmsScreen::cursor() const -{ - if (m_integration->hwCursor()) { - if (!m_integration->separateScreens()) - return m_device->globalCursor(); - - if (m_cursor.isNull()) { - QEglFSKmsScreen *that = const_cast<QEglFSKmsScreen *>(this); - that->m_cursor.reset(new QEglFSKmsCursor(that)); - } - - return m_cursor.data(); - } else { - return QEglFSScreen::cursor(); - } -} - -gbm_surface *QEglFSKmsScreen::createSurface() -{ - if (!m_gbm_surface) { - qCDebug(qLcEglfsKmsDebug) << "Creating window for screen" << name(); - m_gbm_surface = gbm_surface_create(m_device->device(), - geometry().width(), - geometry().height(), - GBM_FORMAT_XRGB8888, - GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); - } - return m_gbm_surface; -} - -void QEglFSKmsScreen::destroySurface() -{ - if (m_gbm_bo_current) { - gbm_bo_destroy(m_gbm_bo_current); - m_gbm_bo_current = Q_NULLPTR; - } - - if (m_gbm_bo_next) { - gbm_bo_destroy(m_gbm_bo_next); - m_gbm_bo_next = Q_NULLPTR; - } - - if (m_gbm_surface) { - gbm_surface_destroy(m_gbm_surface); - m_gbm_surface = Q_NULLPTR; - } -} - -void QEglFSKmsScreen::waitForFlip() -{ - // Don't lock the mutex unless we actually need to - if (!m_gbm_bo_next) - return; - - QMutexLocker lock(&m_waitForFlipMutex); - while (m_gbm_bo_next) - m_device->handleDrmEvent(); -} - -void QEglFSKmsScreen::flip() -{ - if (!m_gbm_surface) { - qWarning("Cannot sync before platform init!"); - return; - } - - m_gbm_bo_next = gbm_surface_lock_front_buffer(m_gbm_surface); - if (!m_gbm_bo_next) { - qWarning("Could not lock GBM surface front buffer!"); - return; - } - - FrameBuffer *fb = framebufferForBufferObject(m_gbm_bo_next); - - if (!m_output.mode_set) { - int ret = drmModeSetCrtc(m_device->fd(), - m_output.crtc_id, - fb->fb, - 0, 0, - &m_output.connector_id, 1, - &m_output.modes[m_output.mode]); - - if (ret) { - qErrnoWarning("Could not set DRM mode!"); - } else { - m_output.mode_set = true; - setPowerState(PowerStateOn); - } - } - - int ret = drmModePageFlip(m_device->fd(), - m_output.crtc_id, - fb->fb, - DRM_MODE_PAGE_FLIP_EVENT, - this); - if (ret) { - qErrnoWarning("Could not queue DRM page flip!"); - gbm_surface_release_buffer(m_gbm_surface, m_gbm_bo_next); - m_gbm_bo_next = Q_NULLPTR; - } -} - -void QEglFSKmsScreen::flipFinished() -{ - if (m_gbm_bo_current) - gbm_surface_release_buffer(m_gbm_surface, - m_gbm_bo_current); - - m_gbm_bo_current = m_gbm_bo_next; - m_gbm_bo_next = Q_NULLPTR; -} - -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; - } -} - -qreal QEglFSKmsScreen::refreshRate() const -{ - quint32 refresh = m_output.modes[m_output.mode].vrefresh; - return refresh > 0 ? refresh : 60; -} - -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; - } -} - -QPlatformScreen::PowerState QEglFSKmsScreen::powerState() const -{ - return m_powerState; -} - -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_powerState = state; -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h deleted file mode 100644 index 7fd6ccaa31..0000000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h +++ /dev/null @@ -1,143 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QEGLFSKMSSCREEN_H -#define QEGLFSKMSSCREEN_H - -#include "qeglfskmsintegration.h" -#include "qeglfsscreen.h" -#include <QtCore/QList> -#include <QtCore/QMutex> - -#include <xf86drm.h> -#include <xf86drmMode.h> -#include <gbm.h> - -QT_BEGIN_NAMESPACE - -class QEglFSKmsDevice; -class QEglFSKmsCursor; -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<drmModeModeInfo> modes; - int subpixel; - drmModePropertyPtr dpms_prop; -}; - -class QEglFSKmsScreen : public QEglFSScreen -{ -public: - QEglFSKmsScreen(QEglFSKmsIntegration *integration, - QEglFSKmsDevice *device, - QEglFSKmsOutput output, - QPoint position); - ~QEglFSKmsScreen(); - - QRect geometry() const Q_DECL_OVERRIDE; - int depth() const Q_DECL_OVERRIDE; - QImage::Format format() const Q_DECL_OVERRIDE; - - QSizeF physicalSize() const Q_DECL_OVERRIDE; - QDpi logicalDpi() const Q_DECL_OVERRIDE; - Qt::ScreenOrientation nativeOrientation() const Q_DECL_OVERRIDE; - Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE; - - QString name() const Q_DECL_OVERRIDE; - - QPlatformCursor *cursor() const Q_DECL_OVERRIDE; - - qreal refreshRate() const Q_DECL_OVERRIDE; - - QList<QPlatformScreen *> virtualSiblings() const Q_DECL_OVERRIDE { return m_siblings; } - void setVirtualSiblings(QList<QPlatformScreen *> sl) { m_siblings = sl; } - - QEglFSKmsIntegration *integration() const { return m_integration; } - QEglFSKmsDevice *device() const { return m_device; } - - gbm_surface *surface() const { return m_gbm_surface; } - gbm_surface *createSurface(); - void destroySurface(); - - void waitForFlip(); - void flip(); - void flipFinished(); - - QEglFSKmsOutput &output() { return m_output; } - void restoreMode(); - - SubpixelAntialiasingType subpixelAntialiasingTypeHint() const Q_DECL_OVERRIDE; - - QPlatformScreen::PowerState powerState() const Q_DECL_OVERRIDE; - void setPowerState(QPlatformScreen::PowerState state) Q_DECL_OVERRIDE; - -private: - QEglFSKmsIntegration *m_integration; - QEglFSKmsDevice *m_device; - gbm_surface *m_gbm_surface; - - gbm_bo *m_gbm_bo_current; - gbm_bo *m_gbm_bo_next; - - QEglFSKmsOutput m_output; - QPoint m_pos; - QScopedPointer<QEglFSKmsCursor> m_cursor; - - QList<QPlatformScreen *> m_siblings; - - PowerState m_powerState; - - struct FrameBuffer { - FrameBuffer() : fb(0) {} - uint32_t fb; - }; - static void bufferDestroyedHandler(gbm_bo *bo, void *data); - FrameBuffer *framebufferForBufferObject(gbm_bo *bo); - - static QMutex m_waitForFlipMutex; - - QEglFSKmsInterruptHandler *m_interruptHandler; -}; - -QT_END_NAMESPACE - -#endif |