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