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:
parent
0805c5b07e
commit
7b8771d618
@ -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
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user