diff options
Diffstat (limited to 'src/plugins/platforms/eglfs/deviceintegration/eglfs_kms')
18 files changed, 681 insertions, 837 deletions
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/CMakeLists.txt b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/CMakeLists.txt new file mode 100644 index 0000000000..9f9d315202 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/CMakeLists.txt @@ -0,0 +1,49 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +##################################################################### +## EglFsKmsGbmSupportPrivate Module: +##################################################################### + +qt_internal_add_module(EglFsKmsGbmSupportPrivate + CONFIG_MODULE_NAME eglfs_kms_gbm_support + INTERNAL_MODULE + SOURCES + qeglfskmsgbmcursor.cpp qeglfskmsgbmcursor_p.h + qeglfskmsgbmdevice.cpp qeglfskmsgbmdevice_p.h + qeglfskmsgbmintegration.cpp qeglfskmsgbmintegration_p.h + qeglfskmsgbmscreen.cpp qeglfskmsgbmscreen_p.h + qeglfskmsgbmwindow.cpp qeglfskmsgbmwindow_p.h + DEFINES + QT_EGL_NO_X11 + PUBLIC_LIBRARIES + Libdrm::Libdrm + Qt::CorePrivate + Qt::EglFSDeviceIntegrationPrivate + Qt::EglFsKmsSupportPrivate + Qt::GuiPrivate + Qt::KmsSupportPrivate + gbm::gbm + NO_GENERATE_CPP_EXPORTS +) +##################################################################### +## QEglFSKmsGbmIntegrationPlugin Plugin: +##################################################################### + +qt_internal_add_plugin(QEglFSKmsGbmIntegrationPlugin + OUTPUT_NAME qeglfs-kms-integration + PLUGIN_TYPE egldeviceintegrations + SOURCES + qeglfskmsgbmmain.cpp + DEFINES + QT_EGL_NO_X11 + LIBRARIES + Libdrm::Libdrm + Qt::CorePrivate + Qt::EglFSDeviceIntegrationPrivate + Qt::EglFsKmsGbmSupportPrivate + Qt::EglFsKmsSupportPrivate + Qt::GuiPrivate + Qt::KmsSupportPrivate + gbm::gbm +) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro deleted file mode 100644 index f5c2c0ed89..0000000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro +++ /dev/null @@ -1,30 +0,0 @@ -TARGET = qeglfs-kms-integration - -PLUGIN_TYPE = egldeviceintegrations -PLUGIN_CLASS_NAME = QEglFSKmsGbmIntegrationPlugin -load(qt_plugin) - -QT += core-private gui-private eglfsdeviceintegration-private eglfs_kms_support-private kms_support-private edid_support-private - -INCLUDEPATH += $$PWD/../../api $$PWD/../eglfs_kms_support - -# Avoid X11 header collision, use generic EGL native types -DEFINES += QT_EGL_NO_X11 - -QMAKE_USE += gbm drm -CONFIG += egl - -SOURCES += $$PWD/qeglfskmsgbmmain.cpp \ - $$PWD/qeglfskmsgbmintegration.cpp \ - $$PWD/qeglfskmsgbmdevice.cpp \ - $$PWD/qeglfskmsgbmscreen.cpp \ - $$PWD/qeglfskmsgbmcursor.cpp \ - $$PWD/qeglfskmsgbmwindow.cpp - -HEADERS += $$PWD/qeglfskmsgbmintegration.h \ - $$PWD/qeglfskmsgbmdevice.h \ - $$PWD/qeglfskmsgbmscreen.h \ - $$PWD/qeglfskmsgbmcursor.h \ - $$PWD/qeglfskmsgbmwindow.h - -OTHER_FILES += $$PWD/eglfs_kms.json diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp index dc98cdce4b..87990ad592 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp @@ -1,48 +1,15 @@ -/**************************************************************************** -** -** 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 "qeglfskmsgbmcursor.h" -#include "qeglfskmsgbmscreen.h" -#include "qeglfskmsgbmdevice.h" +// Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> +// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2016 Pelagicore AG +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#include "qeglfskmsgbmcursor_p.h" +#include "qeglfskmsgbmscreen_p.h" +#include "qeglfskmsgbmdevice_p.h" + +#include <private/qeglfskmsintegration_p.h> + +#include <QtCore/QFile> #include <QtCore/QJsonDocument> #include <QtCore/QJsonObject> #include <QtCore/QJsonArray> @@ -63,7 +30,7 @@ QT_BEGIN_NAMESPACE -Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug) +using namespace Qt::StringLiterals; QEglFSKmsGbmCursor::QEglFSKmsGbmCursor(QEglFSKmsGbmScreen *screen) : m_screen(screen) @@ -111,7 +78,7 @@ QEglFSKmsGbmCursor::~QEglFSKmsGbmCursor() { delete m_deviceListener; - Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { + for (QPlatformScreen *screen : m_screen->virtualSiblings()) { QEglFSKmsScreen *kmsScreen = static_cast<QEglFSKmsScreen *>(screen); drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0, 0); drmModeMoveCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0); @@ -150,7 +117,7 @@ void QEglFSKmsGbmCursorDeviceListener::onDeviceListChanged(QInputDeviceManager:: void QEglFSKmsGbmCursor::pointerEvent(const QMouseEvent &event) { - setPos(event.screenPos().toPoint()); + setPos(event.globalPosition().toPoint()); } #ifndef QT_NO_CURSOR @@ -163,7 +130,7 @@ void QEglFSKmsGbmCursor::changeCursor(QCursor *windowCursor, QWindow *window) if (m_state == CursorPendingHidden) { m_state = CursorHidden; - Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { + for (QPlatformScreen *screen : m_screen->virtualSiblings()) { QEglFSKmsScreen *kmsScreen = static_cast<QEglFSKmsScreen *>(screen); drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0, 0); } @@ -212,7 +179,7 @@ void QEglFSKmsGbmCursor::changeCursor(QCursor *windowCursor, QWindow *window) if (m_state == CursorPendingVisible) m_state = CursorVisible; - Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { + for (QPlatformScreen *screen : m_screen->virtualSiblings()) { QEglFSKmsScreen *kmsScreen = static_cast<QEglFSKmsScreen *>(screen); if (kmsScreen->isCursorOutOfRange()) continue; @@ -231,7 +198,7 @@ QPoint QEglFSKmsGbmCursor::pos() const void QEglFSKmsGbmCursor::setPos(const QPoint &pos) { - Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { + for (QPlatformScreen *screen : m_screen->virtualSiblings()) { QEglFSKmsScreen *kmsScreen = static_cast<QEglFSKmsScreen *>(screen); const QRect screenGeom = kmsScreen->geometry(); const QPoint origin = screenGeom.topLeft(); @@ -247,7 +214,7 @@ void QEglFSKmsGbmCursor::setPos(const QPoint &pos) } } else { int ret; - if (kmsScreen->isCursorOutOfRange()) { + if (kmsScreen->isCursorOutOfRange() && m_bo) { kmsScreen->setCursorOutOfRange(false); uint32_t handle = gbm_bo_get_handle(m_bo).u32; ret = drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, @@ -276,7 +243,7 @@ void QEglFSKmsGbmCursor::initCursorAtlas() QFile file(QString::fromUtf8(json)); if (!file.open(QFile::ReadOnly)) { - Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { + for (QPlatformScreen *screen : m_screen->virtualSiblings()) { QEglFSKmsScreen *kmsScreen = static_cast<QEglFSKmsScreen *>(screen); drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0, 0); drmModeMoveCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0); @@ -288,14 +255,14 @@ void QEglFSKmsGbmCursor::initCursorAtlas() QJsonDocument doc = QJsonDocument::fromJson(file.readAll()); QJsonObject object = doc.object(); - QString atlas = object.value(QLatin1String("image")).toString(); + QString atlas = object.value("image"_L1).toString(); Q_ASSERT(!atlas.isEmpty()); - const int cursorsPerRow = object.value(QLatin1String("cursorsPerRow")).toDouble(); + const int cursorsPerRow = object.value("cursorsPerRow"_L1).toDouble(); Q_ASSERT(cursorsPerRow); m_cursorAtlas.cursorsPerRow = cursorsPerRow; - const QJsonArray hotSpots = object.value(QLatin1String("hotSpots")).toArray(); + const QJsonArray hotSpots = object.value("hotSpots"_L1).toArray(); Q_ASSERT(hotSpots.count() == Qt::LastCursor + 1); for (int i = 0; i < hotSpots.count(); i++) { QPoint hotSpot(hotSpots[i].toArray()[0].toDouble(), hotSpots[i].toArray()[1].toDouble()); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h deleted file mode 100644 index 5d2dfedba2..0000000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h +++ /dev/null @@ -1,122 +0,0 @@ -/**************************************************************************** -** -** 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: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 QEGLFSKMSGBMCURSOR_H -#define QEGLFSKMSGBMCURSOR_H - -#include <qpa/qplatformcursor.h> -#include <QtCore/QVector> -#include <QtGui/QImage> -#include <QtGui/private/qinputdevicemanager_p.h> - -#include <gbm.h> - -QT_BEGIN_NAMESPACE - -class QEglFSKmsGbmScreen; -class QEglFSKmsGbmCursor; - -class QEglFSKmsGbmCursorDeviceListener : public QObject -{ - Q_OBJECT - -public: - QEglFSKmsGbmCursorDeviceListener(QEglFSKmsGbmCursor *cursor) : m_cursor(cursor) { } - bool hasMouse() const; - -public slots: - void onDeviceListChanged(QInputDeviceManager::DeviceType type); - -private: - QEglFSKmsGbmCursor *m_cursor; -}; - -class QEglFSKmsGbmCursor : public QPlatformCursor -{ - Q_OBJECT - -public: - QEglFSKmsGbmCursor(QEglFSKmsGbmScreen *screen); - ~QEglFSKmsGbmCursor(); - - // input methods - void pointerEvent(const QMouseEvent & event) override; -#ifndef QT_NO_CURSOR - void changeCursor(QCursor * windowCursor, QWindow * window) override; -#endif - QPoint pos() const override; - void setPos(const QPoint &pos) override; - - void updateMouseStatus(); - - void reevaluateVisibilityForScreens() { setPos(pos()); } - -private: - void initCursorAtlas(); - - enum CursorState { - CursorDisabled, - CursorPendingHidden, - CursorHidden, - CursorPendingVisible, - CursorVisible - }; - - QEglFSKmsGbmScreen *m_screen; - QSize m_cursorSize; - gbm_bo *m_bo; - QPoint m_pos; - QPlatformCursorImage m_cursorImage; - CursorState m_state; - QEglFSKmsGbmCursorDeviceListener *m_deviceListener; - - // cursor atlas information - struct CursorAtlas { - CursorAtlas() : cursorsPerRow(0), cursorWidth(0), cursorHeight(0) { } - int cursorsPerRow; - int width, height; // width and height of the atlas - int cursorWidth, cursorHeight; // width and height of cursors inside the atlas - QVector<QPoint> hotSpots; - QImage image; - } m_cursorAtlas; -}; - -QT_END_NAMESPACE - -#endif // QEGLFSKMSGBMCURSOR_H diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor_p.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor_p.h new file mode 100644 index 0000000000..a0f78bb310 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor_p.h @@ -0,0 +1,97 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QEGLFSKMSGBMCURSOR_H +#define QEGLFSKMSGBMCURSOR_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <qpa/qplatformcursor.h> +#include <QtCore/QList> +#include <QtGui/QImage> +#include <QtGui/private/qinputdevicemanager_p.h> + +#include <gbm.h> + +QT_BEGIN_NAMESPACE + +class QEglFSKmsGbmScreen; +class QEglFSKmsGbmCursor; + +class QEglFSKmsGbmCursorDeviceListener : public QObject +{ + Q_OBJECT + +public: + QEglFSKmsGbmCursorDeviceListener(QEglFSKmsGbmCursor *cursor) : m_cursor(cursor) { } + bool hasMouse() const; + +public slots: + void onDeviceListChanged(QInputDeviceManager::DeviceType type); + +private: + QEglFSKmsGbmCursor *m_cursor; +}; + +class QEglFSKmsGbmCursor : public QPlatformCursor +{ + Q_OBJECT + +public: + QEglFSKmsGbmCursor(QEglFSKmsGbmScreen *screen); + ~QEglFSKmsGbmCursor(); + + // input methods + void pointerEvent(const QMouseEvent & event) override; +#ifndef QT_NO_CURSOR + void changeCursor(QCursor * windowCursor, QWindow * window) override; +#endif + QPoint pos() const override; + void setPos(const QPoint &pos) override; + + void updateMouseStatus(); + + void reevaluateVisibilityForScreens() { setPos(pos()); } + +private: + void initCursorAtlas(); + + enum CursorState { + CursorDisabled, + CursorPendingHidden, + CursorHidden, + CursorPendingVisible, + CursorVisible + }; + + QEglFSKmsGbmScreen *m_screen; + QSize m_cursorSize; + gbm_bo *m_bo; + QPoint m_pos; + QPlatformCursorImage m_cursorImage; + CursorState m_state; + QEglFSKmsGbmCursorDeviceListener *m_deviceListener; + + // cursor atlas information + struct CursorAtlas { + CursorAtlas() : cursorsPerRow(0), cursorWidth(0), cursorHeight(0) { } + int cursorsPerRow; + int width, height; // width and height of the atlas + int cursorWidth, cursorHeight; // width and height of cursors inside the atlas + QList<QPoint> hotSpots; + QImage image; + } m_cursorAtlas; +}; + +QT_END_NAMESPACE + +#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 index 503419cf91..a7592ed55e 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp @@ -1,48 +1,13 @@ -/**************************************************************************** -** -** 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_p.h" +// Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> +// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2016 Pelagicore AG +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qeglfskmsgbmdevice_p.h" +#include "qeglfskmsgbmscreen_p.h" + +#include <private/qeglfsintegration_p.h> +#include <private/qeglfskmsintegration_p.h> #include <QtCore/QLoggingCategory> #include <QtCore/private/qcore_unix_p.h> @@ -51,8 +16,6 @@ QT_BEGIN_NAMESPACE -Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug) - QEglFSKmsGbmDevice::QEglFSKmsGbmDevice(QKmsScreenConfig *screenConfig, const QString &path) : QEglFSKmsDevice(screenConfig, path) , m_gbm_device(nullptr) @@ -83,7 +46,13 @@ bool QEglFSKmsGbmDevice::open() setFd(fd); - m_eventReader.create(this); + if (usesEventReader()) { + qCDebug(qLcEglfsKmsDebug, "Using dedicated drm event reading thread"); + m_eventReader.create(this); + } else { + qCDebug(qLcEglfsKmsDebug, "Not using dedicated drm event reading thread; " + "threaded multi-screen setups may experience problems"); + } return true; } @@ -92,7 +61,8 @@ void QEglFSKmsGbmDevice::close() { // Note: screens are gone at this stage. - m_eventReader.destroy(); + if (usesEventReader()) + m_eventReader.destroy(); if (m_gbm_device) { gbm_device_destroy(m_gbm_device); @@ -131,14 +101,19 @@ void QEglFSKmsGbmDevice::destroyGlobalCursor() } } -QPlatformScreen *QEglFSKmsGbmDevice::createScreen(const QKmsOutput &output) +void QEglFSKmsGbmDevice::createGlobalCursor(QEglFSKmsGbmScreen *screen) { - QEglFSKmsGbmScreen *screen = new QEglFSKmsGbmScreen(this, output, false); - if (!m_globalCursor && screenConfig()->hwCursor()) { qCDebug(qLcEglfsKmsDebug, "Creating new global GBM mouse cursor"); m_globalCursor = new QEglFSKmsGbmCursor(screen); } +} + +QPlatformScreen *QEglFSKmsGbmDevice::createScreen(const QKmsOutput &output) +{ + QEglFSKmsGbmScreen *screen = new QEglFSKmsGbmScreen(this, output, false); + + createGlobalCursor(screen); return screen; } @@ -150,7 +125,7 @@ QPlatformScreen *QEglFSKmsGbmDevice::createHeadlessScreen() void QEglFSKmsGbmDevice::registerScreenCloning(QPlatformScreen *screen, QPlatformScreen *screenThisScreenClones, - const QVector<QPlatformScreen *> &screensCloningThisScreen) + const QList<QPlatformScreen *> &screensCloningThisScreen) { if (!screenThisScreenClones && screensCloningThisScreen.isEmpty()) return; @@ -169,4 +144,10 @@ void QEglFSKmsGbmDevice::registerScreen(QPlatformScreen *screen, m_globalCursor->reevaluateVisibilityForScreens(); } +bool QEglFSKmsGbmDevice::usesEventReader() const +{ + static const bool eventReaderThreadDisabled = qEnvironmentVariableIntValue("QT_QPA_EGLFS_KMS_NO_EVENT_READER_THREAD"); + return !eventReaderThreadDisabled; +} + 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 deleted file mode 100644 index f1476f8ffa..0000000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** -** -** 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(QKmsScreenConfig *screenConfig, const QString &path); - - bool open() override; - void close() override; - - void *nativeDisplay() const override; - gbm_device *gbmDevice() const; - - QPlatformCursor *globalCursor() const; - void destroyGlobalCursor(); - - QPlatformScreen *createScreen(const QKmsOutput &output) override; - QPlatformScreen *createHeadlessScreen() override; - void registerScreenCloning(QPlatformScreen *screen, - QPlatformScreen *screenThisScreenClones, - const QVector<QPlatformScreen *> &screensCloningThisScreen) override; - void registerScreen(QPlatformScreen *screen, - bool isPrimary, - const QPoint &virtualPos, - const QList<QPlatformScreen *> &virtualSiblings) override; - -private: - Q_DISABLE_COPY(QEglFSKmsGbmDevice) - - gbm_device *m_gbm_device; - - QEglFSKmsGbmCursor *m_globalCursor; -}; - -QT_END_NAMESPACE - -#endif // QEGLFSKMSGBMDEVICE_H diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice_p.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice_p.h new file mode 100644 index 0000000000..e00992ed29 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice_p.h @@ -0,0 +1,68 @@ +// Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> +// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2016 Pelagicore AG +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QEGLFSKMSGBMDEVICE_H +#define QEGLFSKMSGBMDEVICE_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qeglfskmsgbmcursor_p.h" +#include <private/qeglfskmsdevice_p.h> +#include <private/qeglfskmseventreader_p.h> + +#include <gbm.h> + +QT_BEGIN_NAMESPACE + +class QEglFSKmsScreen; + +class Q_EGLFS_EXPORT QEglFSKmsGbmDevice: public QEglFSKmsDevice +{ +public: + QEglFSKmsGbmDevice(QKmsScreenConfig *screenConfig, const QString &path); + + bool open() override; + void close() override; + + void *nativeDisplay() const override; + gbm_device *gbmDevice() const; + + QPlatformCursor *globalCursor() const; + void destroyGlobalCursor(); + void createGlobalCursor(QEglFSKmsGbmScreen *screen); + + QPlatformScreen *createScreen(const QKmsOutput &output) override; + QPlatformScreen *createHeadlessScreen() override; + void registerScreenCloning(QPlatformScreen *screen, + QPlatformScreen *screenThisScreenClones, + const QList<QPlatformScreen *> &screensCloningThisScreen) override; + void registerScreen(QPlatformScreen *screen, + bool isPrimary, + const QPoint &virtualPos, + const QList<QPlatformScreen *> &virtualSiblings) override; + + bool usesEventReader() const; + QEglFSKmsEventReader *eventReader() { return &m_eventReader; } + +private: + Q_DISABLE_COPY(QEglFSKmsGbmDevice) + + gbm_device *m_gbm_device; + QEglFSKmsEventReader m_eventReader; + QEglFSKmsGbmCursor *m_globalCursor; +}; + +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 index caa1187b40..05ffb3b212 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp @@ -1,49 +1,13 @@ -/**************************************************************************** -** -** 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 "qeglfskmsgbmwindow.h" +// Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> +// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2016 Pelagicore AG +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qeglfskmsgbmintegration_p.h" +#include "qeglfskmsgbmdevice_p.h" +#include "qeglfskmsgbmscreen_p.h" +#include "qeglfskmsgbmcursor_p.h" +#include "qeglfskmsgbmwindow_p.h" #include "private/qeglfscursor_p.h" #include <QtCore/QLoggingCategory> diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.h deleted file mode 100644 index 71f232abf9..0000000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.h +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** 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(); - - EGLDisplay createDisplay(EGLNativeDisplayType nativeDisplay) override; - EGLNativeWindowType createNativeOffscreenWindow(const QSurfaceFormat &format) override; - void destroyNativeWindow(EGLNativeWindowType window) override; - - QPlatformCursor *createCursor(QPlatformScreen *screen) const override; - void presentBuffer(QPlatformSurface *surface) override; - QEglFSWindow *createWindow(QWindow *window) const override; - -protected: - QKmsDevice *createDevice() override; - -private: -}; - -QT_END_NAMESPACE - -#endif // QEGLFSKMSGBMINTEGRATION_H diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration_p.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration_p.h new file mode 100644 index 0000000000..fb118438d2 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration_p.h @@ -0,0 +1,49 @@ +// Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> +// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2016 Pelagicore AG +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QEGLFSKMSGBMINTEGRATION_H +#define QEGLFSKMSGBMINTEGRATION_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qeglfskmsintegration_p.h> +#include <QtCore/QMap> +#include <QtCore/QVariant> + +QT_BEGIN_NAMESPACE + +class QEglFSKmsDevice; + +class Q_EGLFS_EXPORT QEglFSKmsGbmIntegration : public QEglFSKmsIntegration +{ +public: + QEglFSKmsGbmIntegration(); + + EGLDisplay createDisplay(EGLNativeDisplayType nativeDisplay) override; + EGLNativeWindowType createNativeOffscreenWindow(const QSurfaceFormat &format) override; + void destroyNativeWindow(EGLNativeWindowType window) override; + + QPlatformCursor *createCursor(QPlatformScreen *screen) const override; + void presentBuffer(QPlatformSurface *surface) override; + QEglFSWindow *createWindow(QWindow *window) const override; + +protected: + QKmsDevice *createDevice() 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 index 945c8b4255..9d6a694f03 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmmain.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmmain.cpp @@ -1,45 +1,9 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2016 Pelagicore AG +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "private/qeglfsdeviceintegration_p.h" -#include "qeglfskmsgbmintegration.h" +#include "qeglfskmsgbmintegration_p.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp index 6f5c3b6953..e2a806f491 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp @@ -1,48 +1,14 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> -** 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_p.h" +// Copyright (C) 2017 The Qt Company Ltd. +// Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> +// Copyright (C) 2016 Pelagicore AG +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qeglfskmsgbmscreen_p.h" +#include "qeglfskmsgbmdevice_p.h" +#include "qeglfskmsgbmcursor_p.h" + +#include <private/qeglfsintegration_p.h> +#include <private/qeglfskmsintegration_p.h> #include <QtCore/QLoggingCategory> @@ -54,7 +20,7 @@ QT_BEGIN_NAMESPACE -Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug) +QMutex QEglFSKmsGbmScreen::m_nonThreadedFlipMutex; static inline uint32_t drmFormatToGbmFormat(uint32_t drmFormat) { @@ -95,8 +61,9 @@ QEglFSKmsGbmScreen::FrameBuffer *QEglFSKmsGbmScreen::framebufferForBufferObject( uint32_t offsets[4] = { 0 }; uint32_t pixelFormat = gbmFormatToDrmFormat(gbm_bo_get_format(bo)); - QScopedPointer<FrameBuffer> fb(new FrameBuffer); - qCDebug(qLcEglfsKmsDebug, "Adding FB, size %ux%u, DRM format 0x%x", width, height, pixelFormat); + auto fb = std::make_unique<FrameBuffer>(); + qCDebug(qLcEglfsKmsDebug, "Adding FB, size %ux%u, DRM format 0x%x, stride %u, handle %u", + width, height, pixelFormat, strides[0], handles[0]); int ret = drmModeAddFB2(device()->fd(), width, height, pixelFormat, handles, strides, offsets, &fb->fb, 0); @@ -106,8 +73,9 @@ QEglFSKmsGbmScreen::FrameBuffer *QEglFSKmsGbmScreen::framebufferForBufferObject( return nullptr; } - gbm_bo_set_user_data(bo, fb.data(), bufferDestroyedHandler); - return fb.take(); + auto res = fb.get(); + gbm_bo_set_user_data(bo, fb.release(), bufferDestroyedHandler); + return res; } QEglFSKmsGbmScreen::QEglFSKmsGbmScreen(QEglFSKmsDevice *device, const QKmsOutput &output, bool headless) @@ -169,36 +137,63 @@ gbm_surface *QEglFSKmsGbmScreen::createSurface(EGLConfig eglConfig) rawGeometry().width(), rawGeometry().height(), native_format, - GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); + gbmFlags()); if (m_gbm_surface) m_output.drm_format = gbmFormatToDrmFormat(native_format); } } + const uint32_t gbmFormat = drmFormatToGbmFormat(m_output.drm_format); + // Fallback for older drivers, and when "format" is explicitly specified // in the output config. (not guaranteed that the requested format works // of course, but do what we are told to) if (!m_gbm_surface) { - uint32_t gbmFormat = drmFormatToGbmFormat(m_output.drm_format); if (queryFromEgl) qCDebug(qLcEglfsKmsDebug, "Could not create surface with EGL_NATIVE_VISUAL_ID, falling back to format %x", gbmFormat); m_gbm_surface = gbm_surface_create(gbmDevice, rawGeometry().width(), rawGeometry().height(), gbmFormat, - GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); + gbmFlags()); + } + + // Fallback for some drivers, its required to request with modifiers + if (!m_gbm_surface) { + uint64_t modifier = DRM_FORMAT_MOD_LINEAR; + + m_gbm_surface = gbm_surface_create_with_modifiers(gbmDevice, + rawGeometry().width(), + rawGeometry().height(), + gbmFormat, + &modifier, 1); } + // Fail here, as it would fail with the next usage of the GBM surface, which is very unexpected + if (!m_gbm_surface) + qFatal("Could not create GBM surface!"); } return m_gbm_surface; // not owned, gets destroyed in QEglFSKmsGbmIntegration::destroyNativeWindow() via QEglFSKmsGbmWindow::invalidateSurface() } void QEglFSKmsGbmScreen::resetSurface() { + m_flipPending = false; // not necessarily true but enough to keep bo_next + m_gbm_bo_current = nullptr; m_gbm_surface = nullptr; + + // Leave m_gbm_bo_next untouched. waitForFlip() should + // still do its work, when called. Otherwise we end up + // in device-is-busy errors if there is a new QWindow + // created afterwards. (QTBUG-122663) + + // If not using atomic, will need a new drmModeSetCrtc if a new window + // gets created later on (and so there's a new fb). + if (!device()->hasAtomicSupport()) + needsNewModeSetForNextFb = true; } void QEglFSKmsGbmScreen::initCloning(QPlatformScreen *screenThisScreenClones, - const QVector<QPlatformScreen *> &screensCloningThisScreen) + const QList<QPlatformScreen *> &screensCloningThisScreen) { // clone destinations need to know the clone source const bool clonesAnother = screenThisScreenClones != nullptr; @@ -206,8 +201,10 @@ void QEglFSKmsGbmScreen::initCloning(QPlatformScreen *screenThisScreenClones, qWarning("QEglFSKmsGbmScreen %s cannot be clone source and destination at the same time", qPrintable(name())); return; } - if (clonesAnother) + if (clonesAnother) { m_cloneSource = static_cast<QEglFSKmsGbmScreen *>(screenThisScreenClones); + qCDebug(qLcEglfsKmsDebug, "Screen %s clones %s", qPrintable(name()), qPrintable(m_cloneSource->name())); + } // clone sources need to know their additional destinations for (QPlatformScreen *s : screensCloningThisScreen) { @@ -222,21 +219,17 @@ void QEglFSKmsGbmScreen::ensureModeSet(uint32_t fb) QKmsOutput &op(output()); const int fd = device()->fd(); - if (!op.mode_set) { + if (!op.mode_set || needsNewModeSetForNextFb) { op.mode_set = true; + needsNewModeSetForNextFb = false; bool doModeSet = true; drmModeCrtcPtr currentMode = drmModeGetCrtc(fd, op.crtc_id); - const bool alreadySet = currentMode && !memcmp(¤tMode->mode, &op.modes[op.mode], sizeof(drmModeModeInfo)); + const bool alreadySet = currentMode && currentMode->buffer_id == fb && !memcmp(¤tMode->mode, &op.modes[op.mode], sizeof(drmModeModeInfo)); if (currentMode) drmModeFreeCrtc(currentMode); - if (alreadySet) { - static bool alwaysDoSet = qEnvironmentVariableIntValue("QT_QPA_EGLFS_ALWAYS_SET_MODE"); - if (!alwaysDoSet) { - qCDebug(qLcEglfsKmsDebug, "Mode already set, skipping modesetting for screen %s", qPrintable(name())); - doModeSet = false; - } - } + if (alreadySet) + doModeSet = false; if (doModeSet) { qCDebug(qLcEglfsKmsDebug, "Setting mode for screen %s", qPrintable(name())); @@ -267,6 +260,29 @@ void QEglFSKmsGbmScreen::ensureModeSet(uint32_t fb) } } +void QEglFSKmsGbmScreen::nonThreadedPageFlipHandler(int fd, + unsigned int sequence, + unsigned int tv_sec, + unsigned int tv_usec, + void *user_data) +{ + // note that with cloning involved this callback is called also for screens that clone another one + Q_UNUSED(fd); + QEglFSKmsGbmScreen *screen = static_cast<QEglFSKmsGbmScreen *>(user_data); + screen->flipFinished(); + screen->pageFlipped(sequence, tv_sec, tv_usec); +} + +void QEglFSKmsGbmScreen::waitForFlipWithEventReader(QEglFSKmsGbmScreen *screen) +{ + m_flipMutex.lock(); + QEglFSKmsGbmDevice *dev = static_cast<QEglFSKmsGbmDevice *>(device()); + dev->eventReader()->startWaitFlip(screen, &m_flipMutex, &m_flipCond); + m_flipCond.wait(&m_flipMutex); + m_flipMutex.unlock(); + screen->flipFinished(); +} + void QEglFSKmsGbmScreen::waitForFlip() { if (m_headless || m_cloneSource) @@ -276,18 +292,69 @@ void QEglFSKmsGbmScreen::waitForFlip() if (!m_gbm_bo_next) return; - m_flipMutex.lock(); - device()->eventReader()->startWaitFlip(this, &m_flipMutex, &m_flipCond); - m_flipCond.wait(&m_flipMutex); - m_flipMutex.unlock(); - - flipFinished(); + QEglFSKmsGbmDevice *dev = static_cast<QEglFSKmsGbmDevice *>(device()); + if (dev->usesEventReader()) { + waitForFlipWithEventReader(this); + // Now, unlike on the other code path, we need to ensure the + // flips have completed for the screens that just scan out + // this one's content, because the eventReader's wait is + // per-output. + for (CloneDestination &d : m_cloneDests) { + if (d.screen != this) + waitForFlipWithEventReader(d.screen); + } + } else { + QMutexLocker lock(&m_nonThreadedFlipMutex); + while (m_gbm_bo_next) { + drmEventContext drmEvent; + memset(&drmEvent, 0, sizeof(drmEvent)); + drmEvent.version = 2; + drmEvent.vblank_handler = nullptr; + drmEvent.page_flip_handler = nonThreadedPageFlipHandler; + drmHandleEvent(device()->fd(), &drmEvent); + } + } #if QT_CONFIG(drm_atomic) device()->threadLocalAtomicReset(); #endif } +#if QT_CONFIG(drm_atomic) +static void addAtomicFlip(drmModeAtomicReq *request, const QKmsOutput &output, uint32_t fb) +{ + drmModeAtomicAddProperty(request, output.eglfs_plane->id, + output.eglfs_plane->framebufferPropertyId, fb); + + drmModeAtomicAddProperty(request, output.eglfs_plane->id, + output.eglfs_plane->crtcPropertyId, output.crtc_id); + + drmModeAtomicAddProperty(request, output.eglfs_plane->id, + output.eglfs_plane->srcwidthPropertyId, output.size.width() << 16); + + drmModeAtomicAddProperty(request, output.eglfs_plane->id, + output.eglfs_plane->srcXPropertyId, 0); + + drmModeAtomicAddProperty(request, output.eglfs_plane->id, + output.eglfs_plane->srcYPropertyId, 0); + + drmModeAtomicAddProperty(request, output.eglfs_plane->id, + output.eglfs_plane->srcheightPropertyId, output.size.height() << 16); + + drmModeAtomicAddProperty(request, output.eglfs_plane->id, + output.eglfs_plane->crtcXPropertyId, 0); + + drmModeAtomicAddProperty(request, output.eglfs_plane->id, + output.eglfs_plane->crtcYPropertyId, 0); + + drmModeAtomicAddProperty(request, output.eglfs_plane->id, + output.eglfs_plane->crtcwidthPropertyId, output.modes[output.mode].hdisplay); + + drmModeAtomicAddProperty(request, output.eglfs_plane->id, + output.eglfs_plane->crtcheightPropertyId, output.modes[output.mode].vdisplay); +} +#endif + void QEglFSKmsGbmScreen::flip() { // For headless screen just return silently. It is not necessarily an error @@ -307,14 +374,24 @@ void QEglFSKmsGbmScreen::flip() 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!"); + qWarning("Could not lock GBM surface front buffer for screen %s", qPrintable(name())); return; } + auto gbmRelease = qScopeGuard([this]{ + m_flipPending = false; + gbm_surface_release_buffer(m_gbm_surface, m_gbm_bo_next); + m_gbm_bo_next = nullptr; + }); + FrameBuffer *fb = framebufferForBufferObject(m_gbm_bo_next); + if (!fb) { + qWarning("FrameBuffer not available. Cannot flip"); + return; + } ensureModeSet(fb->fb); - QKmsOutput &op(output()); + const QKmsOutput &thisOutput(output()); const int fd = device()->fd(); m_flipPending = true; @@ -322,40 +399,27 @@ void QEglFSKmsGbmScreen::flip() #if QT_CONFIG(drm_atomic) drmModeAtomicReq *request = device()->threadLocalAtomicRequest(); if (request) { - drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->framebufferPropertyId, fb->fb); - drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->crtcPropertyId, op.crtc_id); - drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->srcwidthPropertyId, - op.size.width() << 16); - drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->srcXPropertyId, 0); - drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->srcYPropertyId, 0); - drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->srcheightPropertyId, - op.size.height() << 16); - drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->crtcXPropertyId, 0); - drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->crtcYPropertyId, 0); - drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->crtcwidthPropertyId, - m_output.modes[m_output.mode].hdisplay); - drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->crtcheightPropertyId, - m_output.modes[m_output.mode].vdisplay); - + addAtomicFlip(request, thisOutput, fb->fb); static int zpos = qEnvironmentVariableIntValue("QT_QPA_EGLFS_KMS_ZPOS"); - if (zpos) - drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->zposPropertyId, zpos); + if (zpos) { + drmModeAtomicAddProperty(request, thisOutput.eglfs_plane->id, + thisOutput.eglfs_plane->zposPropertyId, zpos); + } static uint blendOp = uint(qEnvironmentVariableIntValue("QT_QPA_EGLFS_KMS_BLEND_OP")); - if (blendOp) - drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->blendOpPropertyId, blendOp); + if (blendOp) { + drmModeAtomicAddProperty(request, thisOutput.eglfs_plane->id, + thisOutput.eglfs_plane->blendOpPropertyId, blendOp); + } } #endif } else { int ret = drmModePageFlip(fd, - op.crtc_id, - fb->fb, - DRM_MODE_PAGE_FLIP_EVENT, - this); + thisOutput.crtc_id, + fb->fb, + DRM_MODE_PAGE_FLIP_EVENT, + this); if (ret) { qErrnoWarning("Could not queue DRM page flip on screen %s", qPrintable(name())); - m_flipPending = false; - gbm_surface_release_buffer(m_gbm_surface, m_gbm_bo_next); - m_gbm_bo_next = nullptr; return; } } @@ -364,34 +428,46 @@ void QEglFSKmsGbmScreen::flip() if (d.screen != this) { d.screen->ensureModeSet(fb->fb); d.cloneFlipPending = true; + const QKmsOutput &destOutput(d.screen->output()); if (device()->hasAtomicSupport()) { #if QT_CONFIG(drm_atomic) drmModeAtomicReq *request = device()->threadLocalAtomicRequest(); - if (request) { - drmModeAtomicAddProperty(request, d.screen->output().eglfs_plane->id, - d.screen->output().eglfs_plane->framebufferPropertyId, fb->fb); - drmModeAtomicAddProperty(request, d.screen->output().eglfs_plane->id, - d.screen->output().eglfs_plane->crtcPropertyId, op.crtc_id); - } + if (request) + addAtomicFlip(request, destOutput, fb->fb); + + // ### This path is broken. On the other branch we can easily + // pass in d.screen as the user_data for drmModePageFlip, but + // using one atomic request breaks down here since we get events + // with the same user_data passed to drmModeAtomicCommit. Until + // this gets reworked (multiple requests?) screen cloning is not + // compatible with atomic. #endif } else { int ret = drmModePageFlip(fd, - d.screen->output().crtc_id, + destOutput.crtc_id, fb->fb, DRM_MODE_PAGE_FLIP_EVENT, d.screen); if (ret) { - qErrnoWarning("Could not queue DRM page flip for clone screen %s", qPrintable(name())); + qErrnoWarning("Could not queue DRM page flip for screen %s (clones screen %s)", + qPrintable(d.screen->name()), + qPrintable(name())); d.cloneFlipPending = false; } } } } + if (device()->hasAtomicSupport()) { #if QT_CONFIG(drm_atomic) - device()->threadLocalAtomicCommit(this); + if (!device()->threadLocalAtomicCommit(this)) { + return; + } #endif + } + + gbmRelease.dismiss(); } void QEglFSKmsGbmScreen::flipFinished() @@ -418,19 +494,23 @@ void QEglFSKmsGbmScreen::cloneDestFlipFinished(QEglFSKmsGbmScreen *cloneDestScre void QEglFSKmsGbmScreen::updateFlipStatus() { - Q_ASSERT(!m_cloneSource); + // only for 'real' outputs that own the color buffer, i.e. that are not cloning another one + if (m_cloneSource) + return; + // proceed only if flips for both this and all others that clone this have finished if (m_flipPending) return; - for (const CloneDestination &d : qAsConst(m_cloneDests)) { + for (const CloneDestination &d : std::as_const(m_cloneDests)) { if (d.cloneFlipPending) return; } - if (m_gbm_bo_current) + 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 = nullptr; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h deleted file mode 100644 index 69feeee703..0000000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h +++ /dev/null @@ -1,106 +0,0 @@ -/**************************************************************************** -** -** 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 <QMutex> -#include <QWaitCondition> - -#include <gbm.h> - -QT_BEGIN_NAMESPACE - -class QEglFSKmsGbmCursor; - -class QEglFSKmsGbmScreen : public QEglFSKmsScreen -{ -public: - QEglFSKmsGbmScreen(QEglFSKmsDevice *device, const QKmsOutput &output, bool headless); - ~QEglFSKmsGbmScreen(); - - QPlatformCursor *cursor() const override; - - gbm_surface *createSurface(EGLConfig eglConfig); - void resetSurface(); - - void initCloning(QPlatformScreen *screenThisScreenClones, - const QVector<QPlatformScreen *> &screensCloningThisScreen); - - void waitForFlip() override; - - void flip(); - -private: - void flipFinished(); - void ensureModeSet(uint32_t fb); - void cloneDestFlipFinished(QEglFSKmsGbmScreen *cloneDestScreen); - void updateFlipStatus(); - - gbm_surface *m_gbm_surface; - - gbm_bo *m_gbm_bo_current; - gbm_bo *m_gbm_bo_next; - bool m_flipPending; - - QMutex m_flipMutex; - QWaitCondition m_flipCond; - - QScopedPointer<QEglFSKmsGbmCursor> m_cursor; - - struct FrameBuffer { - uint32_t fb = 0; - }; - static void bufferDestroyedHandler(gbm_bo *bo, void *data); - FrameBuffer *framebufferForBufferObject(gbm_bo *bo); - - QEglFSKmsGbmScreen *m_cloneSource; - struct CloneDestination { - QEglFSKmsGbmScreen *screen = nullptr; - bool cloneFlipPending = false; - }; - QVector<CloneDestination> m_cloneDests; -}; - -QT_END_NAMESPACE - -#endif // QEGLFSKMSGBMSCREEN_H diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen_p.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen_p.h new file mode 100644 index 0000000000..aca34fcae2 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen_p.h @@ -0,0 +1,92 @@ +// Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> +// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2016 Pelagicore AG +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QEGLFSKMSGBMSCREEN_H +#define QEGLFSKMSGBMSCREEN_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qeglfskmsscreen_p.h> +#include <QMutex> +#include <QWaitCondition> + +#include <gbm.h> + +QT_BEGIN_NAMESPACE + +class QEglFSKmsGbmCursor; + +class Q_EGLFS_EXPORT QEglFSKmsGbmScreen : public QEglFSKmsScreen +{ +public: + QEglFSKmsGbmScreen(QEglFSKmsDevice *device, const QKmsOutput &output, bool headless); + ~QEglFSKmsGbmScreen(); + + QPlatformCursor *cursor() const override; + + gbm_surface *createSurface(EGLConfig eglConfig); + void resetSurface(); + + void initCloning(QPlatformScreen *screenThisScreenClones, + const QList<QPlatformScreen *> &screensCloningThisScreen); + + void waitForFlip() override; + + virtual void flip(); + virtual void updateFlipStatus(); + + virtual uint32_t gbmFlags() { return GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING; } + +protected: + void flipFinished(); + void ensureModeSet(uint32_t fb); + void cloneDestFlipFinished(QEglFSKmsGbmScreen *cloneDestScreen); + void waitForFlipWithEventReader(QEglFSKmsGbmScreen *screen); + static void nonThreadedPageFlipHandler(int fd, + unsigned int sequence, + unsigned int tv_sec, + unsigned int tv_usec, + void *user_data); + + gbm_surface *m_gbm_surface; + + gbm_bo *m_gbm_bo_current; + gbm_bo *m_gbm_bo_next; + bool m_flipPending; + + QMutex m_flipMutex; + QWaitCondition m_flipCond; + static QMutex m_nonThreadedFlipMutex; + + QScopedPointer<QEglFSKmsGbmCursor> m_cursor; + + struct FrameBuffer { + uint32_t fb = 0; + }; + static void bufferDestroyedHandler(gbm_bo *bo, void *data); + FrameBuffer *framebufferForBufferObject(gbm_bo *bo); + + QEglFSKmsGbmScreen *m_cloneSource; + struct CloneDestination { + QEglFSKmsGbmScreen *screen = nullptr; + bool cloneFlipPending = false; + }; + QList<CloneDestination> m_cloneDests; + + bool needsNewModeSetForNextFb = false; +}; + +QT_END_NAMESPACE + +#endif // QEGLFSKMSGBMSCREEN_H diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp index a93762e5b4..f2e23061be 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp @@ -1,47 +1,11 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only -#include "qeglfskmsgbmwindow.h" -#include "qeglfskmsgbmintegration.h" -#include "qeglfskmsgbmscreen.h" +#include "qeglfskmsgbmwindow_p.h" +#include "qeglfskmsgbmintegration_p.h" +#include "qeglfskmsgbmscreen_p.h" -#include <QtEglSupport/private/qeglconvenience_p.h> +#include <QtGui/private/qeglconvenience_p.h> QT_BEGIN_NAMESPACE @@ -67,7 +31,21 @@ void QEglFSKmsGbmWindow::resetSurface() } if (createPlatformWindowSurface) { - m_surface = createPlatformWindowSurface(display, m_config, reinterpret_cast<void *>(m_window), nullptr); + QVector<EGLint> contextAttributes; +#ifdef EGL_EXT_protected_content + if (platformFormat.testOption(QSurfaceFormat::ProtectedContent)) { + if (q_hasEglExtension(display, "EGL_EXT_protected_content")) { + contextAttributes.append(EGL_PROTECTED_CONTENT_EXT); + contextAttributes.append(EGL_TRUE); + qCDebug(qLcEglfsKmsDebug, "Enabled EGL_PROTECTED_CONTENT_EXT for eglCreatePlatformWindowSurfaceEXT"); + } else { + m_format.setOption(QSurfaceFormat::ProtectedContent, false); + } + } +#endif + contextAttributes.append(EGL_NONE); + + m_surface = createPlatformWindowSurface(display, m_config, reinterpret_cast<void *>(m_window), contextAttributes.constData()); } else { qCDebug(qLcEglfsKmsDebug, "No eglCreatePlatformWindowSurface for GBM, falling back to eglCreateWindowSurface"); m_surface = eglCreateWindowSurface(display, m_config, m_window, nullptr); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.h deleted file mode 100644 index ee4b7978f1..0000000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.h +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** 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 QEGLFSKMSGBMWINDOW_H -#define QEGLFSKMSGBMWINDOW_H - -#include "private/qeglfswindow_p.h" - -QT_BEGIN_NAMESPACE - -class QEglFSKmsGbmIntegration; - -class QEglFSKmsGbmWindow : public QEglFSWindow -{ -public: - QEglFSKmsGbmWindow(QWindow *w, const QEglFSKmsGbmIntegration *integration) - : QEglFSWindow(w), - m_integration(integration) - { } - - ~QEglFSKmsGbmWindow() { destroy(); } - - void resetSurface() override; - void invalidateSurface() override; - -private: - const QEglFSKmsGbmIntegration *m_integration; -}; - -QT_END_NAMESPACE - -#endif // QEGLFSKMSGBMWINDOW_H diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow_p.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow_p.h new file mode 100644 index 0000000000..2d225b0314 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow_p.h @@ -0,0 +1,45 @@ +// Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> +// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2016 Pelagicore AG +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QEGLFSKMSGBMWINDOW_H +#define QEGLFSKMSGBMWINDOW_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "private/qeglfswindow_p.h" + +QT_BEGIN_NAMESPACE + +class QEglFSKmsGbmIntegration; + +class Q_EGLFS_EXPORT QEglFSKmsGbmWindow : public QEglFSWindow +{ +public: + QEglFSKmsGbmWindow(QWindow *w, const QEglFSKmsGbmIntegration *integration) + : QEglFSWindow(w), + m_integration(integration) + { } + + ~QEglFSKmsGbmWindow() { destroy(); } + + void resetSurface() override; + void invalidateSurface() override; + +private: + const QEglFSKmsGbmIntegration *m_integration; +}; + +QT_END_NAMESPACE + +#endif // QEGLFSKMSGBMWINDOW_H |