1// Copyright (C) 2025 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#ifndef QSSGRENDERDATA_P_H
5#define QSSGRENDERDATA_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtGui/qmatrix4x4.h>
19
20#include "qssgrenderableobjects_p.h"
21
22#include <vector>
23#include <memory>
24
25QT_BEGIN_NAMESPACE
26
27struct QSSGRenderNode;
28class QSSGRenderRoot;
29
30class QThreadPool;
31
32// Per window node data
33class QSSGGlobalRenderNodeData
34{
35 Q_DISABLE_COPY_MOVE(QSSGGlobalRenderNodeData)
36public:
37 struct InstanceTransforms
38 {
39 QMatrix4x4 local;
40 QMatrix4x4 global;
41 };
42
43 struct LayerNodeSection
44 {
45 size_t offset = 0;
46 size_t size = 0;
47 };
48
49 using LayerNodeView = QSSGDataView<QSSGRenderNode *>;
50
51 using GlobalTransformStore = std::vector<QMatrix4x4>;
52 using GlobalOpacityStore = std::vector<float>;
53 using InstanceTransformStore = std::vector<InstanceTransforms>;
54 using NodeStore = std::vector<QSSGRenderNode *>;
55 using LayerNodeViewStore = std::vector<LayerNodeSection>;
56
57 QSSGGlobalRenderNodeData();
58 ~QSSGGlobalRenderNodeData();
59
60 void reindex(QSSGRenderRoot *rootNode);
61
62 [[nodiscard]] quint32 version() const { return m_version; }
63
64 // NOTE: The node count is the number of nodes in the "world" tree.
65 // This is not the the same as the storage size. as some nodes
66 // may not be stored in the data or use the same storage location!
67 [[nodiscard]] size_t nodeCount() const { return m_nodeCount; }
68 [[nodiscard]] size_t storageSize() const { return m_size; }
69
70 [[nodiscard]] QMatrix4x4 getGlobalTransform(QSSGRenderNodeHandle h, QMatrix4x4 defaultValue) const;
71 [[nodiscard]] QMatrix4x4 getGlobalTransform(QSSGRenderNodeHandle h) const;
72 [[nodiscard]] QMatrix4x4 getGlobalTransform(const QSSGRenderNode &node) const;
73 [[nodiscard]] float getGlobalOpacity(QSSGRenderNodeHandle h, float defaultValue = 1.0f) const;
74 [[nodiscard]] float getGlobalOpacity(const QSSGRenderNode &node) const;
75 [[nodiscard]] InstanceTransforms getInstanceTransforms(QSSGRenderNodeHandle h) const;
76 [[nodiscard]] InstanceTransforms getInstanceTransforms(const QSSGRenderNode &node) const;
77
78 [[nodiscard]] LayerNodeView getLayerNodeView(QSSGRenderLayerHandle h) const;
79 [[nodiscard]] LayerNodeView getLayerNodeView(const QSSGRenderLayer &layer) const;
80
81 GlobalTransformStore globalTransforms { };
82 GlobalOpacityStore globalOpacities { };
83 InstanceTransformStore instanceTransforms { };
84 NodeStore nodes { };
85 LayerNodeViewStore layerNodes { };
86
87#if QT_CONFIG(thread)
88 // NOTE: Thread pool for parallel processing of render data.
89 // This thread pool is not intended for async calls.
90 // For long running tasks use the global thread pool instead.
91 // (Threads executed here are expected to be done before the sync has ended).
92 const std::unique_ptr<QThreadPool> &threadPool() const;
93#endif // QT_CONFIG(thread)
94
95private:
96 void collectNodes(QSSGRenderRoot *rootNode);
97 void updateGlobalState();
98
99#if QT_CONFIG(thread)
100 std::unique_ptr<QThreadPool> m_threadPool;
101#endif // QT_CONFIG(thread)
102
103 size_t m_size = 0;
104 size_t m_nodeCount = 0;
105 quint32 m_version = 0;
106};
107
108using QSSGGlobalRenderNodeDataPtr = std::shared_ptr<QSSGGlobalRenderNodeData>;
109
110class QSSGRenderDataHelpers
111{
112 QSSGRenderDataHelpers() = delete;
113public:
114 enum class Strategy
115 {
116 Initial, // Initial calculation of ALL global variables
117 Update, // Update calculation of ONLY changed global variables
118 };
119
120 enum GlobalStateResult : quint8
121 {
122 None,
123 ActiveChanged = 0x1,
124 PickableChanged = 0x2,
125 };
126
127 using GlobalStateResultT = std::underlying_type_t<GlobalStateResult>;
128
129 /*!
130 \brief calcGlobalNodeData
131 \param node The node to calculate the global data for.
132 \param version The version of the node current node tree.
133 \param globalTransforms The global transforms store.
134 \param globalOpacities The global opacities store.
135 \return true if the data was updated, false otherwise.
136
137 The function is used to calculate the global node data for the given node.
138 It will use the given strategy to determine if it should calculate
139 the initial values or update the existing values based on the node's dirty state.
140
141 NOTE: This function assumes the output data is already allocated and can be directly
142 indexed!!!
143 */
144 template <Strategy strategy>
145 static bool calcGlobalNodeData(QSSGRenderNode *node,
146 const quint32 version,
147 QSSGGlobalRenderNodeData::GlobalTransformStore &globalTransforms,
148 QSSGGlobalRenderNodeData::GlobalOpacityStore &globalOpacities)
149 {
150 if constexpr (strategy == Strategy::Initial)
151 return calcGlobalVariablesIndexed(node, version, globalTransforms, globalOpacities);
152 else
153 return updateGlobalNodeDataIndexed(node, version, globalTransforms, globalOpacities);
154 }
155
156 /*!
157 \brief calcInstanceTransforms
158 \param node The node to calculate the instance transforms for.
159 \param version The version of the node current node tree.
160 \param globalTransforms The global transforms store.
161 \param instanceTransforms The instance transforms store.
162 \return true if the data was updated, false otherwise.
163
164 The function is used to calculate the instance transforms for the given node.
165
166 NOTE: This function assumes the output data is already allocated and can be directly
167 indexed!!!
168 */
169 static bool calcInstanceTransforms(QSSGRenderNode *node,
170 const quint32 version,
171 QSSGGlobalRenderNodeData::GlobalTransformStore &globalTransforms,
172 QSSGGlobalRenderNodeData::InstanceTransformStore &instanceTransforms);
173
174
175 /*!
176 \brief updateGlobalNodeState
177 \param node The node to update the global state for.
178 \param version The version of the node current node tree.
179 \return The result of the update.
180
181 The function is used to update the global state flagsfor the given node,
182 meaning the global active and pickable state of the node.
183 */
184 static GlobalStateResult updateGlobalNodeState(QSSGRenderNode *node, const quint32 version);
185private:
186 static bool updateGlobalNodeDataIndexed(QSSGRenderNode *node,
187 const quint32 version,
188 QSSGGlobalRenderNodeData::GlobalTransformStore &globalTransforms,
189 QSSGGlobalRenderNodeData::GlobalOpacityStore &globalOpacities);
190 static bool calcGlobalVariablesIndexed(QSSGRenderNode *node,
191 const quint32 version,
192 QSSGGlobalRenderNodeData::GlobalTransformStore &globalTransforms,
193 QSSGGlobalRenderNodeData::GlobalOpacityStore &globalOpacities);
194};
195
196// Per layer model data
197class QSSGRenderModelData
198{
199 Q_DISABLE_COPY_MOVE(QSSGRenderModelData)
200public:
201 explicit QSSGRenderModelData(const QSSGGlobalRenderNodeDataPtr &globalNodeData);
202
203 using ModelViewProjections = std::array<QMatrix4x4, 2>;
204 using MaterialList = QVector<QSSGRenderGraphObject *>;
205
206 using ModelViewProjectionStore = std::vector<ModelViewProjections>;
207 using NormalMatrixStore = std::vector<QMatrix3x3>;
208 using MeshStore = std::vector<QSSGRenderMesh *>;
209 using MaterialStore = std::vector<MaterialList>;
210
211 [[nodiscard]] ModelViewProjections getModelViewProjection(QSSGRenderModelHandle h) const;
212 [[nodiscard]] ModelViewProjections getModelViewProjection(const QSSGRenderModel &model) const;
213
214 [[nodiscard]] QMatrix3x3 getNormalMatrix(QSSGRenderModelHandle h, QMatrix3x3 defaultValue) const;
215 [[nodiscard]] QMatrix3x3 getNormalMatrix(const QSSGRenderModel &model) const;
216
217 [[nodiscard]] QSSGRenderMesh *getMesh(QSSGRenderModelHandle h) const;
218 [[nodiscard]] QSSGRenderMesh *getMesh(const QSSGRenderModel &model) const;
219
220 [[nodiscard]] MaterialList getMaterials(QSSGRenderModelHandle h) const;
221 [[nodiscard]] MaterialList getMaterials(const QSSGRenderModel &model) const;
222
223 [[nodiscard]] const QSSGGlobalRenderNodeDataPtr &globalNodeData() const { return m_gnd; }
224
225 void updateModelData(QSSGModelsView &models, QSSGRenderer *renderer, const QSSGRenderCameraDataList &renderCameraData);
226
227private:
228 ModelViewProjectionStore modelViewProjections;
229 NormalMatrixStore normalMatrices;
230 MeshStore meshes;
231 MaterialStore materials;
232
233 void prepareMeshData(const QSSGModelsView &models, QSSGRenderer *renderer);
234 void prepareMaterials(const QSSGModelsView &models);
235
236 QSSGGlobalRenderNodeDataPtr m_gnd;
237
238 quint32 m_version = 0;
239};
240
241QT_END_NAMESPACE
242
243#endif // QSSGRENDERDATA_P_H
244

source code of qtquick3d/src/runtimerender/rendererimpl/qssgrenderdata_p.h