diff options
author | Jan-Arve Sæther <jan-arve.saether@nokia.com> | 2010-01-07 12:22:53 (GMT) |
---|---|---|
committer | Jan-Arve Sæther <jan-arve.saether@nokia.com> | 2010-01-08 09:28:41 (GMT) |
commit | 59a8e0200b912481ff750401ef10c588ad9bd872 (patch) | |
tree | 41a1a59bb9320d87cbac6b3c0cf31e16ba902ec7 /src/corelib/animation | |
parent | 9701f97b6f14e25b405adb7e82ef0ec93a6b8a0f (diff) | |
download | Qt-59a8e0200b912481ff750401ef10c588ad9bd872.zip Qt-59a8e0200b912481ff750401ef10c588ad9bd872.tar.gz Qt-59a8e0200b912481ff750401ef10c588ad9bd872.tar.bz2 |
Don't use QTime::elapsed() on windows to query for the actual time.
It seems that the time spent between the execution of QTime::start()
and QTime::elapsed() can be higher than what QTime::elapsed() sometimes
reports. (To put it differently, QTime::elapsed() was sometimes
returning a time that was *less* than the actual time spent.)
Note that this is *not* a bug on Windows, since GetLocalTime explicitly
mentions that we should not use local system times to to relative
comparisions (this is what elapsed() currently do).
This is also partly reflected by the documentation of QTime::elapsed(),
where it says that the result of elapsed() is undefined if the clock
setting has been changed.
Due to the fact mentioned in the above paragraph this is also a
potential problem on other platforms (at least Linux and Mac).
However, these platforms do not suffer from the immediate problem we
observed on windows (that QTime::elapsed() could return a too small
value), so this commit only fixes the problem on Windows (it now uses
GetTickCount instead of QTime). For the other platforms the behaviour
should be unchanged, since we still use QTime.
This was found by running the QPauseAnimation autotest, where some
tests were unstable (and failed). However, it did not fail on all
windows systems. (Luckilly it failed on my Win 7 system)
Reviewed-by: Leo
Diffstat (limited to 'src/corelib/animation')
-rw-r--r-- | src/corelib/animation/qabstractanimation.cpp | 2 | ||||
-rw-r--r-- | src/corelib/animation/qabstractanimation_p.h | 62 |
2 files changed, 62 insertions, 2 deletions
diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index 299585a..de972d4 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -242,7 +242,7 @@ void QUnifiedTimer::timerEvent(QTimerEvent *event) animationTimer.stop(); isPauseTimerActive = false; // invalidate the start reference time - time = QTime(); + time.invalidate(); } else { restartAnimationTimer(); if (!time.isValid()) { diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h index 720e68d..04dd218 100644 --- a/src/corelib/animation/qabstractanimation_p.h +++ b/src/corelib/animation/qabstractanimation_p.h @@ -58,6 +58,10 @@ #include <QtCore/qtimer.h> #include <private/qobject_p.h> +#ifdef Q_OS_WIN +#include <qt_windows.h> +#endif + #ifndef QT_NO_ANIMATION QT_BEGIN_NAMESPACE @@ -109,6 +113,61 @@ private: Q_DECLARE_PUBLIC(QAbstractAnimation) }; +class ElapsedTimer +{ +public: + ElapsedTimer() { + invalidate(); + } + + void invalidate() { + m_started = -1; + } + + bool isValid() const { + return m_started >= 0; + } + + void start() { + m_started = getTickCount_sys(); + } + + qint64 elapsed() const { + qint64 current = getTickCount_sys(); + qint64 delta = current - m_started; + if (delta < 0) + delta += getPeriod_sys(); //we wrapped around + return delta; + } + +private: + enum { + MSECS_PER_HOUR = 3600000, + MSECS_PER_MIN = 60000 + }; + + qint64 m_started; + + quint64 getPeriod_sys() const { +#ifdef Q_OS_WIN + return Q_UINT64_C(0x100000000); +#else + // fallback + return 86400 * 1000; +#endif + } + + qint64 getTickCount_sys() const { +#ifdef Q_OS_WIN + return ::GetTickCount(); +#else + // fallback + const QTime t = QTime::currentTime(); + return MSECS_PER_HOUR * t.hour() + MSECS_PER_MIN * t.minute() + 1000 * t.second() + t.msec(); +#endif + } +}; + class QUnifiedTimer : public QObject { @@ -162,7 +221,8 @@ private: // timer used to delay the check if we should start/stop the animation timer QBasicTimer startStopAnimationTimer; - QTime time; + ElapsedTimer time; + int lastTick; int timingInterval; int currentAnimationIdx; |