1// Copyright (C) 2008-2012 NVIDIA Corporation.
2// Copyright (C) 2019 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
4
5#ifndef QSSG_RENDERER_P_H
6#define QSSG_RENDERER_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <private/qssgrenderpickresult_p.h>
20#include <private/qssgrhicontext_p.h>
21#include <private/qssgrhiquadrenderer_p.h>
22
23#include <QtCore/qpointer.h>
24
25QT_BEGIN_NAMESPACE
26
27class QSSGShaderCache;
28class QSSGProgramGenerator;
29class QSSGShaderLibraryManager;
30class QSSGBufferManager;
31class QSSGLayerRenderData;
32class QSSGRenderContextInterface;
33struct QSSGRenderNode;
34struct QSSGRenderItem2D;
35struct QSSGRenderRay;
36class QSSGSubsetRenderable;
37struct QSSGShaderDefaultMaterialKeyProperties;
38struct QSSGShaderFeatures;
39class QSGRenderContext;
40class QSGRenderer;
41
42class Q_QUICK3DRUNTIMERENDER_EXPORT QSSGRenderer
43{
44 Q_DISABLE_COPY(QSSGRenderer)
45public:
46 QSSGRenderer();
47 ~QSSGRenderer();
48
49 // Returns true if this layer or a sibling was dirty.
50 bool prepareLayerForRender(QSSGRenderLayer &inLayer);
51
52 void rhiPrepare(QSSGRenderLayer &inLayer);
53 void rhiRender(QSSGRenderLayer &inLayer);
54
55 // Clients need to call this every frame in order for various subsystems to release
56 // temporary per-frame allocated objects.
57 void beginFrame(QSSGRenderLayer &layer, bool allowRecursion = true);
58
59 // When allowRecursion is true, the cleanup is only done when all
60 // beginFrames got their corresponding endFrame. This is indicated by the
61 // return value (false if nothing's been done due to pending "frames")
62 bool endFrame(QSSGRenderLayer &layer, bool allowRecursion = true);
63
64 // Get the number of times EndFrame has been called
65 [[nodiscard]] constexpr quint32 frameCount() const { return m_frameCount; }
66
67 void setViewport(QRect inViewport) { m_viewport = inViewport; }
68 QRect viewport() const { return m_viewport; }
69
70 void setDpr(float dpr) { m_dpr = dpr; }
71 float dpr() const { return m_dpr; }
72
73 void setScissorRect(QRect inScissorRect) { m_scissorRect = inScissorRect; }
74 QRect scissorRect() const { return m_scissorRect; }
75
76 quint32 frameDepth() const { return m_activeFrameRef; }
77
78 const std::unique_ptr<QSSGRhiQuadRenderer> &rhiQuadRenderer() const;
79 const std::unique_ptr<QSSGRhiCubeRenderer> &rhiCubeRenderer() const;
80
81 QSSGRenderContextInterface *contextInterface() const { return m_contextInterface; }
82
83 // Before we start rendering a sublayer(s), e.g., Item2D with View3Ds,
84 // we need to inform the renderer about it, so we can restore the state as we
85 // return from the sublayer(s) rendering. The state will be saved in the data set
86 // for the layer.
87 void beginSubLayerRender(QSSGLayerRenderData &inLayer);
88 void endSubLayerRender(QSSGLayerRenderData &inLayer);
89
90 using ModelViewProjections = std::array<QMatrix4x4, 2>;
91
92 struct Item2DData
93 {
94 const QSSGRenderLayer *layer = nullptr;
95 const QSSGRenderItem2D *item = nullptr;
96 QPointer<QSGRenderer> renderer;
97 QRhiRenderPassDescriptor *rpd = nullptr;
98 ModelViewProjections mvps;
99 bool isValid() const { return layer && item && renderer && rpd; }
100 };
101
102 using Item2DDataList = std::vector<Item2DData>;
103 using Item2DDataMap = std::unordered_map<const QSSGRenderItem2D *, Item2DData>;
104
105 void registerItem2DData(const Item2DData &data);
106 void populateItem2DDataMapForLayer(const QSSGRenderLayer &layer, Item2DDataMap &item2DDataMap) const;
107 void releaseItem2DData(const QSSGRenderItem2D &item2D);
108 void releaseItem2DData(const QSSGRenderLayer &layer);
109
110protected:
111 void cleanupResources(QList<QSSGRenderGraphObject*> &resources);
112 void cleanupResources(QSet<QSSGRenderGraphObject*> &resources);
113
114private:
115 friend class QSSGRendererPrivate;
116 friend class QSSGLayerRenderData;
117 friend class QSSGRenderContextInterface;
118 friend class QQuick3DSceneRenderer;
119 friend class QQuick3DWindowAttachment;
120 friend class QSSGCleanupObject;
121
122 QSSGLayerRenderData *getOrCreateLayerRenderData(QSSGRenderLayer &layer);
123 void beginLayerRender(QSSGLayerRenderData &inLayer);
124 void endLayerRender();
125 void addMaterialDirtyClear(QSSGRenderGraphObject *material);
126 void cleanupUnreferencedBuffers(QSSGRenderLayer *inLayer);
127 void resetResourceCounters(QSSGRenderLayer *inLayer);
128 void releaseCachedResources();
129
130 QSSGRenderContextInterface *m_contextInterface = nullptr; // We're own by the context interface
131
132 bool m_globalPickingEnabled = false;
133
134 // Temporary information stored only when rendering a particular layer.
135 QSSGLayerRenderData *m_currentLayer = nullptr;
136
137 QSet<QSSGRenderGraphObject *> m_materialClearDirty;
138
139 QPointer<QSGRenderContext> m_qsgRenderContext;
140
141 // Item2D data (per layer)
142 Item2DDataList item2DDataList;
143
144 mutable std::unique_ptr<QSSGRhiQuadRenderer> m_rhiQuadRenderer;
145 mutable std::unique_ptr<QSSGRhiCubeRenderer> m_rhiCubeRenderer;
146
147 quint32 m_activeFrameRef = 0;
148 quint32 m_frameCount = 0;
149
150 // Viewport that this render context should use
151 QRect m_viewport;
152 float m_dpr = 1.0;
153 QRect m_scissorRect;
154};
155
156class Q_QUICK3DRUNTIMERENDER_EXPORT QSSGRendererPrivate
157{
158 QSSGRendererPrivate() = default;
159public:
160 using PickResultList = QVarLengthArray<QSSGRenderPickResult, 20>; // Lets assume most items are filtered out already
161
162 static QSSGRhiShaderPipelinePtr generateRhiShaderPipelineImpl(QSSGSubsetRenderable &renderable,
163 QSSGShaderLibraryManager &shaderLibraryManager,
164 QSSGShaderCache &shaderCache,
165 QSSGProgramGenerator &shaderProgramGenerator,
166 const QSSGShaderDefaultMaterialKeyProperties &shaderKeyProperties,
167 const QSSGShaderFeatures &featureSet,
168 QByteArray &shaderString);
169 static QSSGRhiShaderPipelinePtr generateRhiShaderPipeline(QSSGRenderer &renderer,
170 QSSGSubsetRenderable &inRenderable,
171 const QSSGShaderFeatures &inFeatureSet);
172
173 static QSSGRhiShaderPipelinePtr getShaderPipelineForDefaultMaterial(QSSGRenderer &renderer,
174 QSSGSubsetRenderable &inRenderable,
175 const QSSGShaderFeatures &inFeatureSet);
176
177 static void getLayerHitObjectList(const QSSGRenderLayer &layer,
178 QSSGBufferManager &bufferManager,
179 const QSSGRenderRay &ray,
180 bool inPickEverything,
181 PickResultList &outIntersectionResult);
182 static void intersectRayWithSubsetRenderable(const QSSGRenderLayer &layer, QSSGBufferManager &bufferManager,
183 const QSSGRenderRay &inRay,
184 const QSSGRenderNode &node,
185 PickResultList &outIntersectionResultList);
186 static void intersectRayWithItem2D(const QSSGRenderLayer &layer, const QSSGRenderRay &inRay,
187 const QSSGRenderItem2D &item2D,
188 PickResultList &outIntersectionResultList);
189
190 static PickResultList syncPickAll(const QSSGRenderContextInterface &ctx,
191 const QSSGRenderLayer &layer,
192 const QSSGRenderRay &ray);
193
194 static PickResultList syncPick(const QSSGRenderContextInterface &ctx,
195 const QSSGRenderLayer &layer,
196 const QSSGRenderRay &ray,
197 QSSGRenderNode *target = nullptr);
198
199 static PickResultList syncPickSubset(const QSSGRenderLayer &layer,
200 QSSGBufferManager &bufferManager,
201 const QSSGRenderRay &ray,
202 QVarLengthArray<QSSGRenderNode *> subset);
203
204 // Setting this true enables picking for all the models, regardless of
205 // the models pickable property.
206 static bool isGlobalPickingEnabled(const QSSGRenderer &renderer) { return renderer.m_globalPickingEnabled; }
207 static void setGlobalPickingEnabled(QSSGRenderer &renderer, bool isEnabled);
208
209 static void setRenderContextInterface(QSSGRenderer &renderer, QSSGRenderContextInterface *ctx);
210 static void setSgRenderContext(QSSGRenderer &renderer, QSGRenderContext *sgRenderCtx);
211
212 static QSSGLayerRenderData *getCurrentRenderData(const QSSGRenderer &renderer) { return renderer.m_currentLayer; }
213
214 static QSGRenderContext *getSgRenderContext(const QSSGRenderer &renderer);
215
216 static constexpr float minimumRenderOpacity = .01f;
217};
218
219QT_END_NAMESPACE
220
221#endif // QSSG_RENDERER_P_H
222

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