diff --git a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro index 266a97dff5..769c248d0d 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro @@ -1,9 +1,12 @@ TEMPLATE = subdirs contains(QT_CONFIG, egl_x11): SUBDIRS += eglfs_x11 -contains(QT_CONFIG, eglfs_gbm): SUBDIRS += eglfs_kms -contains(QT_CONFIG, eglfs_egldevice): SUBDIRS += eglfs_kms_egldevice +contains(QT_CONFIG, eglfs_gbm): SUBDIRS += eglfs_kms_support eglfs_kms +contains(QT_CONFIG, eglfs_egldevice): SUBDIRS += eglfs_kms_support eglfs_kms_egldevice contains(QT_CONFIG, eglfs_brcm): SUBDIRS += eglfs_brcm contains(QT_CONFIG, eglfs_mali): SUBDIRS += eglfs_mali contains(QT_CONFIG, eglfs_viv): SUBDIRS += eglfs_viv contains(QT_CONFIG, eglfs_viv_wl): SUBDIRS += eglfs_viv_wl + +eglfs_kms_egldevice.depends = eglfs_kms_support +eglfs_kms.depends = eglfs_kms_support 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..82877710fc 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 = QEglFSKmsIntegrationPlugin +load(qt_plugin) -INCLUDEPATH += $$PWD/../.. +QT += core-private gui-private platformsupport-private eglfs_device_lib-private eglfs_kms_support-private + +INCLUDEPATH += $$PWD/../.. $$PWD/../eglfs_kms_support # Avoid X11 header collision DEFINES += MESA_EGL_NO_X11_HEADERS 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/qeglfskmscursor.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp similarity index 92% rename from src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp rename to src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp index ac966d23ee..8536e2c239 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp @@ -2,6 +2,7 @@ ** ** Copyright (C) 2015 Pier Luigi Fiorini ** 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. @@ -38,9 +39,9 @@ ** ****************************************************************************/ -#include "qeglfskmscursor.h" -#include "qeglfskmsscreen.h" -#include "qeglfskmsdevice.h" +#include "qeglfskmsgbmcursor.h" +#include "qeglfskmsgbmscreen.h" +#include "qeglfskmsgbmdevice.h" #include #include @@ -63,7 +64,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) @@ -83,7 +84,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(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!"); @@ -98,7 +99,7 @@ QEglFSKmsCursor::QEglFSKmsCursor(QEglFSKmsScreen *screen) setPos(QPoint(0, 0)); } -QEglFSKmsCursor::~QEglFSKmsCursor() +QEglFSKmsGbmCursor::~QEglFSKmsGbmCursor() { Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { QEglFSKmsScreen *kmsScreen = static_cast(screen); @@ -110,13 +111,13 @@ QEglFSKmsCursor::~QEglFSKmsCursor() m_bo = Q_NULLPTR; } -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); @@ -171,12 +172,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(screen); @@ -192,7 +193,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 similarity index 91% rename from src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.h rename to src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h index bbdd87cefd..c1e3706e91 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h @@ -37,8 +37,8 @@ ** ****************************************************************************/ -#ifndef QEGLFSKMSCURSOR_H -#define QEGLFSKMSCURSOR_H +#ifndef QEGLFSKMSGBMCURSOR_H +#define QEGLFSKMSGBMCURSOR_H #include #include @@ -48,15 +48,15 @@ QT_BEGIN_NAMESPACE -class QEglFSKmsScreen; +class QEglFSKmsGbmScreen; -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; @@ -69,7 +69,7 @@ public: private: void initCursorAtlas(); - QEglFSKmsScreen *m_screen; + QEglFSKmsGbmScreen *m_screen; QSize m_cursorSize; gbm_bo *m_bo; QPoint m_pos; @@ -89,4 +89,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..9bb489d6b4 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Pier Luigi Fiorini +** 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 +#include +#include + +#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(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::device() const +{ + return 0; +} + +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..6203a6dc7f --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Pier Luigi Fiorini +** 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 + +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 device() 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 +** 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +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(platformWindow->screen()); + if (screen->surface()) { + qWarning("Only single window per screen supported!"); + return 0; + } + + return reinterpret_cast(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(device())->gbmDevice(), + 1, 1, + GBM_FORMAT_XRGB8888, + GBM_BO_USE_RENDERING); + + return reinterpret_cast(surface); +} + +void QEglFSKmsGbmIntegration::destroyNativeWindow(EGLNativeWindowType window) +{ + gbm_surface *surface = reinterpret_cast(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(surface->surface()); + QEglFSKmsScreen *screen = static_cast(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 +** 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 +#include + +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/qeglfskmsmain.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmmain.cpp similarity index 91% rename from src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsmain.cpp rename to src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmmain.cpp index a39e2e5434..8e8779ca10 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsmain.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmmain.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** 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. @@ -38,19 +39,19 @@ ****************************************************************************/ #include "qeglfsdeviceintegration.h" -#include "qeglfskmsintegration.h" +#include "qeglfskmsgbmintegration.h" QT_BEGIN_NAMESPACE -class QEglFSKmsIntegrationPlugin : public QEGLDeviceIntegrationPlugin +class QEglFSKmsGbmIntegrationPlugin : public QEGLDeviceIntegrationPlugin { Q_OBJECT Q_PLUGIN_METADATA(IID QEGLDeviceIntegrationFactoryInterface_iid FILE "eglfs_kms.json") public: - QEGLDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSKmsIntegration; } + QEGLDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSKmsGbmIntegration; } }; QT_END_NAMESPACE -#include "qeglfskmsmain.moc" +#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 +** 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 + +#include +#include + +QT_BEGIN_NAMESPACE + +Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug) + +void QEglFSKmsGbmScreen::bufferDestroyedHandler(gbm_bo *bo, void *data) +{ + FrameBuffer *fb = static_cast(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(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 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(device())->globalCursor(); + + if (m_cursor.isNull()) { + QEglFSKmsGbmScreen *that = const_cast(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(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(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 +** 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 + +#include + +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 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_egldevice/eglfs_kms_egldevice.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro index 1932f861b9..3a380b7525 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro @@ -1,23 +1,32 @@ TARGET = qeglfs-kms-egldevice-integration -QT += core-private gui-private platformsupport-private eglfs_device_lib-private +QT += core-private gui-private platformsupport-private eglfs_device_lib-private eglfs_kms_support-private -INCLUDEPATH += $$PWD/../.. +INCLUDEPATH += $$PWD/../.. $$PWD/../eglfs_kms_support DEFINES += MESA_EGL_NO_X11_HEADERS +CONFIG += link_pkgconfig +!contains(QT_CONFIG, no-pkg-config) { + PKGCONFIG += libdrm +} else { + LIBS += -ldrm +} + CONFIG += egl QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF SOURCES += $$PWD/qeglfskmsegldevicemain.cpp \ - $$PWD/qeglfskmsegldeviceintegration.cpp + $$PWD/qeglfskmsegldeviceintegration.cpp \ + qeglfskmsegldevice.cpp \ + qeglfskmsegldevicescreen.cpp -HEADERS += $$PWD/qeglfskmsegldeviceintegration.h +HEADERS += $$PWD/qeglfskmsegldeviceintegration.h \ + qeglfskmsegldevice.h \ + qeglfskmsegldevicescreen.h OTHER_FILES += $$PWD/eglfs_kms_egldevice.json -LIBS += -ldrm - PLUGIN_TYPE = egldeviceintegrations PLUGIN_CLASS_NAME = QEglFSKmsEglDeviceIntegrationPlugin load(qt_plugin) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp new file mode 100644 index 0000000000..e09f2fdb18 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** 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 "qeglfskmsegldevice.h" +#include "qeglfskmsegldevicescreen.h" + +#include + +QEglFSKmsEglDevice::QEglFSKmsEglDevice(QEglFSKmsIntegration *integration, const QString &path) + : QEglFSKmsDevice(integration, path) +{ +} + +bool QEglFSKmsEglDevice::open() +{ + Q_ASSERT(fd() == -1); + + int fd = drmOpen(devicePath().toLocal8Bit().constData(), Q_NULLPTR); + if (Q_UNLIKELY(fd < 0)) + qFatal("Could not open DRM device"); + + setFd(fd); + + return true; +} + +void QEglFSKmsEglDevice::close() +{ + if (qt_safe_close(fd()) == -1) + qErrnoWarning("Could not close DRM device"); + + setFd(-1); +} + +EGLNativeDisplayType QEglFSKmsEglDevice::device() const +{ + return 0; +} + +QEglFSKmsScreen *QEglFSKmsEglDevice::createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output, QPoint position) +{ + return new QEglFSKmsEglDeviceScreen(integration, device, output, position); +} diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h new file mode 100644 index 0000000000..f85ec27fa2 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** 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 QEGLFSKMSEGLDEVICE_H +#define QEGLFSKMSEGLDEVICE_H + +#include + +class QEglFSKmsEglDevice: public QEglFSKmsDevice +{ +public: + QEglFSKmsEglDevice(QEglFSKmsIntegration *integration, const QString &path); + + virtual bool open() Q_DECL_OVERRIDE; + virtual void close() Q_DECL_OVERRIDE; + + virtual EGLNativeDisplayType device() const Q_DECL_OVERRIDE; + + virtual QEglFSKmsScreen *createScreen(QEglFSKmsIntegration *integration, + QEglFSKmsDevice *device, + QEglFSKmsOutput output, + QPoint position) Q_DECL_OVERRIDE; +}; + +#endif // QEGLFSKMSEGLDEVICE_H diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp index 201d9d7443..838569d5c6 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** 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. @@ -38,60 +39,26 @@ ****************************************************************************/ #include "qeglfskmsegldeviceintegration.h" +#include +#include "qeglfswindow.h" +#include "qeglfskmsegldevice.h" +#include "qeglfskmsscreen.h" #include #include QT_BEGIN_NAMESPACE -Q_LOGGING_CATEGORY(qLcEglfsKmsDebug, "qt.qpa.eglfs.kms") - QEglFSKmsEglDeviceIntegration::QEglFSKmsEglDeviceIntegration() - : m_dri_fd(-1) + : QEglFSKmsIntegration() , m_egl_device(EGL_NO_DEVICE_EXT) - , m_egl_display(EGL_NO_DISPLAY) - , m_drm_connector(Q_NULLPTR) - , m_drm_encoder(Q_NULLPTR) - , m_drm_crtc(0) , m_funcs(Q_NULLPTR) { qCDebug(qLcEglfsKmsDebug, "New DRM/KMS on EGLDevice integration created"); } -void QEglFSKmsEglDeviceIntegration::platformInit() +EGLint QEglFSKmsEglDeviceIntegration::surfaceType() const { - if (Q_UNLIKELY(!query_egl_device())) - qFatal("Could not set up EGL device!"); - - const char *deviceName = m_funcs->query_device_string(m_egl_device, EGL_DRM_DEVICE_FILE_EXT); - if (Q_UNLIKELY(!deviceName)) - qFatal("Failed to query device name from EGLDevice"); - - qCDebug(qLcEglfsKmsDebug, "Opening %s", deviceName); - - m_dri_fd = drmOpen(deviceName, Q_NULLPTR); - if (Q_UNLIKELY(m_dri_fd < 0)) - qFatal("Could not open DRM device"); - - if (Q_UNLIKELY(!setup_kms())) - qFatal("Could not set up KMS on device %s!", m_device.constData()); - - qCDebug(qLcEglfsKmsDebug, "DRM/KMS initialized"); -} - -void QEglFSKmsEglDeviceIntegration::platformDestroy() -{ - if (qt_safe_close(m_dri_fd) == -1) - qErrnoWarning("Could not close DRM device"); - - m_dri_fd = -1; - - delete m_funcs; - m_funcs = Q_NULLPTR; -} - -EGLNativeDisplayType QEglFSKmsEglDeviceIntegration::platformDisplay() const -{ - return static_cast(m_egl_device); + return EGL_STREAM_BIT_KHR; } EGLDisplay QEglFSKmsEglDeviceIntegration::createDisplay(EGLNativeDisplayType nativeDisplay) @@ -120,46 +87,17 @@ EGLDisplay QEglFSKmsEglDeviceIntegration::createDisplay(EGLNativeDisplayType nat return display; } -QSizeF QEglFSKmsEglDeviceIntegration::physicalScreenSize() const +bool QEglFSKmsEglDeviceIntegration::supportsSurfacelessContexts() const { - const int defaultPhysicalDpi = 100; - static const int width = qEnvironmentVariableIntValue("QT_QPA_EGLFS_PHYSICAL_WIDTH"); - static const int height = qEnvironmentVariableIntValue("QT_QPA_EGLFS_PHYSICAL_HEIGHT"); - QSizeF size(width, height); - if (size.isEmpty()) { - size = QSizeF(m_drm_connector->mmWidth, m_drm_connector->mmHeight); - if (size.isEmpty()) { - const float pixelsPerMm = Q_MM_PER_INCH / defaultPhysicalDpi; - size = QSizeF(screenSize().width() * pixelsPerMm, screenSize().height() * pixelsPerMm); - } - } - return size; + // Returning false disables the usage of EGL_KHR_surfaceless_context even when the + // extension is available. This is just what we need since, at least with NVIDIA + // 352.00 making a null surface current with a context breaks. + return false; } -QSize QEglFSKmsEglDeviceIntegration::screenSize() const +bool QEglFSKmsEglDeviceIntegration::supportsPBuffers() const { - return QSize(m_drm_mode.hdisplay, m_drm_mode.vdisplay); -} - -int QEglFSKmsEglDeviceIntegration::screenDepth() const -{ - return 32; -} - -QSurfaceFormat QEglFSKmsEglDeviceIntegration::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; -} - -EGLint QEglFSKmsEglDeviceIntegration::surfaceType() const -{ - return EGL_STREAM_BIT_KHR; + return true; } class QEglJetsonTK1Window : public QEglFSWindow @@ -216,11 +154,15 @@ void QEglJetsonTK1Window::resetSurface() return; } + QEglFSKmsScreen *cur_screen = static_cast(screen()); + Q_ASSERT(cur_screen); + qCDebug(qLcEglfsKmsDebug, "Searching for id: %d", cur_screen->output().crtc_id); + for (int i = 0; i < actualCount; ++i) { EGLAttrib id; if (m_integration->m_funcs->query_output_layer_attrib(display, layers[i], EGL_DRM_CRTC_EXT, &id)) { qCDebug(qLcEglfsKmsDebug, " [%d] layer %p - crtc %d", i, layers[i], (int) id); - if (id == EGLAttrib(m_integration->m_drm_crtc)) + if (id == EGLAttrib(cur_screen->output().crtc_id)) layer = layers[i]; } else if (m_integration->m_funcs->query_output_layer_attrib(display, layers[i], EGL_DRM_PLANE_EXT, &id)) { // Not used yet, just for debugging. @@ -251,8 +193,8 @@ void QEglJetsonTK1Window::resetSurface() m_format = q_glFormatFromConfig(display, m_config); qCDebug(qLcEglfsKmsDebug) << "Stream producer format is" << m_format; - const int w = m_integration->screenSize().width(); - const int h = m_integration->screenSize().height(); + const int w = cur_screen->geometry().width(); + const int h = cur_screen->geometry().height(); qCDebug(qLcEglfsKmsDebug, "Creating stream producer surface of size %dx%d", w, h); const EGLint stream_producer_attribs[] = { @@ -280,133 +222,25 @@ QEglFSWindow *QEglFSKmsEglDeviceIntegration::createWindow(QWindow *window) const return eglWindow; } -bool QEglFSKmsEglDeviceIntegration::hasCapability(QPlatformIntegration::Capability cap) const +bool QEglFSKmsEglDeviceIntegration::separateScreens() const { - switch (cap) { - case QPlatformIntegration::ThreadedPixmaps: - case QPlatformIntegration::OpenGL: - case QPlatformIntegration::ThreadedOpenGL: - case QPlatformIntegration::BufferQueueingOpenGL: - return true; - default: - return false; - } -} - -void QEglFSKmsEglDeviceIntegration::waitForVSync(QPlatformSurface *) const -{ - static bool mode_set = false; - - if (!mode_set) { - mode_set = true; - - drmModeCrtcPtr currentMode = drmModeGetCrtc(m_dri_fd, m_drm_crtc); - const bool alreadySet = currentMode - && currentMode->width == m_drm_mode.hdisplay - && currentMode->height == m_drm_mode.vdisplay; - if (currentMode) - drmModeFreeCrtc(currentMode); - if (alreadySet) { - // Maybe detecting the DPMS mode could help here, but there are no properties - // exposed on the connector apparently. So rely on an env var for now. - static bool alwaysDoSet = qEnvironmentVariableIntValue("QT_QPA_EGLFS_ALWAYS_SET_MODE"); - if (!alwaysDoSet) { - qCDebug(qLcEglfsKmsDebug, "Mode already set"); - return; - } - } - - qCDebug(qLcEglfsKmsDebug, "Setting mode"); - int ret = drmModeSetCrtc(m_dri_fd, m_drm_crtc, - -1, 0, 0, - &m_drm_connector->connector_id, 1, - const_cast(&m_drm_mode)); - if (Q_UNLIKELY(ret)) - qFatal("drmModeSetCrtc failed"); - } -} - -qreal QEglFSKmsEglDeviceIntegration::refreshRate() const -{ - quint32 refresh = m_drm_mode.vrefresh; - return refresh > 0 ? refresh : 60; -} - -bool QEglFSKmsEglDeviceIntegration::supportsSurfacelessContexts() const -{ - // Returning false disables the usage of EGL_KHR_surfaceless_context even when the - // extension is available. This is just what we need since, at least with NVIDIA - // 352.00 making a null surface current with a context breaks. - return false; -} - -bool QEglFSKmsEglDeviceIntegration::setup_kms() -{ - drmModeRes *resources; - drmModeConnector *connector; - drmModeEncoder *encoder; - quint32 crtc = 0; - int i; - - resources = drmModeGetResources(m_dri_fd); - if (!resources) { - qWarning("drmModeGetResources failed"); - return false; - } - - for (i = 0; i < resources->count_connectors; i++) { - connector = drmModeGetConnector(m_dri_fd, resources->connectors[i]); - if (!connector) - continue; - - if (connector->connection == DRM_MODE_CONNECTED && connector->count_modes > 0) - break; - - drmModeFreeConnector(connector); - } - - if (i == resources->count_connectors) { - qWarning("No currently active connector found."); - return false; - } - - qCDebug(qLcEglfsKmsDebug, "Using connector with type %d", connector->connector_type); - - for (i = 0; i < resources->count_encoders; i++) { - encoder = drmModeGetEncoder(m_dri_fd, resources->encoders[i]); - if (!encoder) - continue; - - if (encoder->encoder_id == connector->encoder_id) - break; - - drmModeFreeEncoder(encoder); - } - - for (int j = 0; j < resources->count_crtcs; j++) { - if ((encoder->possible_crtcs & (1 << j))) { - crtc = resources->crtcs[j]; - break; - } - } - - if (Q_UNLIKELY(crtc == 0)) - qFatal("No suitable CRTC available"); - - m_drm_connector = connector; - m_drm_encoder = encoder; - m_drm_mode = connector->modes[0]; - m_drm_crtc = crtc; - - qCDebug(qLcEglfsKmsDebug).noquote() << "Using crtc" << m_drm_crtc - << "with mode" << m_drm_mode.hdisplay << "x" << m_drm_mode.vdisplay - << "@" << m_drm_mode.vrefresh; - - drmModeFreeResources(resources); - return true; } +QEglFSKmsDevice *QEglFSKmsEglDeviceIntegration::createDevice(const QString &devicePath) +{ + Q_UNUSED(devicePath) + + if (Q_UNLIKELY(!query_egl_device())) + qFatal("Could not set up EGL device!"); + + const char *deviceName = m_funcs->query_device_string(m_egl_device, EGL_DRM_DEVICE_FILE_EXT); + if (Q_UNLIKELY(!deviceName)) + qFatal("Failed to query device name from EGLDevice"); + + return new QEglFSKmsEglDevice(this, deviceName); +} + bool QEglFSKmsEglDeviceIntegration::query_egl_device() { m_funcs = new QEGLStreamConvenience; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h index 3d8f48d63c..43c1945a7f 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** 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. @@ -40,17 +41,7 @@ #ifndef QEGLFSKMSEGLDEVICEINTEGRATION_H #define QEGLFSKMSEGLDEVICEINTEGRATION_H -#include "qeglfsdeviceintegration.h" -#include "qeglfswindow.h" -#include "qeglfsintegration.h" - -#include -#include -#include -#include -#include -#include -#include +#include #include #include @@ -59,41 +50,28 @@ QT_BEGIN_NAMESPACE -class QEglFSKmsEglDeviceIntegration : public QEGLDeviceIntegration +class QEglFSKmsEglDeviceIntegration : public QEglFSKmsIntegration { public: QEglFSKmsEglDeviceIntegration(); - void platformInit() Q_DECL_OVERRIDE; - void platformDestroy() Q_DECL_OVERRIDE; - EGLNativeDisplayType platformDisplay() const Q_DECL_OVERRIDE; - EGLDisplay createDisplay(EGLNativeDisplayType nativeDisplay) Q_DECL_OVERRIDE; - QSizeF physicalScreenSize() const Q_DECL_OVERRIDE; - QSize screenSize() const Q_DECL_OVERRIDE; - int screenDepth() const Q_DECL_OVERRIDE; - qreal refreshRate() const Q_DECL_OVERRIDE; - QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const Q_DECL_OVERRIDE; EGLint surfaceType() const Q_DECL_OVERRIDE; - QEglFSWindow *createWindow(QWindow *window) const Q_DECL_OVERRIDE; - bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE; - void waitForVSync(QPlatformSurface *surface) const Q_DECL_OVERRIDE; + EGLDisplay createDisplay(EGLNativeDisplayType nativeDisplay) Q_DECL_OVERRIDE; bool supportsSurfacelessContexts() const Q_DECL_OVERRIDE; + bool supportsPBuffers() const Q_DECL_OVERRIDE; + QEglFSWindow *createWindow(QWindow *window) const Q_DECL_OVERRIDE; + virtual bool separateScreens() const Q_DECL_OVERRIDE; +protected: + QEglFSKmsDevice *createDevice(const QString &devicePath) Q_DECL_OVERRIDE; + +private: bool setup_kms(); bool query_egl_device(); - // device bits - QByteArray m_device; - int m_dri_fd; EGLDeviceEXT m_egl_device; - EGLDisplay m_egl_display; - - // KMS bits - drmModeConnector *m_drm_connector; - drmModeEncoder *m_drm_encoder; - drmModeModeInfo m_drm_mode; - quint32 m_drm_crtc; + friend class QEglJetsonTK1Window; // EGLStream infrastructure QEGLStreamConvenience *m_funcs; }; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp new file mode 100644 index 0000000000..da1b577801 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** 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 "qeglfskmsegldevicescreen.h" +#include "qeglfskmsegldevice.h" + +QEglFSKmsEglDeviceScreen::QEglFSKmsEglDeviceScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output, QPoint position) + : QEglFSKmsScreen(integration, device, output, position) +{ +} + +void QEglFSKmsEglDeviceScreen::waitForFlip() +{ + if (!output().mode_set) { + output().mode_set = true; + + drmModeCrtcPtr currentMode = drmModeGetCrtc(device()->fd(), output().crtc_id); + const bool alreadySet = currentMode + && currentMode->width == output().modes[output().mode].hdisplay + && currentMode->height == output().modes[output().mode].vdisplay; + if (currentMode) + drmModeFreeCrtc(currentMode); + if (alreadySet) { + // Maybe detecting the DPMS mode could help here, but there are no properties + // exposed on the connector apparently. So rely on an env var for now. + static bool alwaysDoSet = qEnvironmentVariableIntValue("QT_QPA_EGLFS_ALWAYS_SET_MODE"); + if (!alwaysDoSet) { + qCDebug(qLcEglfsKmsDebug, "Mode already set"); + return; + } + } + + qCDebug(qLcEglfsKmsDebug, "Setting mode"); + int ret = drmModeSetCrtc(device()->fd(), output().crtc_id, + -1, 0, 0, + &output().connector_id, 1, + &output().modes[output().mode]); + if (ret) + qFatal("drmModeSetCrtc failed"); + } + +} diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h new file mode 100644 index 0000000000..0cd46e9f9d --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** 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 QEGLFSKMSEGLDEVICESCREEN_H +#define QEGLFSKMSEGLDEVICESCREEN_H + +#include + +class QEglFSKmsEglDeviceScreen : public QEglFSKmsScreen +{ +public: + QEglFSKmsEglDeviceScreen(QEglFSKmsIntegration *integration, + QEglFSKmsDevice *device, + QEglFSKmsOutput output, + QPoint position); + + void waitForFlip() Q_DECL_OVERRIDE; +}; + +#endif // QEGLFSKMSEGLDEVICESCREEN_H diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro new file mode 100644 index 0000000000..6355fe6abd --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro @@ -0,0 +1,28 @@ +TARGET = QtEglFsKmsSupport +CONFIG += no_module_headers internal_module +load(qt_module) + +QT += core-private gui-private platformsupport-private eglfs_device_lib-private + +INCLUDEPATH += $$PWD/../.. + +# Avoid X11 header collision +DEFINES += MESA_EGL_NO_X11_HEADERS + +CONFIG += link_pkgconfig +!contains(QT_CONFIG, no-pkg-config) { + PKGCONFIG += libdrm +} else { + LIBS += -ldrm +} + +CONFIG += egl +QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF + +SOURCES += $$PWD/qeglfskmsintegration.cpp \ + $$PWD/qeglfskmsdevice.cpp \ + $$PWD/qeglfskmsscreen.cpp \ + +HEADERS += $$PWD/qeglfskmsintegration.h \ + $$PWD/qeglfskmsdevice.h \ + $$PWD/qeglfskmsscreen.h \ diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp similarity index 85% rename from src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp rename to src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp index c4673edb11..f4ffee569d 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp @@ -2,6 +2,7 @@ ** ** Copyright (C) 2015 Pier Luigi Fiorini ** 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. @@ -309,7 +310,7 @@ QEglFSKmsScreen *QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, dr m_crtc_allocator |= (1 << output.crtc_id); m_connector_allocator |= (1 << output.connector_id); - return new QEglFSKmsScreen(m_integration, this, output, pos); + return createScreen(m_integration, this, output, pos); } drmModePropertyPtr QEglFSKmsDevice::connectorProperty(drmModeConnectorPtr connector, const QByteArray &name) @@ -328,68 +329,17 @@ drmModePropertyPtr QEglFSKmsDevice::connectorProperty(drmModeConnectorPtr connec 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(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() +QEglFSKmsDevice::~QEglFSKmsDevice() { - 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() @@ -428,36 +378,27 @@ void QEglFSKmsDevice::createScreens() if (!m_integration->separateScreens()) { Q_FOREACH (QPlatformScreen *screen, siblings) static_cast(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 +QString QEglFSKmsDevice::devicePath() const { - return m_globalCursor; + return m_path; } -void QEglFSKmsDevice::handleDrmEvent() +QEglFSKmsScreen *QEglFSKmsDevice::createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output, QPoint position) { - drmEventContext drmEvent = { - DRM_EVENT_CONTEXT_VERSION, - Q_NULLPTR, // vblank handler - pageFlipHandler // page flip handler - }; + return new QEglFSKmsScreen(integration, device, output, position); +} - drmHandleEvent(m_dri_fd, &drmEvent); +void QEglFSKmsDevice::setFd(int fd) +{ + m_dri_fd = fd; } QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h similarity index 83% rename from src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.h rename to src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h index eab5ac9934..ffa8bcbaa5 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h @@ -2,6 +2,7 @@ ** ** Copyright (C) 2015 Pier Luigi Fiorini ** 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. @@ -41,33 +42,35 @@ #ifndef QEGLFSKMSDEVICE_H #define QEGLFSKMSDEVICE_H -#include "qeglfskmscursor.h" #include "qeglfskmsintegration.h" +#include "qeglfskmsscreen.h" #include #include -#include QT_BEGIN_NAMESPACE -class QEglFSKmsScreen; - -class QEglFSKmsDevice +class Q_EGLFS_EXPORT QEglFSKmsDevice { public: QEglFSKmsDevice(QEglFSKmsIntegration *integration, const QString &path); + virtual ~QEglFSKmsDevice(); - bool open(); - void close(); + virtual bool open() = 0; + virtual void close() = 0; - void createScreens(); + virtual void createScreens(); - gbm_device *device() const; + virtual EGLNativeDisplayType device() const = 0; int fd() const; + QString devicePath() const; - QPlatformCursor *globalCursor() const; - - void handleDrmEvent(); +protected: + virtual QEglFSKmsScreen *createScreen(QEglFSKmsIntegration *integration, + QEglFSKmsDevice *device, + QEglFSKmsOutput output, + QPoint position); + void setFd(int fd); private: Q_DISABLE_COPY(QEglFSKmsDevice) @@ -75,13 +78,10 @@ private: 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); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp similarity index 72% rename from src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp rename to src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp index db503b6e7f..e25e481878 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp @@ -2,6 +2,7 @@ ** ** Copyright (C) 2015 Pier Luigi Fiorini ** 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. @@ -41,11 +42,10 @@ #include "qeglfskmsintegration.h" #include "qeglfskmsdevice.h" #include "qeglfskmsscreen.h" -#include "qeglfskmscursor.h" +#include "qeglfswindow.h" #include "qeglfscursor.h" -#include -#include +#include #include #include #include @@ -55,17 +55,14 @@ #include #include -#include 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_hwCursor(false) , m_pbuffers(false) , m_separateScreens(false) {} @@ -76,21 +73,9 @@ void QEglFSKmsIntegration::platformInit() 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 (Q_UNLIKELY(devices.isEmpty())) - qFatal("Could not find DRM device!"); - - m_devicePath = devices.first(); - qCDebug(qLcEglfsKmsDebug) << "Using" << m_devicePath; } - m_device = new QEglFSKmsDevice(this, m_devicePath); + m_device = createDevice(m_devicePath); if (Q_UNLIKELY(!m_device->open())) qFatal("Could not open device %s - aborting!", qPrintable(m_devicePath)); } @@ -129,42 +114,6 @@ QSurfaceFormat QEglFSKmsIntegration::surfaceFormatFor(const QSurfaceFormat &inpu return format; } -EGLNativeWindowType QEglFSKmsIntegration::createNativeWindow(QPlatformWindow *platformWindow, - const QSize &size, - const QSurfaceFormat &format) -{ - Q_UNUSED(size); - Q_UNUSED(format); - - QEglFSKmsScreen *screen = static_cast(platformWindow->screen()); - if (screen->surface()) { - qWarning("Only single window per screen supported!"); - return 0; - } - - return reinterpret_cast(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(surface); -} - -void QEglFSKmsIntegration::destroyNativeWindow(EGLNativeWindowType window) -{ - gbm_surface *surface = reinterpret_cast(window); - gbm_surface_destroy(surface); -} - bool QEglFSKmsIntegration::hasCapability(QPlatformIntegration::Capability cap) const { switch (cap) { @@ -177,14 +126,6 @@ bool QEglFSKmsIntegration::hasCapability(QPlatformIntegration::Capability cap) c } } -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(surface->surface()); @@ -193,14 +134,6 @@ void QEglFSKmsIntegration::waitForVSync(QPlatformSurface *surface) const screen->waitForFlip(); } -void QEglFSKmsIntegration::presentBuffer(QPlatformSurface *surface) -{ - QWindow *window = static_cast(surface->surface()); - QEglFSKmsScreen *screen = static_cast(window->screen()->handle()); - - screen->flip(); -} - bool QEglFSKmsIntegration::supportsPBuffers() const { return m_pbuffers; @@ -221,6 +154,11 @@ QMap QEglFSKmsIntegration::outputSettings() const return m_outputSettings; } +QEglFSKmsDevice *QEglFSKmsIntegration::device() const +{ + return m_device; +} + void QEglFSKmsIntegration::loadConfig() { static QByteArray json = qgetenv("QT_QPA_EGLFS_KMS_CONFIG"); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h similarity index 82% rename from src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.h rename to src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h index ed0cb6a096..c630d93fce 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h @@ -2,6 +2,7 @@ ** ** Copyright (C) 2015 Pier Luigi Fiorini ** 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. @@ -44,12 +45,15 @@ #include "qeglfsdeviceintegration.h" #include #include +#include QT_BEGIN_NAMESPACE class QEglFSKmsDevice; -class QEglFSKmsIntegration : public QEGLDeviceIntegration +Q_EGLFS_EXPORT Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug) + +class Q_EGLFS_EXPORT QEglFSKmsIntegration : public QEGLDeviceIntegration { public: QEglFSKmsIntegration(); @@ -60,21 +64,19 @@ public: 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; + virtual bool hwCursor() const; + virtual bool separateScreens() const; QMap outputSettings() const; + QEglFSKmsDevice *device() const; + +protected: + virtual QEglFSKmsDevice *createDevice(const QString &devicePath) = 0; + private: void loadConfig(); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp similarity index 60% rename from src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp rename to src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp index f53c3e9132..f614351a40 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp @@ -2,6 +2,7 @@ ** ** Copyright (C) 2015 Pier Luigi Fiorini ** 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. @@ -40,7 +41,6 @@ #include "qeglfskmsscreen.h" #include "qeglfskmsdevice.h" -#include "qeglfskmscursor.h" #include "qeglfsintegration.h" #include @@ -69,45 +69,6 @@ private: QEglFSKmsScreen *m_screen; }; -void QEglFSKmsScreen::bufferDestroyedHandler(gbm_bo *bo, void *data) -{ - FrameBuffer *fb = static_cast(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(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 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, @@ -115,12 +76,8 @@ QEglFSKmsScreen::QEglFSKmsScreen(QEglFSKmsIntegration *integration, : QEglFSScreen(eglGetDisplay(reinterpret_cast(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)) { @@ -191,116 +148,20 @@ 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(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() diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h similarity index 85% rename from src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h rename to src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h index 3f836be143..ed26ca0419 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h @@ -2,6 +2,7 @@ ** ** Copyright (C) 2015 Pier Luigi Fiorini ** 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. @@ -48,12 +49,10 @@ #include #include -#include QT_BEGIN_NAMESPACE class QEglFSKmsDevice; -class QEglFSKmsCursor; class QEglFSKmsInterruptHandler; struct QEglFSKmsOutput @@ -70,7 +69,7 @@ struct QEglFSKmsOutput drmModePropertyPtr dpms_prop; }; -class QEglFSKmsScreen : public QEglFSScreen +class Q_EGLFS_EXPORT QEglFSKmsScreen : public QEglFSScreen { public: QEglFSKmsScreen(QEglFSKmsIntegration *integration, @@ -90,8 +89,6 @@ public: QString name() const Q_DECL_OVERRIDE; - QPlatformCursor *cursor() const Q_DECL_OVERRIDE; - qreal refreshRate() const Q_DECL_OVERRIDE; QList virtualSiblings() const Q_DECL_OVERRIDE { return m_siblings; } @@ -100,13 +97,11 @@ public: 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(); + virtual void waitForFlip(); + virtual void flip(); + virtual void flipFinished(); QEglFSKmsOutput &output() { return m_output; } void restoreMode(); @@ -119,28 +114,14 @@ public: 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 m_cursor; QList 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; };