Use Qt::TimerType on Windows when starting timers
Make all Qt::PreciseTimers and timers with intervals < 20ms use Multimedia timers for maximum accuracy. Qt::CoarseTimers and Qt::VeryCoarseTimers use normal Windows timers, with Qt::VeryCoarseTimers having their interval rounded to the nearest full second. Note that the Windows timer implementation does not attempt to align timers and reduce CPU wakeups like the UNIX implementation does. This might be done in the future, though. However, this change does the best we can do now, keeping most timers working as-is, while allowing explicit use of Multimedia timers via Qt::PreciseTimer. Change-Id: I1898272b101c572a2a9b9454fef27a651eb178f5 Reviewed-by: João Abecasis <joao.abecasis@nokia.com> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com>
This commit is contained in:
parent
c3ad8c1c06
commit
f2edb41c38
@ -2875,4 +2875,10 @@
|
||||
\value PreciseTimer Precise timers try to keep millisecond accuracy
|
||||
\value CoarseTimer Coarse timers try to keep accuracy within 5% of the desired interval
|
||||
\value VeryCoarseTimer Very coarse timers only keep full second accuracy
|
||||
|
||||
On Windows, Qt will use Windows's Multimedia timer facility (if available)
|
||||
for Qt::PreciseTimer and normal Windows timers for Qt::CoarseTimer and
|
||||
Qt::VeryCoarseTimer. The interval for Qt::VeryCoarseTimer is rounded to the
|
||||
nearest full second (e.g. an interval of 23500ms will be rounded to
|
||||
24000ms, and 20300ms to 20000ms).
|
||||
*/
|
||||
|
@ -530,18 +530,21 @@ void QEventDispatcherWin32Private::registerTimer(WinTimerInfo *t)
|
||||
Q_Q(QEventDispatcherWin32);
|
||||
|
||||
int ok = 0;
|
||||
if (t->interval > 20 || !t->interval || !qtimeSetEvent) {
|
||||
uint interval = t->interval;
|
||||
if (interval == 0u) {
|
||||
// optimization for single-shot-zero-timer
|
||||
QCoreApplication::postEvent(q, new QZeroTimerEvent(t->timerId));
|
||||
ok = 1;
|
||||
if (!t->interval) // optimization for single-shot-zero-timer
|
||||
QCoreApplication::postEvent(q, new QZeroTimerEvent(t->timerId));
|
||||
else
|
||||
ok = SetTimer(internalHwnd, t->timerId, (uint) t->interval, 0);
|
||||
} else {
|
||||
ok = t->fastTimerId = qtimeSetEvent(t->interval, 1, qt_fast_timer_proc, (DWORD_PTR)t,
|
||||
} else if ((interval < 20u || t->timerType == Qt::PreciseTimer) && qtimeSetEvent) {
|
||||
ok = t->fastTimerId = qtimeSetEvent(interval, 1, qt_fast_timer_proc, (DWORD_PTR)t,
|
||||
TIME_CALLBACK_FUNCTION | TIME_PERIODIC | TIME_KILL_SYNCHRONOUS);
|
||||
if (ok == 0) { // fall back to normal timer if no more multimedia timers available
|
||||
ok = SetTimer(internalHwnd, t->timerId, (uint) t->interval, 0);
|
||||
}
|
||||
} else if (interval >= 20000u || t->timerType == Qt::VeryCoarseTimer) {
|
||||
// round the interval, VeryCoarseTimers only have full second accuracy
|
||||
interval = ((interval + 500)) / 1000 * 1000;
|
||||
}
|
||||
if (ok == 0) {
|
||||
// user normal timers for (Very)CoarseTimers, or if no more multimedia timers available
|
||||
ok = SetTimer(internalHwnd, t->timerId, interval, 0);
|
||||
}
|
||||
|
||||
if (ok == 0)
|
||||
|
Loading…
Reference in New Issue
Block a user