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 QSGNodeUpdater::~QSGNodeUpdater()
61 void QSGNodeUpdater::updateStates(QSGNode *n)
66 Q_ASSERT(m_opacity_stack.size() == 1); // The one we added in the constructr...
67 Q_ASSERT(m_combined_matrix_stack.isEmpty());
73 \fn void QSGNodeUpdater::setToplevelOpacity(qreal opacity)
75 Sets the toplevel opacity that will be multiplied with the
77 The default opacity is 1. Any other value will cause artifacts, and is
78 primarily useful for debug purposes.
80 The changing the value during an update pass will have undefined results
84 \fn qreal QSGNodeUpdater::toplevelOpacity() const
86 Returns the toplevel opacity for the node updater. The default
92 Returns true if \a node is has something that blocks it in the chain from
93 \a node to \a root doing a full state update pass.
95 This function does not process dirty states, simply does a simple traversion
98 The function assumes that \a root exists in the parent chain of \a node.
101 bool QSGNodeUpdater::isNodeBlocked(QSGNode *node, QSGNode *root) const
104 while (node != root && node != 0) {
105 if (node->type() == QSGNode::OpacityNodeType) {
106 opacity *= static_cast<QSGOpacityNode *>(node)->opacity();
110 node = node->parent();
117 void QSGNodeUpdater::enterTransformNode(QSGTransformNode *t)
119 if (t->dirtyState() & QSGNode::DirtyMatrix)
122 #ifdef QSG_UPDATER_DEBUG
123 qDebug() << "enter transform:" << t << "force=" << m_force_update;
126 if (!t->matrix().isIdentity()) {
127 if (!m_combined_matrix_stack.isEmpty()) {
128 t->setCombinedMatrix(*m_combined_matrix_stack.last() * t->matrix());
130 t->setCombinedMatrix(t->matrix());
132 m_combined_matrix_stack.add(&t->combinedMatrix());
134 if (!m_combined_matrix_stack.isEmpty()) {
135 t->setCombinedMatrix(*m_combined_matrix_stack.last());
137 t->setCombinedMatrix(QMatrix4x4());
143 void QSGNodeUpdater::leaveTransformNode(QSGTransformNode *t)
145 #ifdef QSG_UPDATER_DEBUG
146 qDebug() << "leave transform:" << t;
149 if (t->dirtyState() & QSGNode::DirtyMatrix)
152 if (!t->matrix().isIdentity()) {
153 m_combined_matrix_stack.pop_back();
159 void QSGNodeUpdater::enterClipNode(QSGClipNode *c)
161 #ifdef QSG_UPDATER_DEBUG
162 qDebug() << "enter clip:" << c;
165 if (c->dirtyState() & QSGNode::DirtyClipList)
168 c->m_matrix = m_combined_matrix_stack.isEmpty() ? 0 : m_combined_matrix_stack.last();
169 c->m_clip_list = m_current_clip;
174 void QSGNodeUpdater::leaveClipNode(QSGClipNode *c)
176 #ifdef QSG_UPDATER_DEBUG
177 qDebug() << "leave clip:" << c;
180 if (c->dirtyState() & QSGNode::DirtyClipList)
183 m_current_clip = c->m_clip_list;
187 void QSGNodeUpdater::enterGeometryNode(QSGGeometryNode *g)
189 #ifdef QSG_UPDATER_DEBUG
190 qDebug() << "enter geometry:" << g;
193 g->m_matrix = m_combined_matrix_stack.isEmpty() ? 0 : m_combined_matrix_stack.last();
194 g->m_clip_list = m_current_clip;
195 g->setInheritedOpacity(m_opacity_stack.last());
198 void QSGNodeUpdater::leaveGeometryNode(QSGGeometryNode *g)
200 #ifdef QSG_UPDATER_DEBUG
201 qDebug() << "leave geometry" << g;
207 void QSGNodeUpdater::enterOpacityNode(QSGOpacityNode *o)
209 if (o->dirtyState() & QSGNode::DirtyOpacity)
212 qreal opacity = m_opacity_stack.last() * o->opacity();
213 o->setCombinedOpacity(opacity);
214 m_opacity_stack.add(opacity);
216 #ifdef QSG_UPDATER_DEBUG
217 qDebug() << "enter opacity" << o;
221 void QSGNodeUpdater::leaveOpacityNode(QSGOpacityNode *o)
223 #ifdef QSG_UPDATER_DEBUG
224 qDebug() << "leave opacity" << o;
226 if (o->flags() & QSGNode::DirtyOpacity)
229 m_opacity_stack.pop_back();
232 void QSGNodeUpdater::visitChildren(QSGNode *n)
234 for (QSGNode *c = n->firstChild(); c; c = c->nextSibling())
238 void QSGNodeUpdater::visitNode(QSGNode *n)
240 #ifdef QSG_UPDATER_DEBUG
241 qDebug() << "enter:" << n;
244 if (!n->dirtyState() && !m_force_update)
246 if (n->isSubtreeBlocked())
249 bool forceUpdate = n->dirtyState() & (QSGNode::DirtyNodeAdded | QSGNode::DirtyForceUpdate);
254 case QSGNode::TransformNodeType: {
255 QSGTransformNode *t = static_cast<QSGTransformNode *>(n);
256 enterTransformNode(t);
258 leaveTransformNode(t);
260 case QSGNode::GeometryNodeType: {
261 QSGGeometryNode *g = static_cast<QSGGeometryNode *>(n);
262 enterGeometryNode(g);
264 leaveGeometryNode(g);
266 case QSGNode::ClipNodeType: {
267 QSGClipNode *c = static_cast<QSGClipNode *>(n);
272 case QSGNode::OpacityNodeType: {
273 QSGOpacityNode *o = static_cast<QSGOpacityNode *>(n);