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
Change-Id: I4cddcd09149dcab9e135467b6ef0e047a2a0ecff
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
(cherry picked from commit 820775166132b073a941f2389fba81db49619688)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Laszlo Agocs 2022-09-19 12:58:05 +02:00 committed by Qt Cherry-pick Bot
parent 0805c5b07e
commit 7b8771d618
5 changed files with 58 additions and 15 deletions

View File

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

View File

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

View File

@ -20,6 +20,8 @@ QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug) Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug)
QMutex QEglFSKmsGbmScreen::m_nonThreadedFlipMutex;
static inline uint32_t drmFormatToGbmFormat(uint32_t drmFormat) static inline uint32_t drmFormatToGbmFormat(uint32_t drmFormat)
{ {
Q_ASSERT(DRM_FORMAT_XRGB8888 == GBM_FORMAT_XRGB8888); 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() void QEglFSKmsGbmScreen::waitForFlip()
{ {
if (m_headless || m_cloneSource) if (m_headless || m_cloneSource)
@ -236,12 +250,24 @@ void QEglFSKmsGbmScreen::waitForFlip()
if (!m_gbm_bo_next) if (!m_gbm_bo_next)
return; return;
QEglFSKmsGbmDevice *dev = static_cast<QEglFSKmsGbmDevice *>(device());
if (dev->usesEventReader()) {
m_flipMutex.lock(); m_flipMutex.lock();
device()->eventReader()->startWaitFlip(this, &m_flipMutex, &m_flipCond); dev->eventReader()->startWaitFlip(this, &m_flipMutex, &m_flipCond);
m_flipCond.wait(&m_flipMutex); m_flipCond.wait(&m_flipMutex);
m_flipMutex.unlock(); m_flipMutex.unlock();
flipFinished(); 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) #if QT_CONFIG(drm_atomic)
device()->threadLocalAtomicReset(); device()->threadLocalAtomicReset();

View File

@ -52,6 +52,11 @@ protected:
void flipFinished(); void flipFinished();
void ensureModeSet(uint32_t fb); void ensureModeSet(uint32_t fb);
void cloneDestFlipFinished(QEglFSKmsGbmScreen *cloneDestScreen); 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; gbm_surface *m_gbm_surface;
@ -61,6 +66,7 @@ protected:
QMutex m_flipMutex; QMutex m_flipMutex;
QWaitCondition m_flipCond; QWaitCondition m_flipCond;
static QMutex m_nonThreadedFlipMutex;
QScopedPointer<QEglFSKmsGbmCursor> m_cursor; QScopedPointer<QEglFSKmsGbmCursor> m_cursor;

View File

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