Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qsgnodeupdater.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5#include "qsgnode.h"
7
9
10// #define QSG_UPDATER_DEBUG
11
12/*!
13 \class QSGNodeUpdater
14 \inmodule QtQuick
15 \internal
16*/
17QSGNodeUpdater::QSGNodeUpdater()
18 : m_combined_matrix_stack(64)
19 , m_opacity_stack(64)
20 , m_current_clip(nullptr)
21 , m_force_update(0)
22{
23 m_opacity_stack.add(1);
24}
25
26QSGNodeUpdater::~QSGNodeUpdater()
27{
28}
29
30void QSGNodeUpdater::updateStates(QSGNode *n)
31{
32 m_current_clip = nullptr;
33 m_force_update = 0;
34
35 Q_ASSERT(m_opacity_stack.size() == 1); // The one we added in the constructr...
36 Q_ASSERT(m_combined_matrix_stack.isEmpty());
37
38 visitNode(n);
39}
40
41
42/*!
43 Returns true if \a node is has something that blocks it in the chain from
44 \a node to \a root doing a full state update pass.
45
46 This function does not process dirty states, simply does a simple traversion
47 up to the top.
48
49 The function assumes that \a root exists in the parent chain of \a node.
50 */
51
52bool QSGNodeUpdater::isNodeBlocked(QSGNode *node, QSGNode *root) const
53{
54 while (node != root && node != nullptr) {
55 if (node->isSubtreeBlocked())
56 return true;
57 node = node->parent();
58 }
59 return false;
60}
61
62
63void QSGNodeUpdater::enterTransformNode(QSGTransformNode *t)
64{
65#ifdef QSG_UPDATER_DEBUG
66 qDebug() << "enter transform:" << t << "force=" << m_force_update;
67#endif
68
69 if (!t->matrix().isIdentity()) {
70 if (!m_combined_matrix_stack.isEmpty()) {
71 t->setCombinedMatrix(*m_combined_matrix_stack.last() * t->matrix());
72 } else {
73 t->setCombinedMatrix(t->matrix());
74 }
75 m_combined_matrix_stack.add(&t->combinedMatrix());
76 } else {
77 if (!m_combined_matrix_stack.isEmpty()) {
78 t->setCombinedMatrix(*m_combined_matrix_stack.last());
79 } else {
80 t->setCombinedMatrix(QMatrix4x4());
81 }
82 }
83}
84
85
86void QSGNodeUpdater::leaveTransformNode(QSGTransformNode *t)
87{
88#ifdef QSG_UPDATER_DEBUG
89 qDebug() << "leave transform:" << t;
90#endif
91
92 if (!t->matrix().isIdentity()) {
93 m_combined_matrix_stack.pop_back();
94 }
95
96}
97
98
99void QSGNodeUpdater::enterClipNode(QSGClipNode *c)
100{
101#ifdef QSG_UPDATER_DEBUG
102 qDebug() << "enter clip:" << c;
103#endif
104
105 c->m_matrix = m_combined_matrix_stack.isEmpty() ? 0 : m_combined_matrix_stack.last();
106 c->m_clip_list = m_current_clip;
107 m_current_clip = c;
108}
109
110
111void QSGNodeUpdater::leaveClipNode(QSGClipNode *c)
112{
113#ifdef QSG_UPDATER_DEBUG
114 qDebug() << "leave clip:" << c;
115#endif
116
117 m_current_clip = c->m_clip_list;
118}
119
120
121void QSGNodeUpdater::enterGeometryNode(QSGGeometryNode *g)
122{
123#ifdef QSG_UPDATER_DEBUG
124 qDebug() << "enter geometry:" << g;
125#endif
126
127 g->m_matrix = m_combined_matrix_stack.isEmpty() ? 0 : m_combined_matrix_stack.last();
128 g->m_clip_list = m_current_clip;
129 g->setInheritedOpacity(m_opacity_stack.last());
130}
131
132void QSGNodeUpdater::leaveGeometryNode(QSGGeometryNode *g)
133{
134#ifdef QSG_UPDATER_DEBUG
135 qDebug() << "leave geometry" << g;
136#else
137 Q_UNUSED(g);
138#endif
139}
140
141void QSGNodeUpdater::enterRenderNode(QSGRenderNode *r)
142{
143#ifdef QSG_UPDATER_DEBUG
144 qDebug() << "enter render:" << r;
145#endif
146
147 QSGRenderNodePrivate *rd = QSGRenderNodePrivate::get(r);
148 rd->m_matrix = m_combined_matrix_stack.isEmpty() ? 0 : m_combined_matrix_stack.last();
149 rd->m_clip_list = m_current_clip;
150 rd->m_opacity = m_opacity_stack.last();
151}
152
153void QSGNodeUpdater::leaveRenderNode(QSGRenderNode *r)
154{
155#ifdef QSG_UPDATER_DEBUG
156 qDebug() << "leave render" << r;
157#else
158 Q_UNUSED(r);
159#endif
160}
161
162void QSGNodeUpdater::enterOpacityNode(QSGOpacityNode *o)
163{
164 qreal opacity = m_opacity_stack.last() * o->opacity();
165 o->setCombinedOpacity(opacity);
166 m_opacity_stack.add(opacity);
167
168#ifdef QSG_UPDATER_DEBUG
169 qDebug() << "enter opacity" << o;
170#endif
171}
172
173void QSGNodeUpdater::leaveOpacityNode(QSGOpacityNode *o)
174{
175#ifdef QSG_UPDATER_DEBUG
176 qDebug() << "leave opacity" << o;
177#endif
178 if (o->flags() & QSGNode::DirtyOpacity)
179 --m_force_update;
180
181 m_opacity_stack.pop_back();
182}
183
184void QSGNodeUpdater::visitChildren(QSGNode *n)
185{
186 for (QSGNode *c = n->firstChild(); c; c = c->nextSibling())
187 visitNode(c);
188}
189
190void QSGNodeUpdater::visitNode(QSGNode *n)
191{
192#ifdef QSG_UPDATER_DEBUG
193 qDebug() << "enter:" << n;
194#endif
195
196 if (!m_force_update)
197 return;
198 if (n->isSubtreeBlocked())
199 return;
200
201 switch (n->type()) {
202 case QSGNode::TransformNodeType: {
203 QSGTransformNode *t = static_cast<QSGTransformNode *>(n);
204 enterTransformNode(t);
205 visitChildren(t);
206 leaveTransformNode(t);
207 break; }
208 case QSGNode::GeometryNodeType: {
209 QSGGeometryNode *g = static_cast<QSGGeometryNode *>(n);
210 enterGeometryNode(g);
211 visitChildren(g);
212 leaveGeometryNode(g);
213 break; }
214 case QSGNode::RenderNodeType: {
215 QSGRenderNode *r = static_cast<QSGRenderNode *>(n);
216 enterRenderNode(r);
217 visitChildren(r);
218 leaveRenderNode(r);
219 break; }
220 case QSGNode::ClipNodeType: {
221 QSGClipNode *c = static_cast<QSGClipNode *>(n);
222 enterClipNode(c);
223 visitChildren(c);
224 leaveClipNode(c);
225 break; }
226 case QSGNode::OpacityNodeType: {
227 QSGOpacityNode *o = static_cast<QSGOpacityNode *>(n);
228 enterOpacityNode(o);
229 visitChildren(o);
230 leaveOpacityNode(o);
231 break; }
232 default:
233 visitChildren(n);
234 break;
235 }
236}
237
238QT_END_NAMESPACE
Combined button and popup list for selecting options.