summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/eglfs/deviceintegration
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/eglfs/deviceintegration')
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp48
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp14
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h4
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp44
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h16
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro6
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h6
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp218
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.h99
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp4
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h11
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.cpp2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.h2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp16
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.h2
20 files changed, 426 insertions, 76 deletions
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp
index 4d0cf0c47e..dc98cdce4b 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp
@@ -69,7 +69,7 @@ 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(nullptr)
- , m_cursorImage(0, 0, 0, 0, 0, 0)
+ , m_cursorImage(nullptr, nullptr, 0, 0, 0, 0)
, m_state(CursorPendingVisible)
, m_deviceListener(nullptr)
{
@@ -102,7 +102,7 @@ QEglFSKmsGbmCursor::QEglFSKmsGbmCursor(QEglFSKmsGbmScreen *screen)
#ifndef QT_NO_CURSOR
QCursor cursor(Qt::ArrowCursor);
- changeCursor(&cursor, 0);
+ changeCursor(&cursor, nullptr);
#endif
setPos(QPoint(0, 0));
}
@@ -214,7 +214,8 @@ void QEglFSKmsGbmCursor::changeCursor(QCursor *windowCursor, QWindow *window)
Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) {
QEglFSKmsScreen *kmsScreen = static_cast<QEglFSKmsScreen *>(screen);
-
+ if (kmsScreen->isCursorOutOfRange())
+ continue;
int status = drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, handle,
m_cursorSize.width(), m_cursorSize.height());
if (status != 0)
@@ -232,17 +233,36 @@ void QEglFSKmsGbmCursor::setPos(const QPoint &pos)
{
Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) {
QEglFSKmsScreen *kmsScreen = static_cast<QEglFSKmsScreen *>(screen);
- QPoint origin = kmsScreen->geometry().topLeft();
- QPoint localPos = pos - origin;
- QPoint adjustedPos = localPos - m_cursorImage.hotspot();
-
- int ret = drmModeMoveCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, adjustedPos.x(), adjustedPos.y());
- if (ret == 0)
- m_pos = pos;
- else
- qWarning("Failed to move cursor on screen %s: %d", kmsScreen->name().toLatin1().constData(), ret);
-
- kmsScreen->handleCursorMove(pos);
+ const QRect screenGeom = kmsScreen->geometry();
+ const QPoint origin = screenGeom.topLeft();
+ const QPoint localPos = pos - origin;
+ const QPoint adjustedLocalPos = localPos - m_cursorImage.hotspot();
+
+ if (localPos.x() < 0 || localPos.y() < 0
+ || localPos.x() >= screenGeom.width() || localPos.y() >= screenGeom.height())
+ {
+ if (!kmsScreen->isCursorOutOfRange()) {
+ kmsScreen->setCursorOutOfRange(true);
+ drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0, 0);
+ }
+ } else {
+ int ret;
+ if (kmsScreen->isCursorOutOfRange()) {
+ kmsScreen->setCursorOutOfRange(false);
+ uint32_t handle = gbm_bo_get_handle(m_bo).u32;
+ ret = drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id,
+ handle, m_cursorSize.width(), m_cursorSize.height());
+ } else {
+ ret = drmModeMoveCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id,
+ adjustedLocalPos.x(), adjustedLocalPos.y());
+ }
+ if (ret == 0)
+ m_pos = pos;
+ else
+ qWarning("Failed to move cursor on screen %s: %d", kmsScreen->name().toLatin1().constData(), ret);
+
+ kmsScreen->handleCursorMove(pos);
+ }
}
}
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h
index d47b579238..5d2dfedba2 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h
@@ -85,6 +85,8 @@ public:
void updateMouseStatus();
+ void reevaluateVisibilityForScreens() { setPos(pos()); }
+
private:
void initCursorAtlas();
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp
index 20127ae7f7..503419cf91 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp
@@ -83,6 +83,8 @@ bool QEglFSKmsGbmDevice::open()
setFd(fd);
+ m_eventReader.create(this);
+
return true;
}
@@ -90,6 +92,8 @@ void QEglFSKmsGbmDevice::close()
{
// Note: screens are gone at this stage.
+ m_eventReader.destroy();
+
if (m_gbm_device) {
gbm_device_destroy(m_gbm_device);
m_gbm_device = nullptr;
@@ -155,4 +159,14 @@ void QEglFSKmsGbmDevice::registerScreenCloning(QPlatformScreen *screen,
gbmScreen->initCloning(screenThisScreenClones, screensCloningThisScreen);
}
+void QEglFSKmsGbmDevice::registerScreen(QPlatformScreen *screen,
+ bool isPrimary,
+ const QPoint &virtualPos,
+ const QList<QPlatformScreen *> &virtualSiblings)
+{
+ QEglFSKmsDevice::registerScreen(screen, isPrimary, virtualPos, virtualSiblings);
+ if (screenConfig()->hwCursor() && m_globalCursor)
+ m_globalCursor->reevaluateVisibilityForScreens();
+}
+
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
index 518e2ce58b..f1476f8ffa 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h
@@ -70,6 +70,10 @@ public:
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)
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp
index f154520669..caa1187b40 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp
@@ -54,8 +54,6 @@
QT_BEGIN_NAMESPACE
-QMutex QEglFSKmsGbmScreen::m_waitForFlipMutex;
-
QEglFSKmsGbmIntegration::QEglFSKmsGbmIntegration()
{
qCDebug(qLcEglfsKmsDebug, "New DRM/KMS via GBM integration created");
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
index 16dbfe1522..6f5c3b6953 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
@@ -110,7 +110,7 @@ QEglFSKmsGbmScreen::FrameBuffer *QEglFSKmsGbmScreen::framebufferForBufferObject(
return fb.take();
}
-QEglFSKmsGbmScreen::QEglFSKmsGbmScreen(QKmsDevice *device, const QKmsOutput &output, bool headless)
+QEglFSKmsGbmScreen::QEglFSKmsGbmScreen(QEglFSKmsDevice *device, const QKmsOutput &output, bool headless)
: QEglFSKmsScreen(device, output, headless)
, m_gbm_surface(nullptr)
, m_gbm_bo_current(nullptr)
@@ -243,7 +243,7 @@ void QEglFSKmsGbmScreen::ensureModeSet(uint32_t fb)
if (device()->hasAtomicSupport()) {
#if QT_CONFIG(drm_atomic)
- drmModeAtomicReq *request = device()->atomic_request();
+ drmModeAtomicReq *request = device()->threadLocalAtomicRequest();
if (request) {
drmModeAtomicAddProperty(request, op.connector_id, op.crtcIdPropertyId, op.crtc_id);
drmModeAtomicAddProperty(request, op.crtc_id, op.modeIdPropertyId, op.mode_blob_id);
@@ -276,19 +276,15 @@ void QEglFSKmsGbmScreen::waitForFlip()
if (!m_gbm_bo_next)
return;
- QMutexLocker lock(&m_waitForFlipMutex);
- while (m_gbm_bo_next) {
- drmEventContext drmEvent;
- memset(&drmEvent, 0, sizeof(drmEvent));
- drmEvent.version = 2;
- drmEvent.vblank_handler = nullptr;
- drmEvent.page_flip_handler = pageFlipHandler;
- drmHandleEvent(device()->fd(), &drmEvent);
- }
+ m_flipMutex.lock();
+ device()->eventReader()->startWaitFlip(this, &m_flipMutex, &m_flipCond);
+ m_flipCond.wait(&m_flipMutex);
+ m_flipMutex.unlock();
+
+ flipFinished();
#if QT_CONFIG(drm_atomic)
- if (device()->hasAtomicSupport())
- device()->atomicReset();
+ device()->threadLocalAtomicReset();
#endif
}
@@ -324,16 +320,16 @@ void QEglFSKmsGbmScreen::flip()
if (device()->hasAtomicSupport()) {
#if QT_CONFIG(drm_atomic)
- drmModeAtomicReq *request = device()->atomic_request();
+ 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,
- output().size.width() << 16);
+ 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,
- output().size.height() << 16);
+ 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,
@@ -371,7 +367,7 @@ void QEglFSKmsGbmScreen::flip()
if (device()->hasAtomicSupport()) {
#if QT_CONFIG(drm_atomic)
- drmModeAtomicReq *request = device()->atomic_request();
+ drmModeAtomicReq *request = device()->threadLocalAtomicRequest();
if (request) {
drmModeAtomicAddProperty(request, d.screen->output().eglfs_plane->id,
d.screen->output().eglfs_plane->framebufferPropertyId, fb->fb);
@@ -394,22 +390,10 @@ void QEglFSKmsGbmScreen::flip()
}
#if QT_CONFIG(drm_atomic)
- if (device()->hasAtomicSupport())
- device()->atomicCommit(this);
+ device()->threadLocalAtomicCommit(this);
#endif
}
-void QEglFSKmsGbmScreen::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);
-
- QEglFSKmsGbmScreen *screen = static_cast<QEglFSKmsGbmScreen *>(user_data);
- screen->flipFinished();
-}
-
void QEglFSKmsGbmScreen::flipFinished()
{
if (m_cloneSource) {
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h
index b94f44b7b1..69feeee703 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h
@@ -43,7 +43,8 @@
#define QEGLFSKMSGBMSCREEN_H
#include "qeglfskmsscreen.h"
-#include <QtCore/QMutex>
+#include <QMutex>
+#include <QWaitCondition>
#include <gbm.h>
@@ -54,7 +55,7 @@ class QEglFSKmsGbmCursor;
class QEglFSKmsGbmScreen : public QEglFSKmsScreen
{
public:
- QEglFSKmsGbmScreen(QKmsDevice *device, const QKmsOutput &output, bool headless);
+ QEglFSKmsGbmScreen(QEglFSKmsDevice *device, const QKmsOutput &output, bool headless);
~QEglFSKmsGbmScreen();
QPlatformCursor *cursor() const override;
@@ -75,18 +76,15 @@ private:
void cloneDestFlipFinished(QEglFSKmsGbmScreen *cloneDestScreen);
void updateFlipStatus();
- static void pageFlipHandler(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;
+
QScopedPointer<QEglFSKmsGbmCursor> m_cursor;
struct FrameBuffer {
@@ -101,8 +99,6 @@ private:
bool cloneFlipPending = false;
};
QVector<CloneDestination> m_cloneDests;
-
- static QMutex m_waitForFlipMutex;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp
index 1626c86239..5a62e437c4 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp
@@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug)
-QEglFSKmsEglDeviceScreen::QEglFSKmsEglDeviceScreen(QKmsDevice *device, const QKmsOutput &output)
+QEglFSKmsEglDeviceScreen::QEglFSKmsEglDeviceScreen(QEglFSKmsDevice *device, const QKmsOutput &output)
: QEglFSKmsScreen(device, output)
{
}
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h
index 5efe35f8b3..961398ba3e 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h
@@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE
class QEglFSKmsEglDeviceScreen : public QEglFSKmsScreen
{
public:
- QEglFSKmsEglDeviceScreen(QKmsDevice *device, const QKmsOutput &output);
+ QEglFSKmsEglDeviceScreen(QEglFSKmsDevice *device, const QKmsOutput &output);
~QEglFSKmsEglDeviceScreen();
QPlatformCursor *cursor() const override;
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro
index 40806b6a9b..e51903ed96 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro
@@ -14,9 +14,11 @@ CONFIG += egl
SOURCES += $$PWD/qeglfskmsintegration.cpp \
$$PWD/qeglfskmsdevice.cpp \
- $$PWD/qeglfskmsscreen.cpp
+ $$PWD/qeglfskmsscreen.cpp \
+ $$PWD/qeglfskmseventreader.cpp
HEADERS += $$PWD/qeglfskmsintegration.h \
$$PWD/qeglfskmsdevice.h \
$$PWD/qeglfskmsscreen.h \
- $$PWD/qeglfskmshelpers.h
+ $$PWD/qeglfskmshelpers.h \
+ $$PWD/qeglfskmseventreader.h
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h
index fc83a620d9..34908aa60f 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h
@@ -42,6 +42,7 @@
#define QEGLFSKMSDEVICE_H
#include "private/qeglfsglobal_p.h"
+#include "qeglfskmseventreader.h"
#include <QtKmsSupport/private/qkmsdevice_p.h>
QT_BEGIN_NAMESPACE
@@ -55,6 +56,11 @@ public:
bool isPrimary,
const QPoint &virtualPos,
const QList<QPlatformScreen *> &virtualSiblings) override;
+
+ QEglFSKmsEventReader *eventReader() { return &m_eventReader; }
+
+protected:
+ QEglFSKmsEventReader m_eventReader;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp
new file mode 100644
index 0000000000..645a0ae2e9
--- /dev/null
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp
@@ -0,0 +1,218 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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$
+**
+****************************************************************************/
+
+#include "qeglfskmseventreader.h"
+#include "qeglfskmsdevice.h"
+#include <QSocketNotifier>
+#include <QCoreApplication>
+#include <QLoggingCategory>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug)
+
+static void 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);
+
+ QEglFSKmsEventReaderThread *t = static_cast<QEglFSKmsEventReaderThread *>(QThread::currentThread());
+ t->eventHost()->handlePageFlipCompleted(user_data);
+}
+
+class RegisterWaitFlipEvent : public QEvent
+{
+public:
+ static const QEvent::Type TYPE = QEvent::Type(QEvent::User + 1);
+ RegisterWaitFlipEvent(void *key, QMutex *mutex, QWaitCondition *cond)
+ : QEvent(TYPE), key(key), mutex(mutex), cond(cond)
+ { }
+ void *key;
+ QMutex *mutex;
+ QWaitCondition *cond;
+};
+
+bool QEglFSKmsEventHost::event(QEvent *event)
+{
+ if (event->type() == RegisterWaitFlipEvent::TYPE) {
+ RegisterWaitFlipEvent *e = static_cast<RegisterWaitFlipEvent *>(event);
+ PendingFlipWait *p = &pendingFlipWaits[0];
+ PendingFlipWait *end = p + MAX_FLIPS;
+ while (p < end) {
+ if (!p->key) {
+ p->key = e->key;
+ p->mutex = e->mutex;
+ p->cond = e->cond;
+ updateStatus();
+ return true;
+ }
+ ++p;
+ }
+ qWarning("Cannot queue page flip wait (more than %d screens?)", MAX_FLIPS);
+ e->mutex->lock();
+ e->cond->wakeOne();
+ e->mutex->unlock();
+ return true;
+ }
+ return QObject::event(event);
+}
+
+void QEglFSKmsEventHost::updateStatus()
+{
+ void **begin = &completedFlips[0];
+ void **end = begin + MAX_FLIPS;
+
+ for (int i = 0; i < MAX_FLIPS; ++i) {
+ PendingFlipWait *w = pendingFlipWaits + i;
+ if (!w->key)
+ continue;
+
+ void **p = begin;
+ while (p < end) {
+ if (*p == w->key) {
+ *p = nullptr;
+ w->key = nullptr;
+ w->mutex->lock();
+ w->cond->wakeOne();
+ w->mutex->unlock();
+ return;
+ }
+ ++p;
+ }
+ }
+}
+
+void QEglFSKmsEventHost::handlePageFlipCompleted(void *key)
+{
+ void **begin = &completedFlips[0];
+ void **end = begin + MAX_FLIPS;
+ void **p = begin;
+ while (p < end) {
+ if (*p == key) {
+ updateStatus();
+ return;
+ }
+ ++p;
+ }
+ p = begin;
+ while (p < end) {
+ if (!*p) {
+ *p = key;
+ updateStatus();
+ return;
+ }
+ ++p;
+ }
+ qWarning("Cannot store page flip status (more than %d screens?)", MAX_FLIPS);
+}
+
+void QEglFSKmsEventReaderThread::run()
+{
+ qCDebug(qLcEglfsKmsDebug, "Event reader thread: entering event loop");
+
+ QSocketNotifier notifier(m_fd, QSocketNotifier::Read);
+ QObject::connect(&notifier, &QSocketNotifier::activated, &notifier, [this] {
+ drmEventContext drmEvent;
+ memset(&drmEvent, 0, sizeof(drmEvent));
+ drmEvent.version = 2;
+ drmEvent.vblank_handler = nullptr;
+ drmEvent.page_flip_handler = pageFlipHandler;
+ drmHandleEvent(m_fd, &drmEvent);
+ });
+
+ exec();
+
+ m_ev.moveToThread(thread()); // move back to the thread where m_ev was created
+
+ qCDebug(qLcEglfsKmsDebug, "Event reader thread: event loop stopped");
+}
+
+QEglFSKmsEventReader::~QEglFSKmsEventReader()
+{
+ destroy();
+}
+
+void QEglFSKmsEventReader::create(QEglFSKmsDevice *device)
+{
+ destroy();
+
+ if (!device)
+ return;
+
+ m_device = device;
+
+ qCDebug(qLcEglfsKmsDebug, "Initalizing event reader for device %p fd %d",
+ m_device, m_device->fd());
+
+ m_thread = new QEglFSKmsEventReaderThread(m_device->fd());
+ m_thread->start();
+
+ // Change thread affinity for the event host, so that postEvent()
+ // goes through the event reader thread's event loop for that object.
+ m_thread->eventHost()->moveToThread(m_thread);
+}
+
+void QEglFSKmsEventReader::destroy()
+{
+ if (!m_device)
+ return;
+
+ qCDebug(qLcEglfsKmsDebug, "Stopping event reader for device %p", m_device);
+
+ if (m_thread) {
+ m_thread->quit();
+ m_thread->wait();
+ delete m_thread;
+ m_thread = nullptr;
+ }
+
+ m_device = nullptr;
+}
+
+void QEglFSKmsEventReader::startWaitFlip(void *key, QMutex *mutex, QWaitCondition *cond)
+{
+ if (m_thread) {
+ QCoreApplication::postEvent(m_thread->eventHost(),
+ new RegisterWaitFlipEvent(key, mutex, cond));
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.h
new file mode 100644
index 0000000000..4aa285b0fe
--- /dev/null
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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 QEGLFSKKMSEVENTREADER_H
+#define QEGLFSKKMSEVENTREADER_H
+
+#include "private/qeglfsglobal_p.h"
+#include <QObject>
+#include <QThread>
+#include <QMutex>
+#include <QWaitCondition>
+
+QT_BEGIN_NAMESPACE
+
+class QEglFSKmsDevice;
+
+struct QEglFSKmsEventHost : public QObject
+{
+ struct PendingFlipWait {
+ void *key;
+ QMutex *mutex;
+ QWaitCondition *cond;
+ };
+
+ static const int MAX_FLIPS = 32;
+ void *completedFlips[MAX_FLIPS] = {};
+ QEglFSKmsEventHost::PendingFlipWait pendingFlipWaits[MAX_FLIPS] = {};
+
+ bool event(QEvent *event) override;
+ void updateStatus();
+ void handlePageFlipCompleted(void *key);
+};
+
+class QEglFSKmsEventReaderThread : public QThread
+{
+public:
+ QEglFSKmsEventReaderThread(int fd) : m_fd(fd) { }
+ void run() override;
+ QEglFSKmsEventHost *eventHost() { return &m_ev; }
+
+private:
+ int m_fd;
+ QEglFSKmsEventHost m_ev;
+};
+
+class Q_EGLFS_EXPORT QEglFSKmsEventReader
+{
+public:
+ ~QEglFSKmsEventReader();
+
+ void create(QEglFSKmsDevice *device);
+ void destroy();
+
+ void startWaitFlip(void *key, QMutex *mutex, QWaitCondition *cond);
+
+private:
+ QEglFSKmsDevice *m_device = nullptr;
+ QEglFSKmsEventReaderThread *m_thread = nullptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QEGLFSKKMSEVENTREADER_H
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp
index a6aac61506..28b6b7df63 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp
@@ -140,7 +140,7 @@ void *QEglFSKmsIntegration::nativeResourceForIntegration(const QByteArray &name)
#if QT_CONFIG(drm_atomic)
if (name == QByteArrayLiteral("dri_atomic_request") && m_device)
- return (void *) (qintptr) m_device->atomic_request();
+ return (void *) (qintptr) m_device->threadLocalAtomicRequest();
#endif
return nullptr;
}
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp
index e5354d97bd..959f17eba3 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qeglfskmsscreen.h"
+#include "qeglfskmsdevice.h"
#include "qeglfsintegration_p.h"
#include <QtCore/QLoggingCategory>
@@ -68,10 +69,11 @@ private:
QEglFSKmsScreen *m_screen;
};
-QEglFSKmsScreen::QEglFSKmsScreen(QKmsDevice *device, const QKmsOutput &output, bool headless)
+QEglFSKmsScreen::QEglFSKmsScreen(QEglFSKmsDevice *device, const QKmsOutput &output, bool headless)
: QEglFSScreen(static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration())->display())
, m_device(device)
, m_output(output)
+ , m_cursorOutOfRange(false)
, m_powerState(PowerStateOn)
, m_interruptHandler(new QEglFSKmsInterruptHandler(this))
, m_headless(headless)
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h
index 7f395aacb7..a5c8f5b4e8 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h
@@ -51,12 +51,13 @@
QT_BEGIN_NAMESPACE
+class QEglFSKmsDevice;
class QEglFSKmsInterruptHandler;
class Q_EGLFS_EXPORT QEglFSKmsScreen : public QEglFSScreen
{
public:
- QEglFSKmsScreen(QKmsDevice *device, const QKmsOutput &output, bool headless = false);
+ QEglFSKmsScreen(QEglFSKmsDevice *device, const QKmsOutput &output, bool headless = false);
~QEglFSKmsScreen();
void setVirtualPosition(const QPoint &pos);
@@ -87,7 +88,7 @@ public:
int currentMode() const override;
int preferredMode() const override;
- QKmsDevice *device() const { return m_device; }
+ QEglFSKmsDevice *device() const { return m_device; }
virtual void waitForFlip();
@@ -99,12 +100,16 @@ public:
QPlatformScreen::PowerState powerState() const override;
void setPowerState(QPlatformScreen::PowerState state) override;
+ bool isCursorOutOfRange() const { return m_cursorOutOfRange; }
+ void setCursorOutOfRange(bool b) { m_cursorOutOfRange = b; }
+
protected:
- QKmsDevice *m_device;
+ QEglFSKmsDevice *m_device;
QKmsOutput m_output;
QEdidParser m_edid;
QPoint m_pos;
+ bool m_cursorOutOfRange;
QList<QPlatformScreen *> m_siblings;
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.cpp
index 475d9d55dd..c255bc84b7 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.cpp
@@ -99,7 +99,7 @@ QEglFSKmsVsp2Screen::DmaBuffer *QEglFSKmsVsp2Screen::dmaBufferForGbmBuffer(gbm_b
return fb.take();
}
-QEglFSKmsVsp2Screen::QEglFSKmsVsp2Screen(QKmsDevice *device, const QKmsOutput &output)
+QEglFSKmsVsp2Screen::QEglFSKmsVsp2Screen(QEglFSKmsDevice *device, const QKmsOutput &output)
: QEglFSKmsScreen(device, output)
, m_blender(new Blender(this))
{
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.h
index 7618510333..378786643d 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.h
@@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE
class QEglFSKmsVsp2Screen : public QEglFSKmsScreen
{
public:
- QEglFSKmsVsp2Screen(QKmsDevice *device, const QKmsOutput &output);
+ QEglFSKmsVsp2Screen(QEglFSKmsDevice *device, const QKmsOutput &output);
gbm_surface *createSurface();
void resetSurface();
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp
index 07b2de7c58..ce5a721906 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp
@@ -75,7 +75,7 @@ void EventReader::run()
if (client->format == 32
&& client->type == atoms[Atoms::WM_PROTOCOLS]
&& client->data.data32[0] == atoms[Atoms::WM_DELETE_WINDOW]) {
- QWindow *window = m_integration->platformWindow() ? m_integration->platformWindow()->window() : 0;
+ QWindow *window = m_integration->platformWindow() ? m_integration->platformWindow()->window() : nullptr;
if (window)
QWindowSystemInterface::handleCloseEvent(window);
}
@@ -106,7 +106,7 @@ void QEglFSX11Integration::sendConnectionEvent(xcb_atom_t a)
void QEglFSX11Integration::platformInit()
{
- m_display = XOpenDisplay(0);
+ m_display = XOpenDisplay(nullptr);
if (Q_UNLIKELY(!m_display))
qFatal("Could not open display");
@@ -121,7 +121,7 @@ void QEglFSX11Integration::platformInit()
xcb_create_window(m_connection, XCB_COPY_FROM_PARENT,
m_connectionEventListener, it.data->root,
0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_ONLY,
- it.data->root_visual, 0, 0);
+ it.data->root_visual, 0, nullptr);
m_eventReader = new EventReader(this);
m_eventReader->start();
@@ -135,11 +135,11 @@ void QEglFSX11Integration::platformDestroy()
m_eventReader->wait();
delete m_eventReader;
- m_eventReader = 0;
+ m_eventReader = nullptr;
XCloseDisplay(DISPLAY);
- m_display = 0;
- m_connection = 0;
+ m_display = nullptr;
+ m_connection = nullptr;
}
EGLNativeDisplayType QEglFSX11Integration::platformDisplay() const
@@ -175,7 +175,7 @@ EGLNativeWindowType QEglFSX11Integration::createNativeWindow(QPlatformWindow *pl
xcb_create_window(m_connection, XCB_COPY_FROM_PARENT, m_window, it.data->root,
0, 0, size.width(), size.height(), 0,
XCB_WINDOW_CLASS_INPUT_OUTPUT, it.data->root_visual,
- 0, 0);
+ 0, nullptr);
xcb_intern_atom_cookie_t cookies[Atoms::N_ATOMS];
static const char *atomNames[Atoms::N_ATOMS] = {
@@ -189,7 +189,7 @@ EGLNativeWindowType QEglFSX11Integration::createNativeWindow(QPlatformWindow *pl
for (int i = 0; i < Atoms::N_ATOMS; ++i) {
cookies[i] = xcb_intern_atom(m_connection, false, strlen(atomNames[i]), atomNames[i]);
- xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(m_connection, cookies[i], 0);
+ xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(m_connection, cookies[i], nullptr);
m_atoms[i] = reply->atom;
free(reply);
}
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.h
index bf431caaac..ebcc19b682 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.h
@@ -67,7 +67,7 @@ class EventReader;
class QEglFSX11Integration : public QEglFSDeviceIntegration
{
public:
- QEglFSX11Integration() : m_connection(0), m_window(0), m_eventReader(0) {}
+ QEglFSX11Integration() : m_connection(nullptr), m_window(0), m_eventReader(nullptr) {}
void platformInit() override;
void platformDestroy() override;