From 5871f3e829f1f48995b5d6c03f7ad31fcda386e5 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta <gunnar@sletta.org> Date: Mon, 20 Oct 2014 13:58:33 +0200 Subject: [PATCH] Tweak new animation driver. We're removing the bad/reallyBad concept for the benefit of an accumulated lag. When the lag passes over a certain threshold, we switch to time based. The logic for switching back remains unchanged. We also fixed the switching so that elapsed() does not jump from the predicted time to the animation system's wall time, but rather continues from the predicted time with a walltime offset (this is how it was always intended to be). Task-number: QTBUG-42020 Change-Id: I7ee9181aca46cbc18a74fae5e8d513365906c017 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com> --- src/quick/scenegraph/qsgcontext.cpp | 36 ++++++++++++++--------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp index 83b221a8cc..b5bdbde3ad 100644 --- a/src/quick/scenegraph/qsgcontext.cpp +++ b/src/quick/scenegraph/qsgcontext.cpp @@ -162,7 +162,6 @@ public: , m_vsync(0) , m_mode(VSyncMode) , m_bad(0) - , m_reallyBad(0) , m_good(0) { QScreen *screen = QGuiApplication::primaryScreen(); @@ -185,6 +184,7 @@ public: { m_time = 0; m_timer.start(); + m_wallTime.restart(); QAnimationDriver::start(); } @@ -192,7 +192,7 @@ public: { return m_mode == VSyncMode ? qint64(m_time) - : QAnimationDriver::elapsed(); + : qint64(m_time) + m_wallTime.elapsed(); } void advance() Q_DECL_OVERRIDE @@ -217,25 +217,22 @@ public: m_time += m_vsync; - if (delta > m_vsync * 5) { - ++m_reallyBad; - ++m_bad; - } else if (delta > m_vsync * 1.25) { - ++m_bad; + if (delta > m_vsync * 1.25) { + m_lag += (delta / m_vsync); + m_bad++; + // We tolerate one bad frame without resorting to timer based. This is + // done to cope with a slow loader frame followed by smooth animation. + // However, on the second frame with massive lag, we switch. + if (m_lag > 10 && m_bad > 2) { + m_mode = TimerMode; + qCDebug(QSG_LOG_INFO, "animation driver switched to timer mode"); + m_wallTime.restart(); + } } else { - // reset counters on a good frame. - m_reallyBad = 0; + m_lag = 0; m_bad = 0; } - // rational for the 3 and 50. If we have several really bad frames - // in a row, that would indicate a huge performance problem and we should - // switch right away. For the case of m_bad, we're a bit more tolerant. - if (m_reallyBad > 3 || m_bad > 50) { - m_mode = TimerMode; - qCDebug(QSG_LOG_INFO, "animation driver switched to timer mode"); - } - } else { if (delta < 1.25 * m_vsync) { ++m_good; @@ -249,6 +246,8 @@ public: if (m_good > 10 && !qsg_useConsistentTiming()) { m_time = elapsed(); m_mode = VSyncMode; + m_bad = 0; + m_lag = 0; qCDebug(QSG_LOG_INFO, "animation driver switched to vsync mode"); } } @@ -260,8 +259,9 @@ public: float m_vsync; Mode m_mode; QElapsedTimer m_timer; + QElapsedTimer m_wallTime; + float m_lag; int m_bad; - int m_reallyBad; int m_good; }; -- GitLab