summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2020-04-06 09:52:33 +0200
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2020-04-28 10:31:04 +0200
commitefc94a48526baf92b8a78916e03e1fef5993fa95 (patch)
tree99efdbe19eab1811f22fc2ed12ff13f664633ba7
parentfabaaec60a5fe477f7339c0d825d8b236a7e5330 (diff)
Client: Make frame back callback timeout configurablev5.15.0-rc2v5.15.0-rc1v5.15.05.15.0
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. This was mistakenly pushed to 5.12 branch, so it will not be automatically merged upstream. Therefore we have to cherry-pick it. [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 Reviewed-by: David Edmundson <davidedmundson@kde.org> (cherry picked from commit 0a0e0eb8dca699858435dec5194b0b8b6ebd3cf8) Change-Id: I2aeeecb0fab8f7be9b838e477c88eae22b322d75 Reviewed-by: Janne Koskinen <janne.p.koskinen@qt.io>
-rw-r--r--src/client/qwaylandwindow.cpp25
-rw-r--r--src/client/qwaylandwindow_p.h1
2 files changed, 18 insertions, 8 deletions
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
index 884a9793..0545c80f 100644
--- a/src/client/qwaylandwindow.cpp
+++ b/src/client/qwaylandwindow.cpp
@@ -79,6 +79,13 @@ QWaylandWindow::QWaylandWindow(QWindow *window, QWaylandDisplay *display)
, 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++;
initializeWlSurface();
@@ -1096,7 +1103,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;
@@ -1157,13 +1164,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 ef03fd1f..89d6272d 100644
--- a/src/client/qwaylandwindow_p.h
+++ b/src/client/qwaylandwindow_p.h
@@ -240,6 +240,7 @@ protected:
bool mCanResize = true;
bool mResizeDirty = false;
bool mResizeAfterSwap;
+ int mFrameCallbackTimeout = 100;
QVariantMap m_properties;
bool mSentInitialResize = false;