1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQuick module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef QSGNODE_H
41#define QSGNODE_H
42
43#include <QtQuick/qsggeometry.h>
44#include <QtGui/QMatrix4x4>
45
46#include <float.h>
47
48QT_BEGIN_NAMESPACE
49
50#ifndef QT_NO_DEBUG
51#define QSG_RUNTIME_DESCRIPTION
52#endif
53
54class QSGAbstractRenderer;
55class QSGRenderer;
56
57class QSGNode;
58class QSGRootNode;
59class QSGGeometryNode;
60class QSGTransformNode;
61class QSGClipNode;
62class QSGNodePrivate;
63class QSGBasicGeometryNodePrivate;
64class QSGGeometryNodePrivate;
65
66namespace QSGBatchRenderer {
67 class Renderer;
68 class Updater;
69}
70
71class Q_QUICK_EXPORT QSGNode
72{
73public:
74 enum NodeType {
75 BasicNodeType,
76 GeometryNodeType,
77 TransformNodeType,
78 ClipNodeType,
79 OpacityNodeType,
80 RootNodeType,
81 RenderNodeType
82 };
83
84 enum Flag {
85 // Lower 16 bites reserved for general node
86 OwnedByParent = 0x0001,
87 UsePreprocess = 0x0002,
88
89 // 0x00ff0000 bits reserved for node subclasses
90
91 // QSGBasicGeometryNode
92 OwnsGeometry = 0x00010000,
93 OwnsMaterial = 0x00020000,
94 OwnsOpaqueMaterial = 0x00040000,
95
96 // Uppermost 8 bits are reserved for internal use.
97 IsVisitableNode = 0x01000000
98#ifdef Q_CLANG_QDOC
99 , InternalReserved = 0x01000000
100#endif
101 };
102 Q_DECLARE_FLAGS(Flags, Flag)
103
104 enum DirtyStateBit {
105 DirtySubtreeBlocked = 0x0080,
106 DirtyMatrix = 0x0100,
107 DirtyNodeAdded = 0x0400,
108 DirtyNodeRemoved = 0x0800,
109 DirtyGeometry = 0x1000,
110 DirtyMaterial = 0x2000,
111 DirtyOpacity = 0x4000,
112
113 DirtyForceUpdate = 0x8000,
114
115 DirtyUsePreprocess = UsePreprocess,
116
117 DirtyPropagationMask = DirtyMatrix
118 | DirtyNodeAdded
119 | DirtyOpacity
120 | DirtyForceUpdate
121
122 };
123 Q_DECLARE_FLAGS(DirtyState, DirtyStateBit)
124
125 QSGNode();
126 virtual ~QSGNode();
127
128 QSGNode *parent() const { return m_parent; }
129
130 void removeChildNode(QSGNode *node);
131 void removeAllChildNodes();
132 void prependChildNode(QSGNode *node);
133 void appendChildNode(QSGNode *node);
134 void insertChildNodeBefore(QSGNode *node, QSGNode *before);
135 void insertChildNodeAfter(QSGNode *node, QSGNode *after);
136 void reparentChildNodesTo(QSGNode *newParent);
137
138 int childCount() const;
139 QSGNode *childAtIndex(int i) const;
140 QSGNode *firstChild() const { return m_firstChild; }
141 QSGNode *lastChild() const { return m_lastChild; }
142 QSGNode *nextSibling() const { return m_nextSibling; }
143 QSGNode* previousSibling() const { return m_previousSibling; }
144
145 inline NodeType type() const { return m_type; }
146
147 QT_DEPRECATED void clearDirty() { }
148 void markDirty(DirtyState bits);
149 QT_DEPRECATED DirtyState dirtyState() const { return nullptr; }
150
151 virtual bool isSubtreeBlocked() const;
152
153 Flags flags() const { return m_nodeFlags; }
154 void setFlag(Flag, bool = true);
155 void setFlags(Flags, bool = true);
156
157 virtual void preprocess() { }
158
159protected:
160 QSGNode(NodeType type);
161 QSGNode(QSGNodePrivate &dd, NodeType type);
162
163private:
164 friend class QSGRootNode;
165 friend class QSGBatchRenderer::Renderer;
166 friend class QSGRenderer;
167
168 void init();
169 void destroy();
170
171 QSGNode *m_parent = nullptr;
172 NodeType m_type = BasicNodeType;
173 QSGNode *m_firstChild = nullptr;
174 QSGNode *m_lastChild = nullptr;
175 QSGNode *m_nextSibling = nullptr;
176 QSGNode *m_previousSibling = nullptr;
177 int m_subtreeRenderableCount = 0;
178
179 Flags m_nodeFlags;
180 DirtyState m_dirtyState; // Obsolete, remove in Qt 6
181
182protected:
183 friend class QSGNodePrivate;
184
185 QScopedPointer<QSGNodePrivate> d_ptr;
186};
187
188void Q_QUICK_EXPORT qsgnode_set_description(QSGNode *node, const QString &description);
189
190class Q_QUICK_EXPORT QSGBasicGeometryNode : public QSGNode
191{
192public:
193 ~QSGBasicGeometryNode() override;
194
195 void setGeometry(QSGGeometry *geometry);
196 const QSGGeometry *geometry() const { return m_geometry; }
197 QSGGeometry *geometry() { return m_geometry; }
198
199 const QMatrix4x4 *matrix() const { return m_matrix; }
200 const QSGClipNode *clipList() const { return m_clip_list; }
201
202 void setRendererMatrix(const QMatrix4x4 *m) { m_matrix = m; }
203 void setRendererClipList(const QSGClipNode *c) { m_clip_list = c; }
204
205protected:
206 QSGBasicGeometryNode(NodeType type);
207 QSGBasicGeometryNode(QSGBasicGeometryNodePrivate &dd, NodeType type);
208
209private:
210 friend class QSGNodeUpdater;
211
212 QSGGeometry *m_geometry;
213
214 int m_reserved_start_index;
215 int m_reserved_end_index;
216
217 const QMatrix4x4 *m_matrix;
218 const QSGClipNode *m_clip_list;
219};
220
221class QSGMaterial;
222
223class Q_QUICK_EXPORT QSGGeometryNode : public QSGBasicGeometryNode
224{
225public:
226 QSGGeometryNode();
227 ~QSGGeometryNode() override;
228
229 void setMaterial(QSGMaterial *material);
230 QSGMaterial *material() const { return m_material; }
231
232 void setOpaqueMaterial(QSGMaterial *material);
233 QSGMaterial *opaqueMaterial() const { return m_opaque_material; }
234
235 QSGMaterial *activeMaterial() const;
236
237 void setRenderOrder(int order);
238 int renderOrder() const { return m_render_order; }
239
240 void setInheritedOpacity(qreal opacity);
241 qreal inheritedOpacity() const { return m_opacity; }
242
243protected:
244 QSGGeometryNode(QSGGeometryNodePrivate &dd);
245
246private:
247 friend class QSGNodeUpdater;
248
249 int m_render_order = 0;
250 QSGMaterial *m_material = nullptr;
251 QSGMaterial *m_opaque_material = nullptr;
252
253 qreal m_opacity = 1;
254};
255
256class Q_QUICK_EXPORT QSGClipNode : public QSGBasicGeometryNode
257{
258public:
259 QSGClipNode();
260 ~QSGClipNode() override;
261
262 void setIsRectangular(bool rectHint);
263 bool isRectangular() const { return m_is_rectangular; }
264
265 void setClipRect(const QRectF &);
266 QRectF clipRect() const { return m_clip_rect; }
267
268private:
269 uint m_is_rectangular : 1;
270 uint m_reserved : 31;
271
272 QRectF m_clip_rect;
273};
274
275
276class Q_QUICK_EXPORT QSGTransformNode : public QSGNode
277{
278public:
279 QSGTransformNode();
280 ~QSGTransformNode() override;
281
282 void setMatrix(const QMatrix4x4 &matrix);
283 const QMatrix4x4 &matrix() const { return m_matrix; }
284
285 void setCombinedMatrix(const QMatrix4x4 &matrix);
286 const QMatrix4x4 &combinedMatrix() const { return m_combined_matrix; }
287
288private:
289 QMatrix4x4 m_matrix;
290 QMatrix4x4 m_combined_matrix;
291};
292
293
294class Q_QUICK_EXPORT QSGRootNode : public QSGNode
295{
296public:
297 QSGRootNode();
298 ~QSGRootNode() override;
299
300private:
301 void notifyNodeChange(QSGNode *node, DirtyState state);
302
303 friend class QSGAbstractRenderer;
304 friend class QSGNode;
305 friend class QSGGeometryNode;
306
307 QList<QSGAbstractRenderer *> m_renderers;
308};
309
310
311class Q_QUICK_EXPORT QSGOpacityNode : public QSGNode
312{
313public:
314 QSGOpacityNode();
315 ~QSGOpacityNode() override;
316
317 void setOpacity(qreal opacity);
318 qreal opacity() const { return m_opacity; }
319
320 void setCombinedOpacity(qreal opacity);
321 qreal combinedOpacity() const { return m_combined_opacity; }
322
323 bool isSubtreeBlocked() const override;
324
325private:
326 qreal m_opacity = 1;
327 qreal m_combined_opacity = 1;
328};
329
330class Q_QUICK_EXPORT QSGNodeVisitor {
331public:
332 virtual ~QSGNodeVisitor();
333
334protected:
335 virtual void enterTransformNode(QSGTransformNode *) {}
336 virtual void leaveTransformNode(QSGTransformNode *) {}
337 virtual void enterClipNode(QSGClipNode *) {}
338 virtual void leaveClipNode(QSGClipNode *) {}
339 virtual void enterGeometryNode(QSGGeometryNode *) {}
340 virtual void leaveGeometryNode(QSGGeometryNode *) {}
341 virtual void enterOpacityNode(QSGOpacityNode *) {}
342 virtual void leaveOpacityNode(QSGOpacityNode *) {}
343 virtual void visitNode(QSGNode *n);
344 virtual void visitChildren(QSGNode *n);
345};
346
347#ifndef QT_NO_DEBUG_STREAM
348Q_QUICK_EXPORT QDebug operator<<(QDebug, const QSGNode *n);
349Q_QUICK_EXPORT QDebug operator<<(QDebug, const QSGGeometryNode *n);
350Q_QUICK_EXPORT QDebug operator<<(QDebug, const QSGTransformNode *n);
351Q_QUICK_EXPORT QDebug operator<<(QDebug, const QSGOpacityNode *n);
352Q_QUICK_EXPORT QDebug operator<<(QDebug, const QSGRootNode *n);
353
354#endif
355
356Q_DECLARE_OPERATORS_FOR_FLAGS(QSGNode::DirtyState)
357Q_DECLARE_OPERATORS_FOR_FLAGS(QSGNode::Flags)
358
359QT_END_NAMESPACE
360
361#endif // QSGNODE_H
362