10#include <private/qquickitem_p.h>
11#if QT_CONFIG(quick_shadereffect)
12#include <private/qquickshadereffect_p.h>
14#include <private/qanimationgroupjob_p.h>
16#include <qcoreapplication.h>
42 if (--helper
->ref == 0) {
43 store.remove(helper->item);
51QQuickAnimatorProxyJob::QQuickAnimatorProxyJob(QAbstractAnimationJob *job,
52 QQuickAbstractAnimation *animation)
53 : m_controller(
nullptr)
54 , m_internalState(State_Stopped)
58 m_isRenderThreadProxy =
true;
60 setLoopCount(job->loopCount());
71 QObject *ctx = findAnimationContext(animation);
73 qWarning(
"QtQuick: unable to find animation context for RT animation...");
77 QQuickWindow *window = qobject_cast<QQuickWindow *>(ctx);
81 QQuickItem *item = qobject_cast<QQuickItem *>(ctx);
83 setWindow(item->window());
84 connect(item, &QQuickItem::windowChanged,
this, &QQuickAnimatorProxyJob::windowChanged);
88void QQuickAnimatorProxyJob::updateLoopCount(
int loopCount)
90 m_job->setLoopCount(loopCount);
93QQuickAnimatorProxyJob::~QQuickAnimatorProxyJob()
95 if (m_job && m_controller)
96 m_controller->cancel(m_job);
100QObject *QQuickAnimatorProxyJob::findAnimationContext(QQuickAbstractAnimation *a)
102 QObject *p = a->parent();
103 while (p !=
nullptr && qobject_cast<QQuickWindow *>(p) ==
nullptr && qobject_cast<QQuickItem *>(p) ==
nullptr)
108void QQuickAnimatorProxyJob::updateCurrentTime(
int)
110 if (m_internalState != State_Running)
115 m_currentLoop = m_job->currentLoop();
120 Q_ASSERT(m_controller);
132 if (!m_controller->isPendingStart(m_job)
133 && !m_job->isRunning()) {
138void QQuickAnimatorProxyJob::updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State)
140 if (m_state == Running) {
141 m_internalState = State_Starting;
143 m_internalState = State_Running;
144 m_controller->start(m_job);
147 }
else if (newState == Stopped) {
148 m_internalState = State_Stopped;
150 syncBackCurrentValues();
151 m_controller->cancel(m_job);
153 }
else if (newState == Paused) {
154 m_internalState = State_Paused;
156 syncBackCurrentValues();
157 m_controller->pause(m_job);
162void QQuickAnimatorProxyJob::debugAnimation(QDebug d)
const
164 d <<
"QuickAnimatorProxyJob("<< Qt::hex << (
const void *)
this << Qt::dec
165 <<
"state:" << state() <<
"duration:" << duration()
166 <<
"proxying: (" << job() <<
')';
169void QQuickAnimatorProxyJob::windowChanged(QQuickWindow *window)
174void QQuickAnimatorProxyJob::setWindow(QQuickWindow *window)
177 if (m_job && m_controller) {
178 disconnect(m_controller->window(), &QQuickWindow::sceneGraphInitialized,
179 this, &QQuickAnimatorProxyJob::sceneGraphInitialized);
180 m_controller->cancel(m_job);
183 m_controller =
nullptr;
186 }
else if (!m_controller && m_job) {
187 m_controller = QQuickWindowPrivate::get(window)->animationController.get();
188 if (window->isSceneGraphInitialized())
191 connect(window, &QQuickWindow::sceneGraphInitialized,
this, &QQuickAnimatorProxyJob::sceneGraphInitialized);
195void QQuickAnimatorProxyJob::sceneGraphInitialized()
198 disconnect(m_controller->window(), &QQuickWindow::sceneGraphInitialized,
this, &QQuickAnimatorProxyJob::sceneGraphInitialized);
203void QQuickAnimatorProxyJob::readyToAnimate()
205 Q_ASSERT(m_controller);
206 if (m_internalState == State_Starting) {
207 m_internalState = State_Running;
208 m_controller->start(m_job);
214 if (job->isRenderThreadJob()) {
215 static_cast<QQuickAnimatorJob *>(job)->writeBack();
217 }
else if (job->isGroup()) {
218 QAnimationGroupJob *g =
static_cast<QAnimationGroupJob *>(job);
219 for (QAbstractAnimationJob *a : *g->children())
220 qquick_syncback_helper(a);
225void QQuickAnimatorProxyJob::syncBackCurrentValues()
228 qquick_syncback_helper(m_job.data());
231QQuickAnimatorJob::QQuickAnimatorJob()
233 , m_controller(
nullptr)
238 , m_isTransform(
false)
241 m_isRenderThreadJob =
true;
244void QQuickAnimatorJob::debugAnimation(QDebug d)
const
246 d <<
"QuickAnimatorJob(" << Qt::hex << (
const void *)
this << Qt::dec
247 <<
") state:" << state() <<
"duration:" << duration()
248 <<
"target:" << m_target <<
"value:" << m_value;
251qreal QQuickAnimatorJob::progress(
int time)
const
253 return m_easing.valueForProgress((m_duration == 0) ? qreal(1) : qreal(time) / qreal(m_duration));
256void QQuickAnimatorJob::boundValue()
258 qreal rangeMin = m_from;
259 qreal rangeMax = m_to;
264 m_value = qBound(rangeMin, m_value, rangeMax);
267qreal QQuickAnimatorJob::value()
const
271 m_controller->lock();
273 m_controller->unlock();
278void QQuickAnimatorJob::setTarget(QQuickItem *target)
283void QQuickAnimatorJob::initialize(QQuickAnimatorController *controller)
285 m_controller = controller;
291 m_isTransform =
true;
297 qquick_transform_animatorjob_helper_store()->release(
m_helper);
305 if (m_helper && m_target)
307 QQuickAnimatorJob::setTarget(item);
313 if (m_helper && (m_helper->item != m_target || !m_target)) {
314 qquick_transform_animatorjob_helper_store()->release(
m_helper);
324 m_helper = qquick_transform_animatorjob_helper_store()->acquire(m_target);
349 const quint32 mask = QQuickItemPrivate::Position
350 | QQuickItemPrivate::BasicTransform
351 | QQuickItemPrivate::TransformOrigin
352 | QQuickItemPrivate::Size;
354 QQuickItemPrivate *d = QQuickItemPrivate::get(item);
355#if QT_CONFIG(quick_shadereffect)
356 if (d->extra.isAllocated()
358 && d->extra->layer->enabled()) {
359 d = QQuickItemPrivate::get(d->extra->layer->m_effectSource);
363 quint32 dirty = mask & d->dirtyAttributes;
371 node = d->itemNode();
376 if (dirty & QQuickItemPrivate::Position) {
381 if (dirty & QQuickItemPrivate::BasicTransform) {
386 if (dirty & (QQuickItemPrivate::TransformOrigin | QQuickItemPrivate::Size)) {
387 QPointF o =
item->transformOriginPoint();
395 if (!wasChanged || !node)
403 m.translate(-
ox, -
oy);
415void QQuickXAnimatorJob::writeBack()
418 m_target->setX(value());
421void QQuickXAnimatorJob::updateCurrentTime(
int time)
426 m_value = m_from + (m_to - m_from) * progress(time);
427 m_helper->dx = m_value;
428 m_helper->wasChanged =
true;
431void QQuickYAnimatorJob::writeBack()
434 m_target->setY(value());
437void QQuickYAnimatorJob::updateCurrentTime(
int time)
442 m_value = m_from + (m_to - m_from) * progress(time);
443 m_helper->dy = m_value;
444 m_helper->wasChanged =
true;
447void QQuickScaleAnimatorJob::writeBack()
450 m_target->setScale(value());
453void QQuickScaleAnimatorJob::updateCurrentTime(
int time)
458 m_value = m_from + (m_to - m_from) * progress(time);
459 m_helper->scale = m_value;
460 m_helper->wasChanged =
true;
464QQuickRotationAnimatorJob::QQuickRotationAnimatorJob()
465 : m_direction(QQuickRotationAnimator::Numerical)
473void QQuickRotationAnimatorJob::updateCurrentTime(
int time)
478 float t = progress(time);
480 switch (m_direction) {
481 case QQuickRotationAnimator::Clockwise:
482 m_value = _q_interpolateClockwiseRotation(m_from, m_to, t).toFloat();
489 case QQuickRotationAnimator::Counterclockwise:
490 m_value = _q_interpolateCounterclockwiseRotation(m_from, m_to, t).toFloat();
492 case QQuickRotationAnimator::Shortest:
493 m_value = _q_interpolateShortestRotation(m_from, m_to, t).toFloat();
495 case QQuickRotationAnimator::Numerical:
496 m_value = m_from + (m_to - m_from) * t;
499 m_helper->rotation = m_value;
500 m_helper->wasChanged =
true;
503void QQuickRotationAnimatorJob::writeBack()
506 m_target->setRotation(value());
510QQuickOpacityAnimatorJob::QQuickOpacityAnimatorJob()
511 : m_opacityNode(
nullptr)
515void QQuickOpacityAnimatorJob::postSync()
522 QQuickItemPrivate *d = QQuickItemPrivate::get(m_target);
523#if QT_CONFIG(quick_shadereffect)
524 if (d->extra.isAllocated()
526 && d->extra->layer->enabled()) {
527 d = QQuickItemPrivate::get(d->extra->layer->m_effectSource);
531 m_opacityNode = d->opacityNode();
533 if (!m_opacityNode) {
534 m_opacityNode =
new QSGOpacityNode();
537
538
539
540
541
542
543
544
545
546
547
548
549 QSGNode *iNode = d->itemNode();
550 QSGNode *child = d->childContainerNode();
551 if (child != iNode) {
553 child->parent()->removeChildNode(child);
554 m_opacityNode->appendChildNode(child);
555 iNode->appendChildNode(m_opacityNode);
557 iNode->reparentChildNodesTo(m_opacityNode);
558 iNode->appendChildNode(m_opacityNode);
561 d->extra.value().opacityNode = m_opacityNode;
562 updateCurrentTime(0);
564 Q_ASSERT(m_opacityNode);
567void QQuickOpacityAnimatorJob::invalidate()
569 m_opacityNode =
nullptr;
572void QQuickOpacityAnimatorJob::writeBack()
575 m_target->setOpacity(value());
578void QQuickOpacityAnimatorJob::updateCurrentTime(
int time)
583 m_value = m_from + (m_to - m_from) * progress(time);
584 m_opacityNode->setOpacity(m_value);
587#if QT_CONFIG(quick_shadereffect)
588QQuickUniformAnimatorJob::QQuickUniformAnimatorJob()
593void QQuickUniformAnimatorJob::setTarget(QQuickItem *target)
596 if (qobject_cast<QQuickShaderEffect *>(target) !=
nullptr)
600void QQuickUniformAnimatorJob::updateCurrentTime(
int time)
602 if (!m_effect || m_target != m_effect)
605 m_value = m_from + (m_to - m_from) * progress(time);
606 m_effect->updateUniformValue(m_uniform, m_value);
609void QQuickUniformAnimatorJob::writeBack()
612 m_target->setProperty(m_uniform, value());
615void QQuickUniformAnimatorJob::postSync()
622 m_effect = qobject_cast<QQuickShaderEffect *>(m_target);
625void QQuickUniformAnimatorJob::invalidate()
633#include "moc_qquickanimatorjob_p.cpp"
Combined button and popup list for selecting options.
QVariant _q_interpolateClockwiseRotation(qreal &f, qreal &t, qreal progress)
QVariant _q_interpolateShortestRotation(qreal &f, qreal &t, qreal progress)
\qmltype RotationAnimation \nativetype QQuickRotationAnimation \inqmlmodule QtQuick\inherits Property...
QVariant _q_interpolateCounterclockwiseRotation(qreal &f, qreal &t, qreal progress)
Q_GLOBAL_STATIC(QQuickTransformAnimatorHelperStore, qquick_transform_animatorjob_helper_store)
static void qquick_syncback_helper(QAbstractAnimationJob *job)