1// Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qtickclock_p.h"
5
6#include <QtCore/QThread>
7
8#include <Qt3DCore/private/corelogging_p.h>
9
10QT_BEGIN_NAMESPACE
11
12namespace Qt3DCore {
13
14QTickClock::QTickClock()
15 : m_tickInterval(1000000000 / 60) // Nanoseconds
16 , m_time(0)
17{
18}
19
20void QTickClock::setTickFrequency(float frequency)
21{
22 Q_ASSERT(frequency > 0.0f);
23 m_tickInterval = static_cast<qint64>(1000000000 / frequency);
24}
25
26void QTickClock::start()
27{
28 m_timer.start();
29 m_time = m_timer.nsecsElapsed();
30 qCDebug(ChangeArbiter) << "tickInterval =" << m_tickInterval << "ns";
31}
32
33void QTickClock::reset()
34{
35 m_time = 0;
36}
37
38qint64 QTickClock::waitForNextTick()
39{
40 qint64 t = m_timer.nsecsElapsed();
41 qint64 dt = t - m_time;
42 qint64 timeToSleep = m_tickInterval - dt;
43
44 // If we are lagging behind don't delay
45 // TODO: Do we want a mode where if we are lagging we instead wait
46 // for the next tick instead?
47 if (timeToSleep < 0) {
48 qCDebug(ChangeArbiter) << "Lagging behind desired tick interval";
49 m_time = t;
50 return m_time;
51 }
52
53 unsigned long sleepTimeMicroSeconds = static_cast<unsigned long>(timeToSleep / 1000);
54 //qCDebug(ChangeArbiter) << "sleeping for" << sleepTimeMicroSeconds << "us";
55 QThread::usleep(sleepTimeMicroSeconds);
56
57#if defined(QT3DCORE_DEBUG_TICKCLOCK)
58 qint64 expectedWakeTime = t + sleepTimeMicroSeconds * 1000;
59 qint64 wakeTime = m_timer.nsecsElapsed();
60 qCDebug(ChangeArbiter) << "t =" << t / 1000000 << "timeToSleep =" << timeToSleep / 1000000
61 << "due to wake at =" << expectedWakeTime / 1000000
62 << "actually woke at" << wakeTime / 1000000
63 << "delta =" << (expectedWakeTime - wakeTime) / 1000000;
64#endif
65
66 m_time = m_timer.nsecsElapsed();
67 return m_time;
68}
69
70} // namespace Qt3DCore
71
72QT_END_NAMESPACE
73

source code of qt3d/src/core/qtickclock.cpp