From efeccb3f008c3463d333623cbefc8b77dd9db389 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 17 Jan 2018 13:42:21 +0100 Subject: Avoid repeated calls into thread local storage to get the animation timer Instead hold a direct pointer to the animation timer and make it's methods non static. Change-Id: I6382fd2a1c02464ddb573f0210a14c603fd932db Reviewed-by: Simon Hausmann Reviewed-by: J-P Nurmi Reviewed-by: Robin Burchell --- src/qml/animations/qabstractanimationjob.cpp | 73 +++++++++++++--------------- src/qml/animations/qabstractanimationjob_p.h | 11 +++-- 2 files changed, 41 insertions(+), 43 deletions(-) (limited to 'src/qml') diff --git a/src/qml/animations/qabstractanimationjob.cpp b/src/qml/animations/qabstractanimationjob.cpp index 1ac4925ed3..b726d2fc43 100644 --- a/src/qml/animations/qabstractanimationjob.cpp +++ b/src/qml/animations/qabstractanimationjob.cpp @@ -91,9 +91,8 @@ QQmlAnimationTimer *QQmlAnimationTimer::instance() void QQmlAnimationTimer::ensureTimerUpdate() { - QQmlAnimationTimer *inst = QQmlAnimationTimer::instance(false); QUnifiedTimer *instU = QUnifiedTimer::instance(false); - if (instU && inst && inst->isPaused) + if (instU && isPaused) instU->updateAnimationTimers(-1); } @@ -128,9 +127,7 @@ void QQmlAnimationTimer::updateAnimationsTime(qint64 delta) void QQmlAnimationTimer::updateAnimationTimer() { - QQmlAnimationTimer *inst = QQmlAnimationTimer::instance(false); - if (inst) - inst->restartAnimationTimer(); + restartAnimationTimer(); } void QQmlAnimationTimer::restartAnimationTimer() @@ -175,45 +172,38 @@ void QQmlAnimationTimer::registerAnimation(QAbstractAnimationJob *animation, boo if (animation->userControlDisabled()) return; - QQmlAnimationTimer *inst = instance(true); //we create the instance if needed - inst->registerRunningAnimation(animation); + registerRunningAnimation(animation); if (isTopLevel) { Q_ASSERT(!animation->m_hasRegisteredTimer); animation->m_hasRegisteredTimer = true; - inst->animationsToStart << animation; - if (!inst->startAnimationPending) { - inst->startAnimationPending = true; - QMetaObject::invokeMethod(inst, "startAnimations", Qt::QueuedConnection); + animationsToStart << animation; + if (!startAnimationPending) { + startAnimationPending = true; + QMetaObject::invokeMethod(this, "startAnimations", Qt::QueuedConnection); } } } void QQmlAnimationTimer::unregisterAnimation(QAbstractAnimationJob *animation) { - QQmlAnimationTimer *inst = QQmlAnimationTimer::instance(false); - if (inst) { - //at this point the unified timer should have been created - //but it might also have been already destroyed in case the application is shutting down + unregisterRunningAnimation(animation); - inst->unregisterRunningAnimation(animation); - - if (!animation->m_hasRegisteredTimer) - return; + if (!animation->m_hasRegisteredTimer) + return; - int idx = inst->animations.indexOf(animation); - if (idx != -1) { - inst->animations.removeAt(idx); - // this is needed if we unregister an animation while its running - if (idx <= inst->currentAnimationIdx) - --inst->currentAnimationIdx; + int idx = animations.indexOf(animation); + if (idx != -1) { + animations.removeAt(idx); + // this is needed if we unregister an animation while its running + if (idx <= currentAnimationIdx) + --currentAnimationIdx; - if (inst->animations.isEmpty() && !inst->stopTimerPending) { - inst->stopTimerPending = true; - QMetaObject::invokeMethod(inst, "stopTimer", Qt::QueuedConnection); - } - } else { - inst->animationsToStart.removeOne(animation); + if (animations.isEmpty() && !stopTimerPending) { + stopTimerPending = true; + QMetaObject::invokeMethod(this, "stopTimer", Qt::QueuedConnection); } + } else { + animationsToStart.removeOne(animation); } animation->m_hasRegisteredTimer = false; } @@ -302,8 +292,10 @@ QAbstractAnimationJob::~QAbstractAnimationJob() stateChanged(oldState, m_state); Q_ASSERT(m_state == Stopped); - if (oldState == Running) - QQmlAnimationTimer::unregisterAnimation(this); + if (oldState == Running) { + Q_ASSERT(QQmlAnimationTimer::instance() == m_timer); + m_timer->unregisterAnimation(this); + } Q_ASSERT(!m_hasRegisteredTimer); } @@ -327,6 +319,9 @@ void QAbstractAnimationJob::setState(QAbstractAnimationJob::State newState) if (m_loopCount == 0) return; + if (!m_timer) + m_timer = QQmlAnimationTimer::instance(); + State oldState = m_state; int oldCurrentTime = m_currentTime; int oldCurrentLoop = m_currentLoop; @@ -352,11 +347,11 @@ void QAbstractAnimationJob::setState(QAbstractAnimationJob::State newState) bool isTopLevel = !m_group || m_group->isStopped(); if (oldState == Running) { if (newState == Paused && m_hasRegisteredTimer) - QQmlAnimationTimer::ensureTimerUpdate(); + m_timer->ensureTimerUpdate(); //the animation, is not running any more - QQmlAnimationTimer::unregisterAnimation(this); + m_timer->unregisterAnimation(this); } else if (newState == Running) { - QQmlAnimationTimer::registerAnimation(this, isTopLevel); + m_timer->registerAnimation(this, isTopLevel); } //starting an animation qualifies as a top level loop change @@ -383,7 +378,7 @@ void QAbstractAnimationJob::setState(QAbstractAnimationJob::State newState) m_currentLoop = 0; if (isTopLevel) { // currentTime needs to be updated if pauseTimer is active - RETURN_IF_DELETED(QQmlAnimationTimer::ensureTimerUpdate()); + RETURN_IF_DELETED(m_timer->ensureTimerUpdate()); RETURN_IF_DELETED(setCurrentTime(m_totalCurrentTime)); } } @@ -420,14 +415,14 @@ void QAbstractAnimationJob::setDirection(Direction direction) // the commands order below is important: first we need to setCurrentTime with the old direction, // then update the direction on this and all children and finally restart the pauseTimer if needed if (m_hasRegisteredTimer) - QQmlAnimationTimer::ensureTimerUpdate(); + m_timer->ensureTimerUpdate(); m_direction = direction; updateDirection(direction); if (m_hasRegisteredTimer) // needed to update the timer interval in case of a pause animation - QQmlAnimationTimer::updateAnimationTimer(); + m_timer->updateAnimationTimer(); } void QAbstractAnimationJob::setLoopCount(int loopCount) diff --git a/src/qml/animations/qabstractanimationjob_p.h b/src/qml/animations/qabstractanimationjob_p.h index 95a39b1301..63fd4b0dac 100644 --- a/src/qml/animations/qabstractanimationjob_p.h +++ b/src/qml/animations/qabstractanimationjob_p.h @@ -60,6 +60,8 @@ QT_BEGIN_NAMESPACE class QAnimationGroupJob; class QAnimationJobChangeListener; +class QQmlAnimationTimer; + class Q_QML_PRIVATE_EXPORT QAbstractAnimationJob { Q_DISABLE_COPY(QAbstractAnimationJob) @@ -168,6 +170,7 @@ protected: QAbstractAnimationJob *m_nextSibling; QAbstractAnimationJob *m_previousSibling; + QQmlAnimationTimer *m_timer = nullptr; bool *m_wasDeleted; bool m_hasRegisteredTimer:1; @@ -203,20 +206,20 @@ public: static QQmlAnimationTimer *instance(); static QQmlAnimationTimer *instance(bool create); - static void registerAnimation(QAbstractAnimationJob *animation, bool isTopLevel); - static void unregisterAnimation(QAbstractAnimationJob *animation); + void registerAnimation(QAbstractAnimationJob *animation, bool isTopLevel); + void unregisterAnimation(QAbstractAnimationJob *animation); /* this is used for updating the currentTime of all animations in case the pause timer is active or, otherwise, only of the animation passed as parameter. */ - static void ensureTimerUpdate(); + void ensureTimerUpdate(); /* this will evaluate the need of restarting the pause timer in case there is still some pause animations running. */ - static void updateAnimationTimer(); + void updateAnimationTimer(); void restartAnimationTimer() override; void updateAnimationsTime(qint64 timeStep) override; -- cgit v1.2.3