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 <QtQuick3DRuntimeRender/private/qssgrendercontextcore_p.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 <optional> |
30 | |
31 | #include "qquick3dsceneenvironment_p.h" |
32 | |
33 | QT_BEGIN_NAMESPACE |
34 | |
35 | |
36 | class QQuick3DSceneManager; |
37 | class QQuick3DViewport; |
38 | struct QSSGRenderLayer; |
39 | |
40 | class QQuick3DSceneRenderer |
41 | { |
42 | using PickResultList = QVarLengthArray<QSSGRenderPickResult, 20>; |
43 | public: |
44 | explicit QQuick3DSceneRenderer(const std::shared_ptr<QSSGRenderContextInterface> &rci); |
45 | ~QQuick3DSceneRenderer(); |
46 | |
47 | static QSSGRenderLayer::TonemapMode getTonemapMode(const QQuick3DSceneEnvironment &environment) |
48 | { |
49 | return environment.useBuiltinTonemapper() ? QSSGRenderLayer::TonemapMode(environment.tonemapMode()) |
50 | : QSSGRenderLayer::TonemapMode::None; |
51 | } |
52 | |
53 | protected: |
54 | QRhiTexture *renderToRhiTexture(QQuickWindow *qw); |
55 | void beginFrame(); |
56 | void endFrame(); |
57 | void rhiPrepare(const QRect &viewport, qreal displayPixelRatio); |
58 | void rhiRender(); |
59 | void synchronize(QQuick3DViewport *view3D, const QSize &size, float dpr); |
60 | void invalidateFramebufferObject(); |
61 | QSize surfaceSize() const { return m_surfaceSize; } |
62 | void releaseCachedResources(); |
63 | |
64 | std::optional<QSSGRenderRay> getRayFromViewportPos(const QPointF &pos); |
65 | QSSGRenderPickResult syncPick(const QSSGRenderRay &ray); |
66 | QSSGRenderPickResult syncPickOne(const QSSGRenderRay &ray, QSSGRenderNode *node); |
67 | PickResultList syncPickAll(const QSSGRenderRay &ray); |
68 | |
69 | void setGlobalPickingEnabled(bool isEnabled); |
70 | |
71 | QQuick3DRenderStats *renderStats(); |
72 | |
73 | private: |
74 | void releaseAaDependentRhiResources(); |
75 | void updateLayerNode(QQuick3DViewport *view3D, const QList<QSSGRenderGraphObject *> &resourceLoaders); |
76 | void addNodeToLayer(QSSGRenderNode *node); |
77 | void removeNodeFromLayer(QSSGRenderNode *node); |
78 | std::shared_ptr<QSSGRenderContextInterface> m_sgContext; |
79 | QSSGRenderLayer *m_layer = nullptr; |
80 | QPointer<QQuick3DWindowAttachment> winAttacment; |
81 | QSize m_surfaceSize; |
82 | SGFramebufferObjectNode *fboNode = nullptr; |
83 | bool m_aaIsDirty = true; |
84 | |
85 | // RHI |
86 | QRhiTexture *m_texture = nullptr; |
87 | // the rt is set up to output into m_texture or m_ssaaTexture or m_msaaRenderBuffer(+resolve into m_texture) |
88 | QRhiTextureRenderTarget *m_textureRenderTarget = nullptr; |
89 | QRhiRenderPassDescriptor *m_textureRenderPassDescriptor = nullptr; |
90 | // used by the draw quad that does m_ssaaTexture -> m_texture |
91 | QRhiTextureRenderTarget *m_ssaaTextureToTextureRenderTarget = nullptr; |
92 | QRhiRenderPassDescriptor *m_ssaaTextureToTextureRenderPassDescriptor = nullptr; |
93 | QRhiRenderBuffer *m_msaaRenderBuffer = nullptr; |
94 | QRhiTexture *m_ssaaTexture = nullptr; |
95 | QRhiTexture *m_temporalAATexture = nullptr; |
96 | QRhiTexture *m_prevTempAATexture = nullptr; |
97 | QRhiTextureRenderTarget *m_temporalAARenderTarget = nullptr; |
98 | QRhiRenderPassDescriptor *m_temporalAARenderPassDescriptor = nullptr; |
99 | QRhiRenderBuffer *m_depthStencilBuffer = nullptr; |
100 | bool m_textureNeedsFlip = true; |
101 | QSSGRenderLayer::Background m_backgroundMode; |
102 | QColor m_userBackgroundColor = Qt::black; |
103 | QColor m_linearBackgroundColor = Qt::black; |
104 | QColor m_tonemappedBackgroundColor = Qt::black; |
105 | int m_samples = 1; |
106 | QSSGRhiEffectSystem *m_effectSystem = nullptr; |
107 | |
108 | QPointer<QQuick3DRenderStats> m_renderStats; |
109 | |
110 | QSSGRenderNode *m_sceneRootNode = nullptr; |
111 | QSSGRenderNode *m_importRootNode = nullptr; |
112 | |
113 | float m_ssaaMultiplier = 1.5f; |
114 | |
115 | bool m_prepared = false; |
116 | |
117 | int requestedFramesCount = 0; |
118 | bool m_postProcessingStack = false; |
119 | Q_QUICK3D_PROFILE_ID |
120 | |
121 | friend class SGFramebufferObjectNode; |
122 | friend class QQuick3DSGRenderNode; |
123 | friend class QQuick3DSGDirectRenderer; |
124 | friend class QQuick3DViewport; |
125 | friend struct ViewportTransformHelper; |
126 | }; |
127 | |
128 | namespace QQuick3DRenderLayerHelpers { |
129 | Q_QUICK3D_EXPORT void updateLayerNodeHelper(const QQuick3DViewport &view3D, QSSGRenderLayer &layerNode, bool &aaIsDirty, bool &temporalIsDirty, float &ssaaMultiplier); |
130 | } |
131 | |
132 | class SGFramebufferObjectNode final : public QSGTextureProvider, public QSGSimpleTextureNode |
133 | { |
134 | Q_OBJECT |
135 | |
136 | public: |
137 | SGFramebufferObjectNode(); |
138 | ~SGFramebufferObjectNode() override; |
139 | |
140 | void scheduleRender(); |
141 | |
142 | QSGTexture *texture() const override; |
143 | |
144 | void preprocess() override; |
145 | |
146 | public Q_SLOTS: |
147 | void render(); |
148 | |
149 | void handleScreenChange(); |
150 | |
151 | public: |
152 | QQuickWindow *window; |
153 | QQuick3DSceneRenderer *renderer; |
154 | QQuick3DViewport *quickFbo; |
155 | |
156 | bool renderPending; |
157 | bool invalidatePending; |
158 | |
159 | qreal devicePixelRatio; |
160 | }; |
161 | |
162 | class QQuick3DSGRenderNode final : public QSGRenderNode |
163 | { |
164 | public: |
165 | ~QQuick3DSGRenderNode(); |
166 | void prepare() override; |
167 | StateFlags changedStates() const override; |
168 | void render(const RenderState *state) override; |
169 | void releaseResources() override; |
170 | RenderingFlags flags() const override; |
171 | public: |
172 | QQuickWindow *window = nullptr; |
173 | QQuick3DSceneRenderer *renderer = nullptr; |
174 | }; |
175 | |
176 | class QQuick3DSGDirectRenderer : public QObject |
177 | { |
178 | Q_OBJECT |
179 | public: |
180 | enum QQuick3DSGDirectRendererMode { |
181 | Underlay, |
182 | Overlay |
183 | }; |
184 | QQuick3DSGDirectRenderer(QQuick3DSceneRenderer *renderer, QQuickWindow *window, QQuick3DSGDirectRendererMode mode = Underlay); |
185 | ~QQuick3DSGDirectRenderer(); |
186 | |
187 | QQuick3DSceneRenderer *renderer() { return m_renderer; } |
188 | void setViewport(const QRectF &viewport); |
189 | |
190 | void requestRender(); |
191 | void setVisibility(bool visible); |
192 | |
193 | private Q_SLOTS: |
194 | void prepare(); |
195 | void render(); |
196 | |
197 | private: |
198 | QQuick3DSceneRenderer *m_renderer = nullptr; |
199 | QQuickWindow *m_window = nullptr; |
200 | QQuick3DSGDirectRendererMode m_mode; |
201 | QRectF m_viewport; |
202 | bool m_isVisible = true; |
203 | QRhiTexture *m_rhiTexture = nullptr; |
204 | bool renderPending = false; |
205 | }; |
206 | |
207 | QT_END_NAMESPACE |
208 | |
209 | #endif // QSSGSCENERENDERER_H |
210 | |