eglfs: Add env.var. to disable the dedicated drmHandleEvent thread

Setting QT_QPA_EGLFS_KMS_NO_EVENT_READER_THREAD=1 makes it operate
like it did before 5.12.7: just calling drmhandleEvent (guarded by
a mutex) on the current (main or render, depending on the QQ render
loop) thread.

This should not be needed and is discouraged (will certainly cause
deadlocks in multiscreen setups + QQ threaded render loop on certain
embedded systems), but it seems necessary to provide a way to revert
back to the old way of functioning as there are reports about
problems with screen cloning when the dedicated event reading thread
is used.

Task-number: QTBUG-91882
Pick-to: 6.4 6.3 6.2 5.15
Change-Id: I4cddcd09149dcab9e135467b6ef0e047a2a0ecff
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
This commit is contained in:
Laszlo Agocs 2022-09-19 12:58:05 +02:00
parent 95a3f85a2f
commit 8207751661
5 changed files with 58 additions and 15 deletions

View File

@ -47,7 +47,13 @@ bool QEglFSKmsGbmDevice::open()
setFd(fd);
m_eventReader.create(this);
if (usesEventReader()) {
qCDebug(qLcEglfsKmsDebug, "Using dedicated drm event reading thread");
m_eventReader.create(this);
} else {
qCDebug(qLcEglfsKmsDebug, "Not using dedicated drm event reading thread; "
"threaded multi-screen setups may experience problems");
}
return true;
}
@ -56,7 +62,8 @@ void QEglFSKmsGbmDevice::close()
{
// Note: screens are gone at this stage.
m_eventReader.destroy();
if (usesEventReader())
m_eventReader.destroy();
if (m_gbm_device) {
gbm_device_destroy(m_gbm_device);
@ -138,4 +145,10 @@ void QEglFSKmsGbmDevice::registerScreen(QPlatformScreen *screen,
m_globalCursor->reevaluateVisibilityForScreens();
}
bool QEglFSKmsGbmDevice::usesEventReader() const
{
static const bool eventReaderThreadDisabled = qEnvironmentVariableIntValue("QT_QPA_EGLFS_KMS_NO_EVENT_READER_THREAD");
return !eventReaderThreadDisabled;
}
QT_END_NAMESPACE

View File

@ -19,6 +19,7 @@
#include "qeglfskmsgbmcursor_p.h"
#include <private/qeglfskmsdevice_p.h>
#include <private/qeglfskmseventreader_p.h>
#include <gbm.h>
@ -51,11 +52,14 @@ public:
const QPoint &virtualPos,
const QList<QPlatformScreen *> &virtualSiblings) override;
bool usesEventReader() const;
QEglFSKmsEventReader *eventReader() { return &m_eventReader; }
private:
Q_DISABLE_COPY(QEglFSKmsGbmDevice)
gbm_device *m_gbm_device;
QEglFSKmsEventReader m_eventReader;
QEglFSKmsGbmCursor *m_globalCursor;
};

View File

@ -20,6 +20,8 @@ QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug)
QMutex QEglFSKmsGbmScreen::m_nonThreadedFlipMutex;
static inline uint32_t drmFormatToGbmFormat(uint32_t drmFormat)
{
Q_ASSERT(DRM_FORMAT_XRGB8888 == GBM_FORMAT_XRGB8888);
@ -227,6 +229,18 @@ void QEglFSKmsGbmScreen::ensureModeSet(uint32_t fb)
}
}
void QEglFSKmsGbmScreen::nonThreadedPageFlipHandler(int fd,
unsigned int sequence,
unsigned int tv_sec,
unsigned int tv_usec,
void *user_data)
{
Q_UNUSED(fd);
QEglFSKmsGbmScreen *screen = static_cast<QEglFSKmsGbmScreen *>(user_data);
screen->flipFinished();
screen->pageFlipped(sequence, tv_sec, tv_usec);
}
void QEglFSKmsGbmScreen::waitForFlip()
{
if (m_headless || m_cloneSource)
@ -236,12 +250,24 @@ void QEglFSKmsGbmScreen::waitForFlip()
if (!m_gbm_bo_next)
return;
m_flipMutex.lock();
device()->eventReader()->startWaitFlip(this, &m_flipMutex, &m_flipCond);
m_flipCond.wait(&m_flipMutex);
m_flipMutex.unlock();
flipFinished();
QEglFSKmsGbmDevice *dev = static_cast<QEglFSKmsGbmDevice *>(device());
if (dev->usesEventReader()) {
m_flipMutex.lock();
dev->eventReader()->startWaitFlip(this, &m_flipMutex, &m_flipCond);
m_flipCond.wait(&m_flipMutex);
m_flipMutex.unlock();
flipFinished();
} else {
QMutexLocker lock(&m_nonThreadedFlipMutex);
while (m_gbm_bo_next) {
drmEventContext drmEvent;
memset(&drmEvent, 0, sizeof(drmEvent));
drmEvent.version = 2;
drmEvent.vblank_handler = nullptr;
drmEvent.page_flip_handler = nonThreadedPageFlipHandler;
drmHandleEvent(device()->fd(), &drmEvent);
}
}
#if QT_CONFIG(drm_atomic)
device()->threadLocalAtomicReset();

View File

@ -52,6 +52,11 @@ protected:
void flipFinished();
void ensureModeSet(uint32_t fb);
void cloneDestFlipFinished(QEglFSKmsGbmScreen *cloneDestScreen);
static void nonThreadedPageFlipHandler(int fd,
unsigned int sequence,
unsigned int tv_sec,
unsigned int tv_usec,
void *user_data);
gbm_surface *m_gbm_surface;
@ -61,6 +66,7 @@ protected:
QMutex m_flipMutex;
QWaitCondition m_flipCond;
static QMutex m_nonThreadedFlipMutex;
QScopedPointer<QEglFSKmsGbmCursor> m_cursor;

View File

@ -17,7 +17,6 @@
//
#include "private/qeglfsglobal_p.h"
#include "qeglfskmseventreader_p.h"
#include <QtKmsSupport/private/qkmsdevice_p.h>
QT_BEGIN_NAMESPACE
@ -31,11 +30,6 @@ public:
bool isPrimary,
const QPoint &virtualPos,
const QList<QPlatformScreen *> &virtualSiblings) override;
QEglFSKmsEventReader *eventReader() { return &m_eventReader; }
protected:
QEglFSKmsEventReader m_eventReader;
};
QT_END_NAMESPACE