1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#ifndef QSSGSCENERENDERER_H
5#define QSSGSCENERENDERER_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 <ssg/qssgrendercontextcore.h>
19
20#include <qsgtextureprovider.h>
21#include <qsgrendernode.h>
22#include <QSGSimpleTextureNode>
23
24#include <QtQuick3D/private/qquick3dviewport_p.h>
25#include <QtQuick3DRuntimeRender/private/qssgrenderlayer_p.h>
26#include <QtQuick3DRuntimeRender/private/qssgrhieffectsystem_p.h>
27#include <QtQuick3DRuntimeRender/private/qssgrenderer_p.h>
28
29#include <QtCore/qpointer.h>
30
31#include <optional>
32
33#include "qquick3dsceneenvironment_p.h"
34
35QT_BEGIN_NAMESPACE
36
37
38class QQuick3DSceneManager;
39class QQuick3DViewport;
40
41class QQuick3DSceneRenderer
42{
43 using PickResultList = QVarLengthArray<QSSGRenderPickResult, 20>;
44public:
45 explicit QQuick3DSceneRenderer(const std::shared_ptr<QSSGRenderContextInterface> &rci);
46 ~QQuick3DSceneRenderer();
47
48 static QSSGRenderLayer::TonemapMode getTonemapMode(const QQuick3DSceneEnvironment &environment)
49 {
50 if (environment.useBuiltinTonemapper())
51 return QSSGRenderLayer::TonemapMode(environment.tonemapMode());
52
53 // Special case for the extend scene environment...
54 return (environment.tonemapMode() != QQuick3DSceneEnvironment::QQuick3DEnvironmentTonemapModes::TonemapModeNone) ? QSSGRenderLayer::TonemapMode::Custom
55 : QSSGRenderLayer::TonemapMode::None;
56 }
57
58protected:
59 QRhiTexture *renderToRhiTexture(QQuickWindow *qw);
60 void beginFrame();
61 void endFrame();
62 void rhiPrepare(const QRect &viewport, qreal displayPixelRatio);
63 void rhiRender();
64 void synchronize(QQuick3DViewport *view3D, const QSize &size, float dpr);
65 void invalidateFramebufferObject();
66 QSize surfaceSize() const { return m_surfaceSize; }
67 void releaseCachedResources();
68
69 std::optional<QSSGRenderRay> getRayFromViewportPos(const QPointF &pos);
70 PickResultList syncPick(const QSSGRenderRay &ray);
71 PickResultList syncPickOne(const QSSGRenderRay &ray, QSSGRenderNode *node);
72 PickResultList syncPickSubset(const QSSGRenderRay &ray, QVarLengthArray<QSSGRenderNode *> subset);
73 PickResultList syncPickAll(const QSSGRenderRay &ray);
74
75 void setGlobalPickingEnabled(bool isEnabled);
76
77 QQuick3DRenderStats *renderStats();
78
79private:
80 void releaseAaDependentRhiResources();
81 void updateLayerNode(QSSGRenderLayer &layerNode,
82 const QQuick3DViewport &view3D,
83 const QList<QSSGRenderGraphObject *> &resourceLoaders);
84 void addNodeToLayer(QSSGRenderNode *node);
85 void removeNodeFromLayer(QSSGRenderNode *node);
86 void maybeSetupLightmapBaking(QQuick3DViewport *view3D);
87 std::shared_ptr<QSSGRenderContextInterface> m_sgContext;
88 QSSGRenderLayer *m_layer = nullptr;
89 QPointer<QQuick3DWindowAttachment> winAttacment;
90 QSize m_surfaceSize;
91 SGFramebufferObjectNode *fboNode = nullptr;
92 bool m_aaIsDirty = true;
93 bool m_temporalIsDirty = false;
94 bool m_timeBasedAA = false;
95
96 // RHI
97 QRhiTexture *m_texture = nullptr;
98 // the rt is set up to output into m_texture or m_ssaaTexture or m_msaaRenderBuffer(+resolve into m_texture)
99 QRhiTextureRenderTarget *m_textureRenderTarget = nullptr;
100 QRhiRenderPassDescriptor *m_textureRenderPassDescriptor = nullptr;
101 // used by the draw quad that does m_ssaaTexture -> m_texture
102 QRhiTextureRenderTarget *m_ssaaTextureToTextureRenderTarget = nullptr;
103 QRhiRenderPassDescriptor *m_ssaaTextureToTextureRenderPassDescriptor = nullptr;
104 QRhiRenderBuffer *m_msaaRenderBufferLegacy = nullptr;
105 QRhiTexture *m_msaaRenderTexture = nullptr;
106 QRhiTexture *m_msaaMultiViewRenderBuffer = nullptr;
107 QRhiTexture *m_ssaaTexture = nullptr;
108 QRhiTexture *m_temporalAATexture = nullptr;
109 QRhiTexture *m_prevTempAATexture = nullptr;
110 QRhiTextureRenderTarget *m_temporalAARenderTarget = nullptr;
111 QRhiRenderPassDescriptor *m_temporalAARenderPassDescriptor = nullptr;
112 QRhiRenderBuffer *m_depthStencilBuffer = nullptr;
113 QRhiTexture *m_multiViewDepthStencilBuffer = nullptr;
114 bool m_textureNeedsFlip = true;
115 QSSGRenderLayer::Background m_backgroundMode = QSSGRenderLayer::Background::Unspecified;
116 QColor m_userBackgroundColor = Qt::black;
117 QColor m_linearBackgroundColor = Qt::black;
118 QColor m_tonemappedBackgroundColor = Qt::black;
119 int m_samples = 1;
120 QSSGRhiEffectSystem *m_effectSystem = nullptr;
121
122 QPointer<QQuick3DRenderStats> m_renderStats;
123
124 QSSGRenderNode *m_sceneRootNode = nullptr;
125 QSSGRenderNode *m_importSceneRootNode = nullptr;
126
127 bool m_prepared = false;
128
129 QSSGLightmapperOptions lmOptions;
130 bool m_lightmapBakingFromCmdRequested = false;
131 bool m_lightmapDenoisingFromCmdRequested = false;
132
133 int m_requestedFramesCount = 0;
134 bool m_postProcessingStack = false;
135 bool m_useFBO = false;
136 Q_QUICK3D_PROFILE_ID
137
138 friend class SGFramebufferObjectNode;
139 friend class QQuick3DSGRenderNode;
140 friend class QQuick3DSGDirectRenderer;
141 friend class QQuick3DViewport;
142 friend struct ViewportTransformHelper;
143 friend class QQuick3DRenderLayerHelpers;
144};
145
146class Q_QUICK3D_EXPORT QQuick3DRenderLayerHelpers
147{
148public:
149 static void updateLayerNodeHelper(const QQuick3DViewport &view3D,
150 const std::shared_ptr<QSSGRenderContextInterface> &rci,
151 QSSGRenderLayer &layerNode,
152 bool &aaIsDirty,
153 bool &temporalIsDirty);
154};
155
156class SGFramebufferObjectNode final : public QSGTextureProvider, public QSGSimpleTextureNode
157{
158 Q_OBJECT
159
160public:
161 SGFramebufferObjectNode();
162 ~SGFramebufferObjectNode() override;
163
164 void scheduleRender();
165
166 QSGTexture *texture() const override;
167
168 void preprocess() override;
169
170public Q_SLOTS:
171 void render();
172
173 void handleScreenChange();
174
175public:
176 QQuickWindow *window;
177 QQuick3DSceneRenderer *renderer;
178 QQuick3DViewport *quickFbo;
179
180 bool renderPending;
181 bool invalidatePending;
182
183 qreal devicePixelRatio;
184};
185
186class QQuick3DSGRenderNode final : public QSGRenderNode
187{
188public:
189 ~QQuick3DSGRenderNode();
190 void prepare() override;
191 StateFlags changedStates() const override;
192 void render(const RenderState *state) override;
193 void releaseResources() override;
194 RenderingFlags flags() const override;
195public:
196 QQuickWindow *window = nullptr;
197 QQuick3DSceneRenderer *renderer = nullptr;
198};
199
200class QQuick3DSGDirectRenderer : public QObject
201{
202 Q_OBJECT
203public:
204 enum QQuick3DSGDirectRendererMode {
205 Underlay,
206 Overlay
207 };
208 QQuick3DSGDirectRenderer(QQuick3DSceneRenderer *renderer, QQuickWindow *window, QQuick3DSGDirectRendererMode mode = Underlay);
209 ~QQuick3DSGDirectRenderer();
210
211 QQuick3DSceneRenderer *renderer() { return m_renderer; }
212 void setViewport(const QRectF &viewport);
213
214 void requestRender();
215 void setVisibility(bool visible);
216
217 void preSynchronize();
218
219private Q_SLOTS:
220 void prepare();
221 void render();
222
223private:
224 QQuick3DSceneRenderer *m_renderer = nullptr;
225 QQuickWindow *m_window = nullptr;
226 QRectF m_viewport;
227 bool m_isVisible = true;
228 QRhiTexture *m_rhiTexture = nullptr;
229 bool renderPending = false;
230};
231
232QT_END_NAMESPACE
233
234#endif // QSSGSCENERENDERER_H
235

source code of qtquick3d/src/quick3d/qquick3dscenerenderer_p.h