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 | |
35 | QT_BEGIN_NAMESPACE |
36 | |
37 | |
38 | class QQuick3DSceneManager; |
39 | class QQuick3DViewport; |
40 | |
41 | class QQuick3DSceneRenderer |
42 | { |
43 | using PickResultList = QVarLengthArray<QSSGRenderPickResult, 20>; |
44 | public: |
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 | |
58 | protected: |
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 | |
79 | private: |
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 | std::shared_ptr<QSSGRenderContextInterface> m_sgContext; |
87 | QSSGRenderLayer *m_layer = nullptr; |
88 | QPointer<QQuick3DWindowAttachment> winAttacment; |
89 | QSize m_surfaceSize; |
90 | SGFramebufferObjectNode *fboNode = nullptr; |
91 | bool m_aaIsDirty = true; |
92 | bool m_temporalIsDirty = false; |
93 | bool m_timeBasedAA = false; |
94 | |
95 | // RHI |
96 | QRhiTexture *m_texture = nullptr; |
97 | // the rt is set up to output into m_texture or m_ssaaTexture or m_msaaRenderBuffer(+resolve into m_texture) |
98 | QRhiTextureRenderTarget *m_textureRenderTarget = nullptr; |
99 | QRhiRenderPassDescriptor *m_textureRenderPassDescriptor = nullptr; |
100 | // used by the draw quad that does m_ssaaTexture -> m_texture |
101 | QRhiTextureRenderTarget *m_ssaaTextureToTextureRenderTarget = nullptr; |
102 | QRhiRenderPassDescriptor *m_ssaaTextureToTextureRenderPassDescriptor = nullptr; |
103 | QRhiRenderBuffer *m_msaaRenderBuffer = nullptr; |
104 | QRhiTexture *m_msaaMultiViewRenderBuffer = nullptr; |
105 | QRhiTexture *m_ssaaTexture = nullptr; |
106 | QRhiTexture *m_temporalAATexture = nullptr; |
107 | QRhiTexture *m_prevTempAATexture = nullptr; |
108 | QRhiTextureRenderTarget *m_temporalAARenderTarget = nullptr; |
109 | QRhiRenderPassDescriptor *m_temporalAARenderPassDescriptor = nullptr; |
110 | QRhiRenderBuffer *m_depthStencilBuffer = nullptr; |
111 | QRhiTexture *m_multiViewDepthStencilBuffer = nullptr; |
112 | bool m_textureNeedsFlip = true; |
113 | QSSGRenderLayer::Background m_backgroundMode = QSSGRenderLayer::Background::Unspecified; |
114 | QColor m_userBackgroundColor = Qt::black; |
115 | QColor m_linearBackgroundColor = Qt::black; |
116 | QColor m_tonemappedBackgroundColor = Qt::black; |
117 | int m_samples = 1; |
118 | QSSGRhiEffectSystem *m_effectSystem = nullptr; |
119 | |
120 | QPointer<QQuick3DRenderStats> m_renderStats; |
121 | |
122 | QSSGRenderNode *m_sceneRootNode = nullptr; |
123 | QSSGRenderNode *m_importRootNode = nullptr; |
124 | |
125 | bool m_prepared = false; |
126 | |
127 | int m_requestedFramesCount = 0; |
128 | bool m_postProcessingStack = false; |
129 | bool m_useFBO = false; |
130 | Q_QUICK3D_PROFILE_ID |
131 | |
132 | friend class SGFramebufferObjectNode; |
133 | friend class QQuick3DSGRenderNode; |
134 | friend class QQuick3DSGDirectRenderer; |
135 | friend class QQuick3DViewport; |
136 | friend struct ViewportTransformHelper; |
137 | friend class QQuick3DRenderLayerHelpers; |
138 | }; |
139 | |
140 | class Q_QUICK3D_EXPORT QQuick3DRenderLayerHelpers |
141 | { |
142 | public: |
143 | static void updateLayerNodeHelper(const QQuick3DViewport &view3D, |
144 | const std::shared_ptr<QSSGRenderContextInterface> &rci, |
145 | QSSGRenderLayer &layerNode, |
146 | bool &aaIsDirty, |
147 | bool &temporalIsDirty); |
148 | }; |
149 | |
150 | class SGFramebufferObjectNode final : public QSGTextureProvider, public QSGSimpleTextureNode |
151 | { |
152 | Q_OBJECT |
153 | |
154 | public: |
155 | SGFramebufferObjectNode(); |
156 | ~SGFramebufferObjectNode() override; |
157 | |
158 | void scheduleRender(); |
159 | |
160 | QSGTexture *texture() const override; |
161 | |
162 | void preprocess() override; |
163 | |
164 | public Q_SLOTS: |
165 | void render(); |
166 | |
167 | void handleScreenChange(); |
168 | |
169 | public: |
170 | QQuickWindow *window; |
171 | QQuick3DSceneRenderer *renderer; |
172 | QQuick3DViewport *quickFbo; |
173 | |
174 | bool renderPending; |
175 | bool invalidatePending; |
176 | |
177 | qreal devicePixelRatio; |
178 | }; |
179 | |
180 | class QQuick3DSGRenderNode final : public QSGRenderNode |
181 | { |
182 | public: |
183 | ~QQuick3DSGRenderNode(); |
184 | void prepare() override; |
185 | StateFlags changedStates() const override; |
186 | void render(const RenderState *state) override; |
187 | void releaseResources() override; |
188 | RenderingFlags flags() const override; |
189 | public: |
190 | QQuickWindow *window = nullptr; |
191 | QQuick3DSceneRenderer *renderer = nullptr; |
192 | }; |
193 | |
194 | class QQuick3DSGDirectRenderer : public QObject |
195 | { |
196 | Q_OBJECT |
197 | public: |
198 | enum QQuick3DSGDirectRendererMode { |
199 | Underlay, |
200 | Overlay |
201 | }; |
202 | QQuick3DSGDirectRenderer(QQuick3DSceneRenderer *renderer, QQuickWindow *window, QQuick3DSGDirectRendererMode mode = Underlay); |
203 | ~QQuick3DSGDirectRenderer(); |
204 | |
205 | QQuick3DSceneRenderer *renderer() { return m_renderer; } |
206 | void setViewport(const QRectF &viewport); |
207 | |
208 | void requestRender(); |
209 | void setVisibility(bool visible); |
210 | |
211 | void preSynchronize(); |
212 | |
213 | private Q_SLOTS: |
214 | void prepare(); |
215 | void render(); |
216 | |
217 | private: |
218 | QQuick3DSceneRenderer *m_renderer = nullptr; |
219 | QQuickWindow *m_window = nullptr; |
220 | QRectF m_viewport; |
221 | bool m_isVisible = true; |
222 | QRhiTexture *m_rhiTexture = nullptr; |
223 | bool renderPending = false; |
224 | }; |
225 | |
226 | QT_END_NAMESPACE |
227 | |
228 | #endif // QSSGSCENERENDERER_H |
229 | |