summaryrefslogtreecommitdiffstats
path: root/src/corelib/animation
diff options
context:
space:
mode:
authorJan-Arve Sæther <jan-arve.saether@nokia.com>2010-01-07 13:22:53 +0100
committerJan-Arve Sæther <jan-arve.saether@nokia.com>2010-01-08 10:28:41 +0100
commit59a8e0200b912481ff750401ef10c588ad9bd872 (patch)
tree41a1a59bb9320d87cbac6b3c0cf31e16ba902ec7 /src/corelib/animation
parent9701f97b6f14e25b405adb7e82ef0ec93a6b8a0f (diff)
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.cpp2
-rw-r--r--src/corelib/animation/qabstractanimation_p.h62
2 files changed, 62 insertions, 2 deletions
diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp
index 299585a0de..de972d47a5 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 720e68d193..04dd218e70 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;