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
qsgsoftwarerenderablenodeupdater.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
14
15#include <QtQuick/qsgsimplerectnode.h>
16#include <QtQuick/qsgsimpletexturenode.h>
17#include <QtQuick/qsgrendernode.h>
18
19QT_BEGIN_NAMESPACE
20
22 : m_renderer(renderer)
23{
24 m_opacityState.push(1.0f);
25 // Invalid RectF by default for no clip
26 m_clipState.push(QRegion());
27 m_hasClip = false;
28 m_transformState.push(QTransform());
29}
30
31QSGSoftwareRenderableNodeUpdater::~QSGSoftwareRenderableNodeUpdater()
32{
33
34}
35
36bool QSGSoftwareRenderableNodeUpdater::visit(QSGTransformNode *node)
37{
38 m_transformState.push(node->matrix().toTransform() * m_transformState.top());
39 // Renderables in a blocked subtree (e.g. hidden items) are treated as fully
40 // transparent, which skips painting them.
41 m_opacityState.push(node->isSubtreeBlocked() ? 0.0f : m_opacityState.top());
42 m_stateMap[node] = currentState(node);
43 return true;
44}
45
46void QSGSoftwareRenderableNodeUpdater::endVisit(QSGTransformNode *)
47{
48 m_transformState.pop();
49 m_opacityState.pop();
50}
51
52bool QSGSoftwareRenderableNodeUpdater::visit(QSGClipNode *node)
53{
54 // Make sure to translate the clip rect into world coordinates
55 if (m_clipState.size() == 0 || (m_clipState.size() == 1 && m_clipState.top().isNull())) {
56 m_clipState.push(m_transformState.top().map(QRegion(node->clipRect().toRect())));
57 m_hasClip = true;
58 } else {
59 const QRegion transformedClipRect = m_transformState.top().map(QRegion(node->clipRect().toRect()));
60 m_clipState.push(transformedClipRect.intersected(m_clipState.top()));
61 }
62 m_stateMap[node] = currentState(node);
63 return true;
64}
65
66void QSGSoftwareRenderableNodeUpdater::endVisit(QSGClipNode *)
67{
68 m_clipState.pop();
69 if (m_clipState.size() == 0 || (m_clipState.size() == 1 && m_clipState.top().isNull()))
70 m_hasClip = false;
71}
72
73bool QSGSoftwareRenderableNodeUpdater::visit(QSGGeometryNode *node)
74{
75 if (QSGSimpleRectNode *rectNode = dynamic_cast<QSGSimpleRectNode *>(node)) {
76 return updateRenderableNode(QSGSoftwareRenderableNode::SimpleRect, rectNode);
77 } else if (QSGSimpleTextureNode *tn = dynamic_cast<QSGSimpleTextureNode *>(node)) {
78 return updateRenderableNode(QSGSoftwareRenderableNode::SimpleTexture, tn);
79 } else if (QSGNinePatchNode *nn = dynamic_cast<QSGNinePatchNode *>(node)) {
80 return updateRenderableNode(QSGSoftwareRenderableNode::NinePatch, nn);
81 } else if (QSGRectangleNode *rn = dynamic_cast<QSGRectangleNode *>(node)) {
82 return updateRenderableNode(QSGSoftwareRenderableNode::SimpleRectangle, rn);
83 } else if (QSGImageNode *n = dynamic_cast<QSGImageNode *>(node)) {
84 return updateRenderableNode(QSGSoftwareRenderableNode::SimpleImage, n);
85 } else {
86 // We dont know, so skip
87 return false;
88 }
89}
90
91void QSGSoftwareRenderableNodeUpdater::endVisit(QSGGeometryNode *)
92{
93}
94
95bool QSGSoftwareRenderableNodeUpdater::visit(QSGOpacityNode *node)
96{
97 m_opacityState.push(m_opacityState.top() * node->opacity());
98 m_stateMap[node] = currentState(node);
99 return true;
100}
101
102void QSGSoftwareRenderableNodeUpdater::endVisit(QSGOpacityNode *)
103{
104 m_opacityState.pop();
105}
106
107bool QSGSoftwareRenderableNodeUpdater::visit(QSGInternalImageNode *node)
108{
109 return updateRenderableNode(QSGSoftwareRenderableNode::Image, node);
110}
111
112void QSGSoftwareRenderableNodeUpdater::endVisit(QSGInternalImageNode *)
113{
114}
115
116bool QSGSoftwareRenderableNodeUpdater::visit(QSGPainterNode *node)
117{
118 return updateRenderableNode(QSGSoftwareRenderableNode::Painter, node);
119}
120
121void QSGSoftwareRenderableNodeUpdater::endVisit(QSGPainterNode *)
122{
123}
124
125bool QSGSoftwareRenderableNodeUpdater::visit(QSGInternalRectangleNode *node)
126{
127 return updateRenderableNode(QSGSoftwareRenderableNode::Rectangle, node);
128}
129
130void QSGSoftwareRenderableNodeUpdater::endVisit(QSGInternalRectangleNode *)
131{
132}
133
134bool QSGSoftwareRenderableNodeUpdater::visit(QSGGlyphNode *node)
135{
136 return updateRenderableNode(QSGSoftwareRenderableNode::Glyph, node);
137}
138
139void QSGSoftwareRenderableNodeUpdater::endVisit(QSGGlyphNode *)
140{
141}
142
143bool QSGSoftwareRenderableNodeUpdater::visit(QSGRootNode *node)
144{
145 m_stateMap[node] = currentState(node);
146 return true;
147}
148
149void QSGSoftwareRenderableNodeUpdater::endVisit(QSGRootNode *)
150{
151}
152
153#if QT_CONFIG(quick_sprite)
154bool QSGSoftwareRenderableNodeUpdater::visit(QSGSpriteNode *node)
155{
156 return updateRenderableNode(QSGSoftwareRenderableNode::SpriteNode, node);
157}
158
159void QSGSoftwareRenderableNodeUpdater::endVisit(QSGSpriteNode *)
160{
161
162}
163#endif
164
165bool QSGSoftwareRenderableNodeUpdater::visit(QSGRenderNode *node)
166{
167 return updateRenderableNode(QSGSoftwareRenderableNode::RenderNode, node);
168}
169
170void QSGSoftwareRenderableNodeUpdater::endVisit(QSGRenderNode *)
171{
172}
173
174void QSGSoftwareRenderableNodeUpdater::updateNodes(QSGNode *node, bool isNodeRemoved)
175{
176 m_opacityState.clear();
177 m_clipState.clear();
178 m_transformState.clear();
179
180 auto parentNode = node->parent();
181 // If the node was deleted, it will have no parent
182 // check if the state map has the previous parent
183 if ((!parentNode || isNodeRemoved ) && m_stateMap.contains(node))
184 parentNode = m_stateMap[node].parent;
185
186 // If we find a parent, use its state for updating the new children
187 if (parentNode && m_stateMap.contains(parentNode)) {
188 auto state = m_stateMap[parentNode];
189 m_opacityState.push(state.opacity);
190 m_transformState.push(state.transform);
191 m_clipState.push(state.clip);
192 m_hasClip = state.hasClip;
193 } else {
194 // There is no parent, and no previous parent, so likely a root node
195 m_opacityState.push(1.0f);
196 m_transformState.push(QTransform());
197 m_clipState.push(QRegion());
198 m_hasClip = false;
199 }
200
201 // If the node is being removed, then cleanup the state data
202 // Then just visit the children without visiting the now removed node
203 if (isNodeRemoved) {
204 m_stateMap.remove(node);
205 return;
206 }
207
208 // Visit the current node itself first
209 switch (node->type()) {
210 case QSGNode::ClipNodeType: {
211 QSGClipNode *c = static_cast<QSGClipNode*>(node);
212 if (visit(c))
213 visitChildren(c);
214 endVisit(c);
215 break;
216 }
217 case QSGNode::TransformNodeType: {
218 QSGTransformNode *c = static_cast<QSGTransformNode*>(node);
219 if (visit(c))
220 visitChildren(c);
221 endVisit(c);
222 break;
223 }
224 case QSGNode::OpacityNodeType: {
225 QSGOpacityNode *c = static_cast<QSGOpacityNode*>(node);
226 if (visit(c))
227 visitChildren(c);
228 endVisit(c);
229 break;
230 }
231 case QSGNode::GeometryNodeType: {
232 if (node->flags() & QSGNode::IsVisitableNode) {
233 QSGVisitableNode *v = static_cast<QSGVisitableNode*>(node);
234 v->accept(this);
235 } else {
236 QSGGeometryNode *c = static_cast<QSGGeometryNode*>(node);
237 if (visit(c))
238 visitChildren(c);
239 endVisit(c);
240 }
241 break;
242 }
243 case QSGNode::RootNodeType: {
244 QSGRootNode *root = static_cast<QSGRootNode*>(node);
245 if (visit(root))
246 visitChildren(root);
247 endVisit(root);
248 break;
249 }
250 case QSGNode::BasicNodeType: {
251 visitChildren(node);
252 break;
253 }
254 case QSGNode::RenderNodeType: {
255 QSGRenderNode *r = static_cast<QSGRenderNode*>(node);
256 if (visit(r))
257 visitChildren(r);
258 endVisit(r);
259 break;
260 }
261 default:
262 Q_UNREACHABLE();
263 break;
264 }
265}
266
267QSGSoftwareRenderableNodeUpdater::NodeState QSGSoftwareRenderableNodeUpdater::currentState(QSGNode *node) const
268{
269 NodeState state;
270 state.opacity = m_opacityState.top();
271 state.clip = m_clipState.top();
272 state.hasClip = m_hasClip;
273 state.transform = m_transformState.top();
274 state.parent = node->parent();
275 return state;
276}
277
278QT_END_NAMESPACE