1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qsgnodeupdater_p.h"
46 // #define QSG_UPDATER_DEBUG
48 QSGNodeUpdater::QSGNodeUpdater()
49 : m_combined_matrix_stack(64)
54 m_opacity_stack.add(1);
57 void QSGNodeUpdater::updateStates(QSGNode *n)
62 Q_ASSERT(m_opacity_stack.size() == 1); // The one we added in the constructr...
63 Q_ASSERT(m_combined_matrix_stack.isEmpty());
69 \fn void QSGNodeUpdater::setToplevelOpacity(qreal opacity)
71 Sets the toplevel opacity that will be multiplied with the
73 The default opacity is 1. Any other value will cause artifacts, and is
74 primarily useful for debug purposes.
76 The changing the value during an update pass will have undefined results
80 \fn qreal QSGNodeUpdater::toplevelOpacity() const
82 Returns the toplevel opacity for the node updater. The default
88 Returns true if \a node is has something that blocks it in the chain from
89 \a node to \a root doing a full state update pass.
91 This function does not process dirty states, simply does a simple traversion
94 The function assumes that \a root exists in the parent chain of \a node.
97 bool QSGNodeUpdater::isNodeBlocked(QSGNode *node, QSGNode *root) const
100 while (node != root && node != 0) {
101 if (node->type() == QSGNode::OpacityNodeType) {
102 opacity *= static_cast<QSGOpacityNode *>(node)->opacity();
106 node = node->parent();
113 void QSGNodeUpdater::enterTransformNode(QSGTransformNode *t)
115 if (t->dirtyState() & QSGNode::DirtyMatrix)
118 #ifdef QSG_UPDATER_DEBUG
119 qDebug() << "enter transform:" << t << "force=" << m_force_update;
122 if (!t->matrix().isIdentity()) {
123 if (!m_combined_matrix_stack.isEmpty()) {
124 t->setCombinedMatrix(*m_combined_matrix_stack.last() * t->matrix());
126 t->setCombinedMatrix(t->matrix());
128 m_combined_matrix_stack.add(&t->combinedMatrix());
130 if (!m_combined_matrix_stack.isEmpty()) {
131 t->setCombinedMatrix(*m_combined_matrix_stack.last());
133 t->setCombinedMatrix(QMatrix4x4());
139 void QSGNodeUpdater::leaveTransformNode(QSGTransformNode *t)
141 #ifdef QSG_UPDATER_DEBUG
142 qDebug() << "leave transform:" << t;
145 if (t->dirtyState() & QSGNode::DirtyMatrix)
148 if (!t->matrix().isIdentity()) {
149 m_combined_matrix_stack.pop_back();
155 void QSGNodeUpdater::enterClipNode(QSGClipNode *c)
157 #ifdef QSG_UPDATER_DEBUG
158 qDebug() << "enter clip:" << c;
161 if (c->dirtyState() & QSGNode::DirtyClipList)
164 c->m_matrix = m_combined_matrix_stack.isEmpty() ? 0 : m_combined_matrix_stack.last();
165 c->m_clip_list = m_current_clip;
170 void QSGNodeUpdater::leaveClipNode(QSGClipNode *c)
172 #ifdef QSG_UPDATER_DEBUG
173 qDebug() << "leave clip:" << c;
176 if (c->dirtyState() & QSGNode::DirtyClipList)
179 m_current_clip = c->m_clip_list;
183 void QSGNodeUpdater::enterGeometryNode(QSGGeometryNode *g)
185 #ifdef QSG_UPDATER_DEBUG
186 qDebug() << "enter geometry:" << g;
189 g->m_matrix = m_combined_matrix_stack.isEmpty() ? 0 : m_combined_matrix_stack.last();
190 g->m_clip_list = m_current_clip;
191 g->setInheritedOpacity(m_opacity_stack.last());
194 void QSGNodeUpdater::leaveGeometryNode(QSGGeometryNode *g)
196 #ifdef QSG_UPDATER_DEBUG
197 qDebug() << "leave geometry" << g;
203 void QSGNodeUpdater::enterOpacityNode(QSGOpacityNode *o)
205 if (o->dirtyState() & QSGNode::DirtyOpacity)
208 qreal opacity = m_opacity_stack.last() * o->opacity();
209 o->setCombinedOpacity(opacity);
210 m_opacity_stack.add(opacity);
212 #ifdef QSG_UPDATER_DEBUG
213 qDebug() << "enter opacity" << o;
217 void QSGNodeUpdater::leaveOpacityNode(QSGOpacityNode *o)
219 #ifdef QSG_UPDATER_DEBUG
220 qDebug() << "leave opacity" << o;
222 if (o->flags() & QSGNode::DirtyOpacity)
225 m_opacity_stack.pop_back();
228 void QSGNodeUpdater::visitChildren(QSGNode *n)
230 for (QSGNode *c = n->firstChild(); c; c = c->nextSibling())
234 void QSGNodeUpdater::visitNode(QSGNode *n)
236 #ifdef QSG_UPDATER_DEBUG
237 qDebug() << "enter:" << n;
240 if (!n->dirtyState() && !m_force_update)
242 if (n->isSubtreeBlocked())
245 bool forceUpdate = n->dirtyState() & (QSGNode::DirtyNodeAdded | QSGNode::DirtyForceUpdate);
250 case QSGNode::TransformNodeType: {
251 QSGTransformNode *t = static_cast<QSGTransformNode *>(n);
252 enterTransformNode(t);
254 leaveTransformNode(t);
256 case QSGNode::GeometryNodeType: {
257 QSGGeometryNode *g = static_cast<QSGGeometryNode *>(n);
258 enterGeometryNode(g);
260 leaveGeometryNode(g);
262 case QSGNode::ClipNodeType: {
263 QSGClipNode *c = static_cast<QSGClipNode *>(n);
268 case QSGNode::OpacityNodeType: {
269 QSGOpacityNode *o = static_cast<QSGOpacityNode *>(n);