aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/util/qquickanimatorjob.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/util/qquickanimatorjob.cpp')
-rw-r--r--src/quick/util/qquickanimatorjob.cpp167
1 files changed, 50 insertions, 117 deletions
diff --git a/src/quick/util/qquickanimatorjob.cpp b/src/quick/util/qquickanimatorjob.cpp
index 0112a4b337..83d5181c34 100644
--- a/src/quick/util/qquickanimatorjob.cpp
+++ b/src/quick/util/qquickanimatorjob.cpp
@@ -1,53 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Gunnar Sletta <gunnar@sletta.org>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2016 Gunnar Sletta <gunnar@sletta.org>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qquickanimatorcontroller_p.h"
#include "qquickanimatorjob_p.h"
#include "qquickanimator_p.h"
#include "qquickanimator_p_p.h"
-#include <private/qquickwindow_p.h>
#include <private/qquickitem_p.h>
-#if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl)
-# include <private/qquickopenglshadereffectnode_p.h>
-# include <private/qquickopenglshadereffect_p.h>
-# include <private/qquickshadereffect_p.h>
+#if QT_CONFIG(quick_shadereffect)
+#include <private/qquickshadereffect_p.h>
#endif
#include <private/qanimationgroupjob_p.h>
@@ -86,14 +47,14 @@ struct QQuickTransformAnimatorHelperStore
};
Q_GLOBAL_STATIC(QQuickTransformAnimatorHelperStore, qquick_transform_animatorjob_helper_store);
-QQuickAnimatorProxyJob::QQuickAnimatorProxyJob(QAbstractAnimationJob *job, QObject *item)
+QQuickAnimatorProxyJob::QQuickAnimatorProxyJob(QAbstractAnimationJob *job,
+ QQuickAbstractAnimation *animation)
: m_controller(nullptr)
, m_internalState(State_Stopped)
{
m_job.reset(job);
m_isRenderThreadProxy = true;
- m_animation = qobject_cast<QQuickAbstractAnimation *>(item);
setLoopCount(job->loopCount());
@@ -106,7 +67,7 @@ QQuickAnimatorProxyJob::QQuickAnimatorProxyJob(QAbstractAnimationJob *job, QObje
// be negligiblie compared to animating and re-rendering the scene on the render thread.
m_duration = -1;
- QObject *ctx = findAnimationContext(m_animation);
+ QObject *ctx = findAnimationContext(animation);
if (!ctx) {
qWarning("QtQuick: unable to find animation context for RT animation...");
return;
@@ -123,6 +84,11 @@ QQuickAnimatorProxyJob::QQuickAnimatorProxyJob(QAbstractAnimationJob *job, QObje
}
}
+void QQuickAnimatorProxyJob::updateLoopCount(int loopCount)
+{
+ m_job->setLoopCount(loopCount);
+}
+
QQuickAnimatorProxyJob::~QQuickAnimatorProxyJob()
{
if (m_job && m_controller)
@@ -143,6 +109,10 @@ void QQuickAnimatorProxyJob::updateCurrentTime(int)
if (m_internalState != State_Running)
return;
+ // Copy current loop number from the job
+ // we could make currentLoop() virtual but it would be less efficient
+ m_currentLoop = m_job->currentLoop();
+
// A proxy which is being ticked should be associated with a window, (see
// setWindow() below). If we get here when there is no more controller we
// have a problem.
@@ -239,7 +209,7 @@ static void qquick_syncback_helper(QAbstractAnimationJob *job)
} else if (job->isGroup()) {
QAnimationGroupJob *g = static_cast<QAnimationGroupJob *>(job);
- for (QAbstractAnimationJob *a = g->firstChild(); a; a = a->nextSibling())
+ for (QAbstractAnimationJob *a : *g->children())
qquick_syncback_helper(a);
}
@@ -276,6 +246,17 @@ qreal QQuickAnimatorJob::progress(int time) const
return m_easing.valueForProgress((m_duration == 0) ? qreal(1) : qreal(time) / qreal(m_duration));
}
+void QQuickAnimatorJob::boundValue()
+{
+ qreal rangeMin = m_from;
+ qreal rangeMax = m_to;
+ if (m_from > m_to) {
+ rangeMax = m_from;
+ rangeMin = m_to;
+ }
+ m_value = qBound(rangeMin, m_value, rangeMax);
+}
+
qreal QQuickAnimatorJob::value() const
{
qreal value = m_to;
@@ -379,11 +360,12 @@ void QQuickTransformAnimatorJob::Helper::sync()
wasSynced = true;
}
+ // We update the node before checking on dirty, as the node might have changed without the animator running
+ node = d->itemNode();
+
if (dirty == 0)
return;
- node = d->itemNode();
-
if (dirty & QQuickItemPrivate::Position) {
dx = item->x();
dy = item->y();
@@ -431,9 +413,6 @@ void QQuickXAnimatorJob::writeBack()
void QQuickXAnimatorJob::updateCurrentTime(int time)
{
-#if QT_CONFIG(opengl)
- Q_ASSERT(!m_controller || !m_controller->m_window->openglContext() || m_controller->m_window->openglContext()->thread() == QThread::currentThread());
-#endif
if (!m_helper)
return;
@@ -450,9 +429,6 @@ void QQuickYAnimatorJob::writeBack()
void QQuickYAnimatorJob::updateCurrentTime(int time)
{
-#if QT_CONFIG(opengl)
- Q_ASSERT(!m_controller || !m_controller->m_window->openglContext() || m_controller->m_window->openglContext()->thread() == QThread::currentThread());
-#endif
if (!m_helper)
return;
@@ -469,9 +445,6 @@ void QQuickScaleAnimatorJob::writeBack()
void QQuickScaleAnimatorJob::updateCurrentTime(int time)
{
-#if QT_CONFIG(opengl)
- Q_ASSERT(!m_controller || !m_controller->m_window->openglContext() || m_controller->m_window->openglContext()->thread() == QThread::currentThread());
-#endif
if (!m_helper)
return;
@@ -492,9 +465,6 @@ extern QVariant _q_interpolateCounterclockwiseRotation(qreal &f, qreal &t, qreal
void QQuickRotationAnimatorJob::updateCurrentTime(int time)
{
-#if QT_CONFIG(opengl)
- Q_ASSERT(!m_controller || !m_controller->m_window->openglContext() || m_controller->m_window->openglContext()->thread() == QThread::currentThread());
-#endif
if (!m_helper)
return;
@@ -582,6 +552,7 @@ void QQuickOpacityAnimatorJob::postSync()
}
d->extra.value().opacityNode = m_opacityNode;
+ updateCurrentTime(0);
}
Q_ASSERT(m_opacityNode);
}
@@ -599,10 +570,6 @@ void QQuickOpacityAnimatorJob::writeBack()
void QQuickOpacityAnimatorJob::updateCurrentTime(int time)
{
-#if QT_CONFIG(opengl)
- Q_ASSERT(!m_controller || !m_controller->m_window->openglContext() || m_controller->m_window->openglContext()->thread() == QThread::currentThread());
-#endif
-
if (!m_opacityNode)
return;
@@ -610,28 +577,32 @@ void QQuickOpacityAnimatorJob::updateCurrentTime(int time)
m_opacityNode->setOpacity(m_value);
}
-
-#if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl)
+#if QT_CONFIG(quick_shadereffect)
QQuickUniformAnimatorJob::QQuickUniformAnimatorJob()
- : m_node(nullptr)
- , m_uniformIndex(-1)
- , m_uniformType(-1)
{
m_isUniform = true;
}
void QQuickUniformAnimatorJob::setTarget(QQuickItem *target)
{
- QQuickShaderEffect* effect = qobject_cast<QQuickShaderEffect*>(target);
- if (effect && effect->isOpenGLShaderEffect())
+ // Check target is of expected type
+ if (qobject_cast<QQuickShaderEffect *>(target) != nullptr)
m_target = target;
}
-void QQuickUniformAnimatorJob::invalidate()
+void QQuickUniformAnimatorJob::updateCurrentTime(int time)
+{
+ if (!m_effect || m_target != m_effect)
+ return;
+
+ m_value = m_from + (m_to - m_from) * progress(time);
+ m_effect->updateUniformValue(m_uniform, m_value);
+}
+
+void QQuickUniformAnimatorJob::writeBack()
{
- m_node = nullptr;
- m_uniformIndex = -1;
- m_uniformType = -1;
+ if (m_target)
+ m_target->setProperty(m_uniform, value());
}
void QQuickUniformAnimatorJob::postSync()
@@ -641,50 +612,12 @@ void QQuickUniformAnimatorJob::postSync()
return;
}
- m_node = static_cast<QQuickOpenGLShaderEffectNode *>(QQuickItemPrivate::get(m_target)->paintNode);
-
- if (m_node && m_uniformIndex == -1 && m_uniformType == -1) {
- QQuickOpenGLShaderEffectMaterial *material =
- static_cast<QQuickOpenGLShaderEffectMaterial *>(m_node->material());
- bool found = false;
- for (int t=0; !found && t<QQuickOpenGLShaderEffectMaterialKey::ShaderTypeCount; ++t) {
- const QVector<QQuickOpenGLShaderEffectMaterial::UniformData> &uniforms = material->uniforms[t];
- for (int i=0; i<uniforms.size(); ++i) {
- if (uniforms.at(i).name == m_uniform) {
- m_uniformIndex = i;
- m_uniformType = t;
- found = true;
- break;
- }
- }
- }
- }
-
+ m_effect = qobject_cast<QQuickShaderEffect *>(m_target);
}
-void QQuickUniformAnimatorJob::updateCurrentTime(int time)
+void QQuickUniformAnimatorJob::invalidate()
{
- if (!m_controller)
- return;
-
- if (!m_node || m_uniformIndex == -1 || m_uniformType == -1)
- return;
-
- m_value = m_from + (m_to - m_from) * progress(time);
- QQuickOpenGLShaderEffectMaterial *material =
- static_cast<QQuickOpenGLShaderEffectMaterial *>(m_node->material());
- material->uniforms[m_uniformType][m_uniformIndex].value = m_value;
- // As we're not touching the nodes, we need to explicitly mark it dirty.
- // Otherwise, the renderer will abort repainting if this was the only
- // change in the graph currently rendering.
- m_node->markDirty(QSGNode::DirtyMaterial);
-}
-
-void QQuickUniformAnimatorJob::writeBack()
-{
- if (m_target)
- m_target->setProperty(m_uniform, value());
}
#endif