diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2020-04-06 09:52:33 +0200 |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2020-04-16 12:37:35 +0000 |
commit | 0a0e0eb8dca699858435dec5194b0b8b6ebd3cf8 (patch) | |
tree | b63ec5c777c5d4ff39561cff65cca28ae2deb91c | |
parent | 714d1b4850456480cd9161678f723f87659284e9 (diff) | |
download | qtwayland-0a0e0eb8dca699858435dec5194b0b8b6ebd3cf8.tar.gz |
Client: Make frame back callback timeout configurable
To avoid rendering when windows are minimized, we try to detect
this case by checking if 100 ms passes after an update before
any frame callback arrives. Wayland expects to drive the rendering
through frame callbacks, while Qt expects to be informed when a
window is no longer visible and will run a tight, vsynced render loop
until it gets the appropriate event. This mismatch causes issues,
and the timeout is an attempt to avoid actively rendering to a hidden
surface by detecting the missing callbacks.
It causes problems on embedded, though, when a device is so
busy that the timeout happens even when the window is visible.
So we introduce a way to configure the timeout. Either increase
its duration if you can guarantee a certain minimum time between
events even with high load, or set it to 0 to disable it completely.
(at the expense of drawing to invisible windows).
Note that this is required for fixing a critical memory leak that
happens when using Wayland on embedded.
[ChangeLog][Client] Added support for QT_WAYLAND_FRAME_CALLBACK_TIMEOUT
environment variable, which can be used to disable or change the
internal frame callback timeout. If you see windows that stop rendering
or minimize on heavy load, then try setting the variable to 0.
Task-number: QTBUG-82914
Change-Id: I31f48930731c92c0aaf8bbc2e30cdb25fd14ddd1
Reviewed-by: David Edmundson <davidedmundson@kde.org>
-rw-r--r-- | src/client/qwaylandwindow.cpp | 25 | ||||
-rw-r--r-- | src/client/qwaylandwindow_p.h | 1 |
2 files changed, 18 insertions, 8 deletions
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index cf8b60f1..29bc0581 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -85,6 +85,13 @@ QWaylandWindow::QWaylandWindow(QWindow *window) , mFrameQueue(mDisplay->createEventQueue()) , mResizeAfterSwap(qEnvironmentVariableIsSet("QT_WAYLAND_RESIZE_AFTER_SWAP")) { + { + bool ok; + int frameCallbackTimeout = qEnvironmentVariableIntValue("QT_WAYLAND_FRAME_CALLBACK_TIMEOUT", &ok); + if (ok) + mFrameCallbackTimeout = frameCallbackTimeout; + } + static WId id = 1; mWindowId = id++; connect(qApp, &QGuiApplication::screenRemoved, this, &QWaylandWindow::handleScreenRemoved); @@ -1086,7 +1093,7 @@ void QWaylandWindow::timerEvent(QTimerEvent *event) if (event->timerId() != mFrameCallbackCheckIntervalTimerId) return; - bool callbackTimerExpired = mFrameCallbackElapsedTimer.hasExpired(100); + bool callbackTimerExpired = mFrameCallbackElapsedTimer.hasExpired(mFrameCallbackTimeout); if (!mFrameCallbackElapsedTimer.isValid() || callbackTimerExpired ) { killTimer(mFrameCallbackCheckIntervalTimerId); mFrameCallbackCheckIntervalTimerId = -1; @@ -1147,13 +1154,15 @@ void QWaylandWindow::handleUpdate() mWaitingForUpdate = false; // Start a timer for handling the case when the compositor stops sending frame callbacks. - QMetaObject::invokeMethod(this, [this] { - if (mWaitingForFrameCallback) { - if (mFrameCallbackCheckIntervalTimerId < 0) - mFrameCallbackCheckIntervalTimerId = startTimer(100); - mFrameCallbackElapsedTimer.start(); - } - }, Qt::QueuedConnection); + if (mFrameCallbackTimeout > 0) { + QMetaObject::invokeMethod(this, [this] { + if (mWaitingForFrameCallback) { + if (mFrameCallbackCheckIntervalTimerId < 0) + mFrameCallbackCheckIntervalTimerId = startTimer(mFrameCallbackTimeout); + mFrameCallbackElapsedTimer.start(); + } + }, Qt::QueuedConnection); + } } void QWaylandWindow::deliverUpdateRequest() diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h index 0b664bda..60917183 100644 --- a/src/client/qwaylandwindow_p.h +++ b/src/client/qwaylandwindow_p.h @@ -237,6 +237,7 @@ protected: bool mCanResize = true; bool mResizeDirty = false; bool mResizeAfterSwap; + int mFrameCallbackTimeout = 100; QVariantMap m_properties; bool mSentInitialResize = false; |