104 lines
4.2 KiB
Diff
104 lines
4.2 KiB
Diff
|
From efc94a48526baf92b8a78916e03e1fef5993fa95 Mon Sep 17 00:00:00 2001
|
||
|
From: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
||
|
Date: Mon, 06 Apr 2020 09:52:33 +0200
|
||
|
Subject: [PATCH] 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.
|
||
|
|
||
|
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>
|
||
|
---
|
||
|
|
||
|
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
|
||
|
index 884a979..0545c80 100644
|
||
|
--- a/src/client/qwaylandwindow.cpp
|
||
|
+++ b/src/client/qwaylandwindow.cpp
|
||
|
@@ -79,6 +79,13 @@
|
||
|
, 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 @@
|
||
|
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 @@
|
||
|
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 ef03fd1..89d6272 100644
|
||
|
--- a/src/client/qwaylandwindow_p.h
|
||
|
+++ b/src/client/qwaylandwindow_p.h
|
||
|
@@ -240,6 +240,7 @@
|
||
|
bool mCanResize = true;
|
||
|
bool mResizeDirty = false;
|
||
|
bool mResizeAfterSwap;
|
||
|
+ int mFrameCallbackTimeout = 100;
|
||
|
QVariantMap m_properties;
|
||
|
|
||
|
bool mSentInitialResize = false;
|