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 | |
4 | #ifndef QSGNODE_H |
5 | #define QSGNODE_H |
6 | |
7 | #include <QtCore/qlist.h> |
8 | #include <QtQuick/qsggeometry.h> |
9 | #include <QtGui/QMatrix4x4> |
10 | |
11 | #include <float.h> |
12 | |
13 | QT_BEGIN_NAMESPACE |
14 | |
15 | #ifndef QT_NO_DEBUG |
16 | #define QSG_RUNTIME_DESCRIPTION |
17 | #endif |
18 | |
19 | class QSGAbstractRenderer; |
20 | class QSGRenderer; |
21 | |
22 | class QSGNode; |
23 | class QSGRootNode; |
24 | class QSGGeometryNode; |
25 | class QSGTransformNode; |
26 | class QSGClipNode; |
27 | class QSGNodePrivate; |
28 | class QSGBasicGeometryNodePrivate; |
29 | class QSGGeometryNodePrivate; |
30 | |
31 | namespace QSGBatchRenderer { |
32 | class Renderer; |
33 | class Updater; |
34 | } |
35 | |
36 | class Q_QUICK_EXPORT QSGNode |
37 | { |
38 | public: |
39 | enum NodeType { |
40 | BasicNodeType, |
41 | GeometryNodeType, |
42 | TransformNodeType, |
43 | ClipNodeType, |
44 | OpacityNodeType, |
45 | RootNodeType, |
46 | RenderNodeType |
47 | }; |
48 | |
49 | enum Flag { |
50 | // Lower 16 bites reserved for general node |
51 | OwnedByParent = 0x0001, |
52 | UsePreprocess = 0x0002, |
53 | |
54 | // 0x00ff0000 bits reserved for node subclasses |
55 | |
56 | // QSGBasicGeometryNode |
57 | OwnsGeometry = 0x00010000, |
58 | OwnsMaterial = 0x00020000, |
59 | OwnsOpaqueMaterial = 0x00040000, |
60 | |
61 | // Uppermost 8 bits are reserved for internal use. |
62 | IsVisitableNode = 0x01000000 |
63 | #ifdef Q_QDOC |
64 | , InternalReserved = 0x01000000 |
65 | #endif |
66 | }; |
67 | Q_DECLARE_FLAGS(Flags, Flag) |
68 | |
69 | enum DirtyStateBit { |
70 | DirtySubtreeBlocked = 0x0080, |
71 | DirtyMatrix = 0x0100, |
72 | DirtyNodeAdded = 0x0400, |
73 | DirtyNodeRemoved = 0x0800, |
74 | DirtyGeometry = 0x1000, |
75 | DirtyMaterial = 0x2000, |
76 | DirtyOpacity = 0x4000, |
77 | |
78 | DirtyForceUpdate = 0x8000, |
79 | |
80 | DirtyUsePreprocess = UsePreprocess, |
81 | |
82 | DirtyPropagationMask = DirtyMatrix |
83 | | DirtyNodeAdded |
84 | | DirtyOpacity |
85 | | DirtyForceUpdate |
86 | |
87 | }; |
88 | Q_DECLARE_FLAGS(DirtyState, DirtyStateBit) |
89 | |
90 | QSGNode(); |
91 | virtual ~QSGNode(); |
92 | |
93 | QSGNode *parent() const { return m_parent; } |
94 | |
95 | void removeChildNode(QSGNode *node); |
96 | void removeAllChildNodes(); |
97 | void prependChildNode(QSGNode *node); |
98 | void appendChildNode(QSGNode *node); |
99 | void insertChildNodeBefore(QSGNode *node, QSGNode *before); |
100 | void insertChildNodeAfter(QSGNode *node, QSGNode *after); |
101 | void reparentChildNodesTo(QSGNode *newParent); |
102 | |
103 | int childCount() const; |
104 | QSGNode *childAtIndex(int i) const; |
105 | QSGNode *firstChild() const { return m_firstChild; } |
106 | QSGNode *lastChild() const { return m_lastChild; } |
107 | QSGNode *nextSibling() const { return m_nextSibling; } |
108 | QSGNode* previousSibling() const { return m_previousSibling; } |
109 | |
110 | inline NodeType type() const { return m_type; } |
111 | |
112 | QT_DEPRECATED void clearDirty() { } |
113 | void markDirty(DirtyState bits); |
114 | QT_DEPRECATED DirtyState dirtyState() const { return { }; } |
115 | |
116 | virtual bool isSubtreeBlocked() const; |
117 | |
118 | Flags flags() const { return m_nodeFlags; } |
119 | void setFlag(Flag, bool = true); |
120 | void setFlags(Flags, bool = true); |
121 | |
122 | virtual void preprocess() { } |
123 | |
124 | protected: |
125 | QSGNode(NodeType type); |
126 | QSGNode(QSGNodePrivate &dd, NodeType type); |
127 | |
128 | private: |
129 | friend class QSGRootNode; |
130 | friend class QSGBatchRenderer::Renderer; |
131 | friend class QSGRenderer; |
132 | |
133 | void init(); |
134 | void destroy(); |
135 | |
136 | QSGNode *m_parent = nullptr; |
137 | NodeType m_type = BasicNodeType; |
138 | QSGNode *m_firstChild = nullptr; |
139 | QSGNode *m_lastChild = nullptr; |
140 | QSGNode *m_nextSibling = nullptr; |
141 | QSGNode *m_previousSibling = nullptr; |
142 | int m_subtreeRenderableCount = 0; |
143 | |
144 | Flags m_nodeFlags; |
145 | |
146 | protected: |
147 | friend class QSGNodePrivate; |
148 | |
149 | QScopedPointer<QSGNodePrivate> d_ptr; |
150 | }; |
151 | |
152 | void Q_QUICK_EXPORT qsgnode_set_description(QSGNode *node, const QString &description); |
153 | |
154 | class Q_QUICK_EXPORT QSGBasicGeometryNode : public QSGNode |
155 | { |
156 | public: |
157 | ~QSGBasicGeometryNode() override; |
158 | |
159 | void setGeometry(QSGGeometry *geometry); |
160 | const QSGGeometry *geometry() const { return m_geometry; } |
161 | QSGGeometry *geometry() { return m_geometry; } |
162 | |
163 | const QMatrix4x4 *matrix() const { return m_matrix; } |
164 | const QSGClipNode *clipList() const { return m_clip_list; } |
165 | |
166 | void setRendererMatrix(const QMatrix4x4 *m) { m_matrix = m; } |
167 | void setRendererClipList(const QSGClipNode *c) { m_clip_list = c; } |
168 | |
169 | protected: |
170 | QSGBasicGeometryNode(NodeType type); |
171 | QSGBasicGeometryNode(QSGBasicGeometryNodePrivate &dd, NodeType type); |
172 | |
173 | private: |
174 | friend class QSGNodeUpdater; |
175 | |
176 | QSGGeometry *m_geometry; |
177 | |
178 | Q_DECL_UNUSED_MEMBER int m_reserved_start_index; |
179 | Q_DECL_UNUSED_MEMBER int m_reserved_end_index; |
180 | |
181 | const QMatrix4x4 *m_matrix; |
182 | const QSGClipNode *m_clip_list; |
183 | }; |
184 | |
185 | class QSGMaterial; |
186 | |
187 | class Q_QUICK_EXPORT QSGGeometryNode : public QSGBasicGeometryNode |
188 | { |
189 | public: |
190 | QSGGeometryNode(); |
191 | ~QSGGeometryNode() override; |
192 | |
193 | void setMaterial(QSGMaterial *material); |
194 | QSGMaterial *material() const { return m_material; } |
195 | |
196 | void setOpaqueMaterial(QSGMaterial *material); |
197 | QSGMaterial *opaqueMaterial() const { return m_opaque_material; } |
198 | |
199 | QSGMaterial *activeMaterial() const; |
200 | |
201 | void setRenderOrder(int order); |
202 | int renderOrder() const { return m_render_order; } |
203 | |
204 | void setInheritedOpacity(qreal opacity); |
205 | qreal inheritedOpacity() const { return m_opacity; } |
206 | |
207 | protected: |
208 | QSGGeometryNode(QSGGeometryNodePrivate &dd); |
209 | |
210 | private: |
211 | friend class QSGNodeUpdater; |
212 | |
213 | int m_render_order = 0; |
214 | QSGMaterial *m_material = nullptr; |
215 | QSGMaterial *m_opaque_material = nullptr; |
216 | |
217 | qreal m_opacity = 1; |
218 | }; |
219 | |
220 | class Q_QUICK_EXPORT QSGClipNode : public QSGBasicGeometryNode |
221 | { |
222 | public: |
223 | QSGClipNode(); |
224 | ~QSGClipNode() override; |
225 | |
226 | void setIsRectangular(bool rectHint); |
227 | bool isRectangular() const { return m_is_rectangular; } |
228 | |
229 | void setClipRect(const QRectF &); |
230 | QRectF clipRect() const { return m_clip_rect; } |
231 | |
232 | private: |
233 | uint m_is_rectangular : 1; |
234 | uint m_reserved : 31; |
235 | |
236 | QRectF m_clip_rect; |
237 | }; |
238 | |
239 | |
240 | class Q_QUICK_EXPORT QSGTransformNode : public QSGNode |
241 | { |
242 | public: |
243 | QSGTransformNode(); |
244 | ~QSGTransformNode() override; |
245 | |
246 | void setMatrix(const QMatrix4x4 &matrix); |
247 | const QMatrix4x4 &matrix() const { return m_matrix; } |
248 | |
249 | void setCombinedMatrix(const QMatrix4x4 &matrix); |
250 | const QMatrix4x4 &combinedMatrix() const { return m_combined_matrix; } |
251 | |
252 | private: |
253 | QMatrix4x4 m_matrix; |
254 | QMatrix4x4 m_combined_matrix; |
255 | }; |
256 | |
257 | |
258 | class Q_QUICK_EXPORT QSGRootNode : public QSGNode |
259 | { |
260 | public: |
261 | QSGRootNode(); |
262 | ~QSGRootNode() override; |
263 | |
264 | private: |
265 | void notifyNodeChange(QSGNode *node, DirtyState state); |
266 | |
267 | friend class QSGAbstractRenderer; |
268 | friend class QSGNode; |
269 | friend class QSGGeometryNode; |
270 | |
271 | QList<QSGAbstractRenderer *> m_renderers; |
272 | }; |
273 | |
274 | |
275 | class Q_QUICK_EXPORT QSGOpacityNode : public QSGNode |
276 | { |
277 | public: |
278 | QSGOpacityNode(); |
279 | ~QSGOpacityNode() override; |
280 | |
281 | void setOpacity(qreal opacity); |
282 | qreal opacity() const { return m_opacity; } |
283 | |
284 | void setCombinedOpacity(qreal opacity); |
285 | qreal combinedOpacity() const { return m_combined_opacity; } |
286 | |
287 | bool isSubtreeBlocked() const override; |
288 | |
289 | private: |
290 | qreal m_opacity = 1; |
291 | qreal m_combined_opacity = 1; |
292 | }; |
293 | |
294 | class Q_QUICK_EXPORT QSGNodeVisitor { |
295 | public: |
296 | virtual ~QSGNodeVisitor(); |
297 | |
298 | protected: |
299 | virtual void enterTransformNode(QSGTransformNode *) {} |
300 | virtual void leaveTransformNode(QSGTransformNode *) {} |
301 | virtual void enterClipNode(QSGClipNode *) {} |
302 | virtual void leaveClipNode(QSGClipNode *) {} |
303 | virtual void enterGeometryNode(QSGGeometryNode *) {} |
304 | virtual void leaveGeometryNode(QSGGeometryNode *) {} |
305 | virtual void enterOpacityNode(QSGOpacityNode *) {} |
306 | virtual void leaveOpacityNode(QSGOpacityNode *) {} |
307 | virtual void visitNode(QSGNode *n); |
308 | virtual void visitChildren(QSGNode *n); |
309 | }; |
310 | |
311 | #ifndef QT_NO_DEBUG_STREAM |
312 | Q_QUICK_EXPORT QDebug operator<<(QDebug, const QSGNode *n); |
313 | Q_QUICK_EXPORT QDebug operator<<(QDebug, const QSGGeometryNode *n); |
314 | Q_QUICK_EXPORT QDebug operator<<(QDebug, const QSGTransformNode *n); |
315 | Q_QUICK_EXPORT QDebug operator<<(QDebug, const QSGOpacityNode *n); |
316 | Q_QUICK_EXPORT QDebug operator<<(QDebug, const QSGRootNode *n); |
317 | |
318 | #endif |
319 | |
320 | Q_DECLARE_OPERATORS_FOR_FLAGS(QSGNode::DirtyState) |
321 | Q_DECLARE_OPERATORS_FOR_FLAGS(QSGNode::Flags) |
322 | |
323 | QT_END_NAMESPACE |
324 | |
325 | #endif // QSGNODE_H |
326 | |