diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2020-02-21 13:40:38 +0100 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2022-12-12 19:25:44 +0100 |
commit | 6e3170b674d7ae3f2f00f982798a21c635ba3926 (patch) | |
tree | a6b6dfe3117ead5b1a6881e3f0add3cfc449c56a /src/plugins/platforms/eglfs | |
parent | 2d20406f5996e42dfb06c6c19ae28a92314929bf (diff) |
eglfs_kms: Prevent drm errors with more than one window during the screen's lifetime
The QML Live Preview tool exercises the problematic case of having a
QQuickWindow, then closing it, then showing another, then destroying
that, ..., and so on.
It seems that the eglfs_kms backend does not handle this gracefully:
if there was a page flip issued for a window that is then closed, the
new window will result in drm errors (like -22 EINVAL) because the
logic gets confused due to holding on to surface buffers from the old
window.
To remedy this, make sure the same cleanup is performed on a failing
atomic commit as it is done on the non-atomic code path. In addition,
reset more things in resetSurface().
Change-Id: I7e13dbbf4d74b4ed9beaf71472680a0daafb4f95
Fixes: QTBUG-82104
Reviewed-by: Christian Strømme <christian.stromme@qt.io>
Diffstat (limited to 'src/plugins/platforms/eglfs')
-rw-r--r-- | src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp index 722d0266ce..0f829ee00c 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp @@ -161,6 +161,9 @@ gbm_surface *QEglFSKmsGbmScreen::createSurface(EGLConfig eglConfig) void QEglFSKmsGbmScreen::resetSurface() { + m_flipPending = false; + m_gbm_bo_current = nullptr; + m_gbm_bo_next = nullptr; m_gbm_surface = nullptr; } @@ -423,9 +426,15 @@ void QEglFSKmsGbmScreen::flip() } } + if (device()->hasAtomicSupport()) { #if QT_CONFIG(drm_atomic) - device()->threadLocalAtomicCommit(this); + if (!device()->threadLocalAtomicCommit(this)) { + m_flipPending = false; + gbm_surface_release_buffer(m_gbm_surface, m_gbm_bo_next); + m_gbm_bo_next = nullptr; + } #endif + } } void QEglFSKmsGbmScreen::flipFinished() |