Remove warnings with clang
[profile/ivi/qtdeclarative.git] / src / quick / scenegraph / coreapi / qsgnodeupdater.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
7 **
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.
16 **
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.
20 **
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.
28 **
29 ** Other Usage
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.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qsgnodeupdater_p.h"
43
44 QT_BEGIN_NAMESPACE
45
46 // #define QSG_UPDATER_DEBUG
47
48 QSGNodeUpdater::QSGNodeUpdater()
49     : m_combined_matrix_stack(64)
50     , m_opacity_stack(64)
51     , m_current_clip(0)
52     , m_force_update(0)
53 {
54     m_opacity_stack.add(1);
55 }
56
57 QSGNodeUpdater::~QSGNodeUpdater()
58 {
59 }
60
61 void QSGNodeUpdater::updateStates(QSGNode *n)
62 {
63     m_current_clip = 0;
64     m_force_update = 0;
65
66     Q_ASSERT(m_opacity_stack.size() == 1); // The one we added in the constructr...
67     Q_ASSERT(m_combined_matrix_stack.isEmpty());
68
69     visitNode(n);
70 }
71
72 /*!
73     \fn void QSGNodeUpdater::setToplevelOpacity(qreal opacity)
74
75     Sets the toplevel opacity that will be multiplied with the
76
77     The default opacity is 1. Any other value will cause artifacts, and is
78     primarily useful for debug purposes.
79
80     The changing the value during an update pass will have undefined results
81  */
82
83 /*!
84     \fn qreal QSGNodeUpdater::toplevelOpacity() const
85
86     Returns the toplevel opacity for the node updater. The default
87     value is 1.
88  */
89
90
91 /*!
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.
94
95     This function does not process dirty states, simply does a simple traversion
96     up to the top.
97
98     The function assumes that \a root exists in the parent chain of \a node.
99  */
100
101 bool QSGNodeUpdater::isNodeBlocked(QSGNode *node, QSGNode *root) const
102 {
103     qreal opacity = 1;
104     while (node != root && node != 0) {
105         if (node->type() == QSGNode::OpacityNodeType) {
106             opacity *= static_cast<QSGOpacityNode *>(node)->opacity();
107             if (opacity < 0.001)
108                 return true;
109         }
110         node = node->parent();
111     }
112
113     return false;
114 }
115
116
117 void QSGNodeUpdater::enterTransformNode(QSGTransformNode *t)
118 {
119     if (t->dirtyState() & QSGNode::DirtyMatrix)
120         ++m_force_update;
121
122 #ifdef QSG_UPDATER_DEBUG
123     qDebug() << "enter transform:" << t << "force=" << m_force_update;
124 #endif
125
126     if (!t->matrix().isIdentity()) {
127         if (!m_combined_matrix_stack.isEmpty()) {
128             t->setCombinedMatrix(*m_combined_matrix_stack.last() * t->matrix());
129         } else {
130             t->setCombinedMatrix(t->matrix());
131         }
132         m_combined_matrix_stack.add(&t->combinedMatrix());
133     } else {
134         if (!m_combined_matrix_stack.isEmpty()) {
135             t->setCombinedMatrix(*m_combined_matrix_stack.last());
136         } else {
137             t->setCombinedMatrix(QMatrix4x4());
138         }
139     }
140 }
141
142
143 void QSGNodeUpdater::leaveTransformNode(QSGTransformNode *t)
144 {
145 #ifdef QSG_UPDATER_DEBUG
146     qDebug() << "leave transform:" << t;
147 #endif
148
149     if (t->dirtyState() & QSGNode::DirtyMatrix)
150         --m_force_update;
151
152     if (!t->matrix().isIdentity()) {
153         m_combined_matrix_stack.pop_back();
154     }
155
156 }
157
158
159 void QSGNodeUpdater::enterClipNode(QSGClipNode *c)
160 {
161 #ifdef QSG_UPDATER_DEBUG
162     qDebug() << "enter clip:" << c;
163 #endif
164
165     if (c->dirtyState() & QSGNode::DirtyClipList)
166         ++m_force_update;
167
168     c->m_matrix = m_combined_matrix_stack.isEmpty() ? 0 : m_combined_matrix_stack.last();
169     c->m_clip_list = m_current_clip;
170     m_current_clip = c;
171 }
172
173
174 void QSGNodeUpdater::leaveClipNode(QSGClipNode *c)
175 {
176 #ifdef QSG_UPDATER_DEBUG
177     qDebug() << "leave clip:" << c;
178 #endif
179
180     if (c->dirtyState() & QSGNode::DirtyClipList)
181         --m_force_update;
182
183     m_current_clip = c->m_clip_list;
184 }
185
186
187 void QSGNodeUpdater::enterGeometryNode(QSGGeometryNode *g)
188 {
189 #ifdef QSG_UPDATER_DEBUG
190     qDebug() << "enter geometry:" << g;
191 #endif
192
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());
196 }
197
198 void QSGNodeUpdater::leaveGeometryNode(QSGGeometryNode *g)
199 {
200 #ifdef QSG_UPDATER_DEBUG
201     qDebug() << "leave geometry" << g;
202 #else
203     Q_UNUSED(g)
204 #endif
205 }
206
207 void QSGNodeUpdater::enterOpacityNode(QSGOpacityNode *o)
208 {
209     if (o->dirtyState() & QSGNode::DirtyOpacity)
210         ++m_force_update;
211
212     qreal opacity = m_opacity_stack.last() * o->opacity();
213     o->setCombinedOpacity(opacity);
214     m_opacity_stack.add(opacity);
215
216 #ifdef QSG_UPDATER_DEBUG
217     qDebug() << "enter opacity" << o;
218 #endif
219 }
220
221 void QSGNodeUpdater::leaveOpacityNode(QSGOpacityNode *o)
222 {
223 #ifdef QSG_UPDATER_DEBUG
224     qDebug() << "leave opacity" << o;
225 #endif
226     if (o->flags() & QSGNode::DirtyOpacity)
227         --m_force_update;
228
229     m_opacity_stack.pop_back();
230 }
231
232 void QSGNodeUpdater::visitChildren(QSGNode *n)
233 {
234     for (QSGNode *c = n->firstChild(); c; c = c->nextSibling())
235         visitNode(c);
236 }
237
238 void QSGNodeUpdater::visitNode(QSGNode *n)
239 {
240 #ifdef QSG_UPDATER_DEBUG
241     qDebug() << "enter:" << n;
242 #endif
243
244     if (!n->dirtyState() && !m_force_update)
245         return;
246     if (n->isSubtreeBlocked())
247         return;
248
249     bool forceUpdate = n->dirtyState() & (QSGNode::DirtyNodeAdded | QSGNode::DirtyForceUpdate);
250     if (forceUpdate)
251         ++m_force_update;
252
253     switch (n->type()) {
254     case QSGNode::TransformNodeType: {
255         QSGTransformNode *t = static_cast<QSGTransformNode *>(n);
256         enterTransformNode(t);
257         visitChildren(t);
258         leaveTransformNode(t);
259         break; }
260     case QSGNode::GeometryNodeType: {
261         QSGGeometryNode *g = static_cast<QSGGeometryNode *>(n);
262         enterGeometryNode(g);
263         visitChildren(g);
264         leaveGeometryNode(g);
265         break; }
266     case QSGNode::ClipNodeType: {
267         QSGClipNode *c = static_cast<QSGClipNode *>(n);
268         enterClipNode(c);
269         visitChildren(c);
270         leaveClipNode(c);
271         break; }
272     case QSGNode::OpacityNodeType: {
273         QSGOpacityNode *o = static_cast<QSGOpacityNode *>(n);
274         enterOpacityNode(o);
275         visitChildren(o);
276         leaveOpacityNode(o);
277         break; }
278     default:
279         visitChildren(n);
280         break;
281     }
282
283     if (forceUpdate)
284         --m_force_update;
285
286     n->clearDirty();
287 }
288
289 QT_END_NAMESPACE